https://stackoverflow.com/questions/18201075/mybatis-spring-multiple-databases-java-configuration

********************************************************************

I'm working with Spring and Mybatis and I have two databases, the configuration for the first database was relative easy, but I can't get to work the second database with Spring and transactions, here is my code

@Configuration
@ComponentScan(basePackages = {"hernandez.service", "hernandez.dao"})
@EnableTransactionManagement
@MapperScan(basePackages="hernandez.mapper" )
@Import(DbConfig2.class)
public class AppConfig { @Bean(name = "dataSource")
public DataSource dataSource() {
DriverManagerDataSource ds = new DriverManagerDataSource("com.mysql.jdbc.Driver",
"jdbc:mysql://localhost:3306/northwind", "root", "");
return ds;
} @Bean
public SqlSessionFactoryBean sqlSessionFactory() {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource());
return factoryBean;
} @Bean(name = "transactionManager")
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource());
}
} @Configuration
@MapperScan("loli.mapper" )
public class DbConfig2 {
@Bean(name = "dataSource_2")
public DataSource dataSource2() {
DriverManagerDataSource ds = new DriverManagerDataSource("com.mysql.jdbc.Driver",
"jdbc:mysql://localhost:3306/dmsolut_dmsms", "root", "");
return ds;
} @Bean
public SqlSessionFactory sqlSessionFactory2() throws Exception{
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource2());
return factoryBean.getObject();
} @Bean(name = "transactionManager_2")
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource2());
}
}

Is there a way to get this working with pure Spring Java configuration or at least with some XML? There's no official documentation to get two databases working in the Mybatis-Spring project

Multi datasources with mybatis are used in my project right now. This is an Example, add to your application.xml

  <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
<property name="url" value="${center.connectionURL}"/>
<property name="username" value="${userName}"/>
<property name="password" value="${password}"/>
</bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.xxx.dao.center"/>
<property name="sqlSessionFactoryBeanName" value="cneterSqlSessionFactory"/>
</bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" name="cneterSqlSessionFactory">
<property name="dataSource" ref="dataSource"></property>
<property name="mapperLocations" value="classpath*:mapperConfig/center/*.xml"/>
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<!--center db end-->
<!--exdb-->
<bean id="dataSourceEx" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
<property name="url" value="${ex.connectionURL}"/>
<property name="username" value="${userName}"/>
<property name="password" value="${password}"/>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.xxx.dao.ex"/>
<property name="sqlSessionFactoryBeanName" value="exSqlSessionFactory"/>
</bean>
<bean id="sqlSessionFactoryEx" class="org.mybatis.spring.SqlSessionFactoryBean" name="exSqlSessionFactory">
<property name="dataSource" ref="dataSourceEx"></property>
<property name="mapperLocations" value="classpath*:mapperConfig/ex/*.xml"/>
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
<bean id="transactionManagerEx" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSourceEx"/>

Add answer with java config example we use in our project:

import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.JdbcType;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.sql.DataSource; @Configuration
@ComponentScan(basePackages = "com.mycompany")
@EnableTransactionManagement(proxyTargetClass = true)
public class ApplicationConfig2 {
public static final String DATA_SOURCE_NAME_1 = "jdbc/dataSource1";
public static final String DATA_SOURCE_NAME_2 = "jdbc/dataSource2"; public static final String SQL_SESSION_FACTORY_NAME_1 = "sqlSessionFactory1";
public static final String SQL_SESSION_FACTORY_NAME_2 = "sqlSessionFactory2"; public static final String MAPPERS_PACKAGE_NAME_1 = "com.mycompany.mappers.dao1";
public static final String MAPPERS_PACKAGE_NAME_2 = "com.mycompany.mappers.dao2"; @Bean
public DataSource dataSource1() {
JndiDataSourceLookup dsLookup = new JndiDataSourceLookup();
return dsLookup.getDataSource(DATA_SOURCE_NAME_1);
} @Bean
public DataSource dataSource2() {
JndiDataSourceLookup dsLookup = new JndiDataSourceLookup();
return dsLookup.getDataSource(DATA_SOURCE_NAME_2);
} @Bean
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource());
} @Bean(name = SQL_SESSION_FACTORY_NAME_1)
public SqlSessionFactory sqlSessionFactory1(DataSource dataSource1) throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setTypeHandlersPackage(DateTimeTypeHandler.class.getPackage().getName());
sqlSessionFactoryBean.setDataSource(dataSource1);
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBean.getObject();
sqlSessionFactory.getConfiguration().setMapUnderscoreToCamelCase(true);
sqlSessionFactory.getConfiguration().setJdbcTypeForNull(JdbcType.NULL);
return sqlSessionFactory;
} @Bean(name = SQL_SESSION_FACTORY_NAME_2)
public SqlSessionFactory sqlSessionFactory2(DataSource dataSource2) throws Exception {
SqlSessionFactoryBean diSqlSessionFactoryBean = new SqlSessionFactoryBean();
diSqlSessionFactoryBean.setTypeHandlersPackage(DateTimeTypeHandler.class.getPackage().getName());
diSqlSessionFactoryBean.setDataSource(dataSource2);
SqlSessionFactory sqlSessionFactory = diSqlSessionFactoryBean.getObject();
sqlSessionFactory.getConfiguration().setMapUnderscoreToCamelCase(true);
sqlSessionFactory.getConfiguration().setJdbcTypeForNull(JdbcType.NULL);
return sqlSessionFactory;
} @Bean
public MapperScannerConfigurer mapperScannerConfigurer1() {
MapperScannerConfigurer configurer = new MapperScannerConfigurer();
configurer.setBasePackage(MAPPERS_PACKAGE_NAME_1);
configurer.setSqlSessionFactoryBeanName(SQL_SESSION_FACTORY_NAME_1);
return configurer;
} @Bean
public MapperScannerConfigurer mapperScannerConfigurer2() {
MapperScannerConfigurer configurer = new MapperScannerConfigurer();
configurer.setBasePackage(MAPPERS_PACKAGE_NAME_2);
configurer.setSqlSessionFactoryBeanName(SQL_SESSION_FACTORY_NAME_2);
return configurer;
}
}

