Reputation: 599
My applications uses Spring3+MyBatis3. I'm trying to setup multiple data source for it. Setup looks like:
<!-- db1 setup-->
<bean id="db1SqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"
p:configLocation="WEB-INF/mybatis/sqlMapConfig.xml"
p:dataSource-ref="db1DataSource" />
<bean id="db1SqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg ref="db1SqlSessionFactory"/>
</bean>
<!-- db2 setup -->
<bean id="db2SqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"
p:configLocation="WEB-INF/mybatis/sqlMapConfig.xml"
p:dataSource-ref="db2DataSource" />
<bean id="db2SqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg ref="db2SqlSessionFactory"/>
</bean>
In the logs, I've found this message:
No unique bean of type [org.apache.ibatis.session.SqlSessionFactory] is defined: expected single matching bean but found 2: [db1SqlSessionFactory, db2SqlSessionFactory]
I googled and looked into mybatis manuals but couldn't find way how to setup multiple data sources with mybatis. Any ideas?
Upvotes: 4
Views: 23219
Reputation: 207
Make Following Changes In applicationContext.xml
Step 1: Configure the data source beans
<!-- DataSource 1 -->
<bean id="dataSource1" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/db1" />
<property name="username" value="username1" />
<property name="password" value="password1" />
</bean>
<!-- DataSource 2 -->
<bean id="dataSource2" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/db2" />
<property name="username" value="username2" />
<property name="password" value="password2" />
</bean>
Step 2: Configure the SqlSessionFactory beans
<!-- SqlSessionFactory for DataSource 1 -->
<bean id="sqlSessionFactory1" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource1" />
<property name="mapperLocations" value="classpath:mappers1/*.xml" />
</bean>
<!-- SqlSessionFactory for DataSource 2 -->
<bean id="sqlSessionFactory2" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource2" />
<property name="mapperLocations" value="classpath:mappers2/*.xml" />
</bean>
Step 3: Configure the MapperScannerConfigurer beans
<!-- MapperScannerConfigurer for DataSource 1 -->
<bean id="mapperScannerConfigurer1" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.example.mapper1" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory1" />
</bean>
<!-- MapperScannerConfigurer for DataSource 2 -->
<bean id="mapperScannerConfigurer2" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.example.mapper2" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory2" />
</bean>
Step 4: Now You can configured above things in your code as per requirements
@Component
public class MyComponent {
private SqlSessionFactory sqlSessionFactory;
private MyMapper myMapper;
@Autowired
public MyComponent(@Qualifier("sqlSessionFactory1") SqlSessionFactory sqlSessionFactory,
@Qualifier("myMapper1") MyMapper myMapper) {
this.sqlSessionFactory = sqlSessionFactory;
this.myMapper = myMapper;
}
// Use the sqlSessionFactory and myMapper in your component's methods
// ...
}
Note:
Create separate mapper interfaces and XML files for each data source, corresponding to the basePackage values used in step 3
Upvotes: 0
Reputation: 1
In a DAO implementation use SqlSessionTemplate
instead of SqlSessionDaoSupport
. Inject bean db1SqlSessionTemplate
or db2SqlSessionTemplate
.
@Repository
public class TestDaoImpl implements TestDao{
@Autowired
private SqlSession db1SqlSessionTemplate;
...
db1SqlSessionTemplate.selectList("testSelect");
...
}
When extending SqlSessionDaoSupport
the context Spring does not know that you use SqlSession
.
Upvotes: 0
Reputation: 41
also solved ! just reference your factory bean in MapperScannerConfigurer : sqlSessionFactoryBeanName
First data source >>>>>>>
<bean id="dataSource1" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<bean id="sqlSessionFactory1" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource1"/>
</bean>
<bean id="MapperScannerConfigurer1" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.package.p1"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory1"/>
</bean>
Second data source >>>>>>
<bean id="dataSource2" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<bean id="sqlSessionFactory2" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource2"/>
</bean>
<bean id="MapperScannerConfigurer1" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.package.p2"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory2"/>
</bean>
Upvotes: 4
Reputation: 599
solved, the problem was that I must specify directly reference to sqlSessionFactory
<bean id="myDao" class="org.mybatis.spring.mapper.MapperFactoryBean"
p:sqlSessionTemplate-ref="db1SqlSessionTemplate"
p:mapperInterface="my.project.domain.dao.MyDao"
p:sqlSessionFactory-ref="db1SqlSessionFactory"/>
Upvotes: 2