In my experience, you should also add @Primary to one of the DataSource beans. Otherwise it will throw NoUniqueBeanDefinitionException.

@Bean
@Primary
public DataSource dataSource1() {
JndiDataSourceLookup dsLookup = new JndiDataSourceLookup();
return dsLookup.getDataSource(DATA_SOURCE_NAME_1);
} @Bean
public DataSource dataSource2() {
JndiDataSourceLookup dsLookup = new JndiDataSourceLookup();
return dsLookup.getDataSource(DATA_SOURCE_NAME_2);
}

You can use spring's AbstractRoutingDataSource by extending it and overriding the method determineCurrentLookupKey().

Spring Configuration

You can define separate datasource in spring configuration.

<!-- db2 data source -->
<bean id="db2DataSource" class="com.ibm.db2.jdbc.app.DB2Driver">
<property name="serverName" value="${db2.jdbc.serverName}" />
<property name="portNumber" value="${db2.jdbc.portNumber}" />
<property name="user" value="${db2.jdbc.username}" />
<property name="password" value="${db2.jdbc.password}" />
<property name="databaseName" value="${db2.jdbc.databaseName}" />
</bean> <!-- mysql data source -->
<bean id="mysqlDataSource" class="com.mysql.jdbc.Driver">
<property name="serverName" value="${mysql.jdbc.serverName}" />
<property name="portNumber" value="${mysql.jdbc.portNumber}" />
<property name="user" value="${mysql.jdbc.username}" />
<property name="password" value="${mysql.jdbc.password}" />
<property name="databaseName" value="${mysql.jdbc.databaseName}" />
</bean>

Associate the datasource with customer:

<bean id="customer" class="com.example.Customer">
<property name="dataSource" ref="dataSource"/>
</bean> <bean id="dataSource" class="com.example.datasource.CustomerRoutingDataSource">
<property name="targetDataSources">
<map key-type="com.example.Customer">
<entry key="db2" value-ref="mysqlDataSource"/>
<entry key="mysql" value-ref="db2DataSource"/>
</map>
</property>
<property name="defaultTargetDataSource" ref="mysql"/>
</bean>

Java

package com.example;

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

public class CustomerRoutingDataSource extends AbstractRoutingDataSource {

 @Bean
CustomerContextHolder context; @Override
protected Object determineCurrentLookupKey() {
return context.getCustomerType();
}
}

Basically, each request will have its context. You can associate datasource with request using mapped key. You can find more details here dynamic-datasource-routing

**************

<bean id="sqlSessionFactory1" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource1" />
<property name="configLocation">
<value>classpath:com/dtcc/dao/impl/DaoSqlMapConfig_MyBatis1.xml</value>
</property>
<property name="transactionFactory">
<bean class="org.apache.ibatis.transaction.managed.ManagedTransactionFactory" />
</property>
<property name="mapperLocations" value="classpath*:com/dtcc/dao/impl/DaoEmfMyBatis.sp.xml"/>
</bean>
<bean id="sqlSession1" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory1" />
</bean>
<!-- MyBatis Changes Ends --> <bean id="daoEmf" class="com.dtcc.dao.DaoEmfImpl">
<property name="connectionType"><ref local="com.dtcc.sharedservices.utils.resources.ConnTypes.IBM_DB2_CONNECTION" /></property>
<property name="jndiNameForLogging"><ref local="dataSourceName1" /></property>
<property name="sqlSessionTemplate"> <ref local="sqlSession1" /></property>
<property name="applicationLog"><ref local="appLog" /></property>
</bean>
As mentioned above, we need to give corresponding sessionFactory in your DaoImpl. You can not autowire SqlSessionTemplate
in your DaoImpl class if you have more than one sessionFactory. Give unique name for each session factory and map it to your respective DaoImpl class.
All you have to do is just to create object for SqlSessionTemplate with Setter method in DaoImpl class and you can make your db call using sqlSessionTemplate object as below,
this.sqlSessionTemplate.selectList("ProcedureID", parameter);

Mybatis Spring multiple databases Java configuration的更多相关文章

  1. Mybatis异常:java.lang.ClassNotFoundException: org.mybatis.spring.SqlSessionFactoryBean

    问题描述: 一月 15, 2014 3:43:13 下午 org.springframework.context.support.AbstractApplicationContext prepareR ...

  2. spring mvc + mybatis + spring aop声明式事务管理没有作用

    在最近的一个项目中,采用springMVC.mybatis,发现一个很恼人的问题:事务管理不起作用!!网上查阅了大量的资料,尝试了各种解决办法,亦未能解决问题! spring版本:3.0.5 myba ...

  3. 使用Spring MVC,Mybatis框架等创建Java Web项目时各种前期准备的配置文件内容

    1.pom.xml 首先,pom.xml文件,里面包含各种maven的依赖,代码如下: <project xmlns="http://maven.apache.org/POM/4.0. ...

  4. 集成框架 javaweb开发平台ssmy_m(生成代码) java struts2 mybatis spring maven jquery

    网页地址 http://blog.csdn.net/lpy3654321/article/details/31841573 项目设想,在项目开发中,我们的开发者大多数时间都在反复开发 相同的keywo ...

  5. Java知识总结---整合SpringMVC+Mybatis+Spring(二)

    在如今的Java Web开发过程中,各种各样框架层出不穷.在工作中,框架的使用也越来越频繁. 今天介绍一下如今比較流行的SpringMVC.Mybatis和Spring框架.学习一下怎样在项目中使用它 ...

  6. 疑惑的 java.lang.AbstractMethodError: org.mybatis.spring.transaction.SpringManagedTransaction.getTimeout()L

    在MAVEN项目里面,在整合spring和mybatis在执行数据库操作的时候报出了: java.lang.AbstractMethodError: org.mybatis.spring.transa ...

  7. Spring Security(十二):5. Java Configuration

    General support for Java Configuration was added to Spring Framework in Spring 3.1. Since Spring Sec ...

  8. java.lang.AbstractMethodError: org.mybatis.spring.transaction.SpringManagedTransaction.getTimeout()Ljava/lang/Integer; at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.jav

    在整合spring和mybatis在执行数据库操作的时候报出了: java.lang.AbstractMethodError: org.mybatis.spring.transaction.Sprin ...

  9. java.lang.AbstractMethodError: org.mybatis.spring.transaction.SpringManagedTransaction.getTimeout()L

    mybatis与springboot集成的时候,报错:java.lang.AbstractMethodError: org.mybatis.spring.transaction.SpringManag ...

随机推荐

  1. 23、List集合

    1.List List接口是Collection的子接口,用于定义线性表数据结构.List是可重复集 2.List自身定义的方法 List处理继承Collection方法外,自己还定义了其它方法,例如 ...

  2. Windows下如何配置tomcat环境变量

    Apache Tomcat 是一款 Java Servlet 和 JavaServer Pages 技术的开源软件实现,可以作为测试 Servlet 的独立服务器,而且可以集成到 Apache Web ...

  3. 【zend studio】如何添加已存在的git项目

    1.在zend里面新增项目crm2 2.win下进入crm2目录,右键选择 Git Bash Here,进项git clone操作 3.进入下载下来的GIT项目目录,选择复制,然后返回上一目录crm2 ...

  4. 照片管家iOS-实现本地相册、视频、安全保护、社交分享源码下载Demo

    <照片管家> APP功能: 1.本地照片批量导入与编辑 2.本地视频存储与播放 3.手势密码.数字密码.TouchID安全保护 4.QQ.微信.微博.空间社交分享 5.其他细节功能. 运用 ...

  5. java测试Unicode编码以及数组的运用(初学篇)

    /*第二章第四小题*/ /* * (1)编写一个应用程序,给出汉字“你” ,“我”,“他”在Unicode 表中的位置 * (2)编写一个java应用程序,输出全部的希腊字母 */ public cl ...

  6. HDUOJ----More is better(并查集)

    More is better Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 327680/102400 K (Java/Others) ...

  7. 使用免费ip代理进行投票

    只要是投票系统,必然要限制一个用户投多张票. 如何限制呢?限制ip是最直观最简单的思路,可是代理池可以解决限制ip的情况. 如果投票页面前面加上一个验证码,那程序就会有点困难了. 有些投票使用微信号, ...

  8. html5中的FileReader对象

    表单中有图片选项,选中图片文件之后要求可以预览.这个功能很多控件都封装好了,但是它们的底层都是FileReader对象. FileReader对象提供了丰富的功能,包括以二进制.以文本方式读取文件内容 ...

  9. 深入理解SpringBoot配置

    一.application.properties的位置 1.当前目录的 "/config"的子目录下 2.当前目录下 3.classpath根目录的"/config&qu ...

  10. 【LeetCode】39. Combination Sum (2 solutions)

    Combination Sum Given a set of candidate numbers (C) and a target number (T), find all unique combin ...