Mybatis Spring multiple databases Java configuration
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">As mentioned above, we need to give corresponding sessionFactory in your DaoImpl. You can not autowire SqlSessionTemplate
<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>
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的更多相关文章
- Mybatis异常:java.lang.ClassNotFoundException: org.mybatis.spring.SqlSessionFactoryBean
问题描述: 一月 15, 2014 3:43:13 下午 org.springframework.context.support.AbstractApplicationContext prepareR ...
- spring mvc + mybatis + spring aop声明式事务管理没有作用
在最近的一个项目中,采用springMVC.mybatis,发现一个很恼人的问题:事务管理不起作用!!网上查阅了大量的资料,尝试了各种解决办法,亦未能解决问题! spring版本:3.0.5 myba ...
- 使用Spring MVC,Mybatis框架等创建Java Web项目时各种前期准备的配置文件内容
1.pom.xml 首先,pom.xml文件,里面包含各种maven的依赖,代码如下: <project xmlns="http://maven.apache.org/POM/4.0. ...
- 集成框架 javaweb开发平台ssmy_m(生成代码) java struts2 mybatis spring maven jquery
网页地址 http://blog.csdn.net/lpy3654321/article/details/31841573 项目设想,在项目开发中,我们的开发者大多数时间都在反复开发 相同的keywo ...
- Java知识总结---整合SpringMVC+Mybatis+Spring(二)
在如今的Java Web开发过程中,各种各样框架层出不穷.在工作中,框架的使用也越来越频繁. 今天介绍一下如今比較流行的SpringMVC.Mybatis和Spring框架.学习一下怎样在项目中使用它 ...
- 疑惑的 java.lang.AbstractMethodError: org.mybatis.spring.transaction.SpringManagedTransaction.getTimeout()L
在MAVEN项目里面,在整合spring和mybatis在执行数据库操作的时候报出了: java.lang.AbstractMethodError: org.mybatis.spring.transa ...
- Spring Security(十二):5. Java Configuration
General support for Java Configuration was added to Spring Framework in Spring 3.1. Since Spring Sec ...
- 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 ...
- java.lang.AbstractMethodError: org.mybatis.spring.transaction.SpringManagedTransaction.getTimeout()L
mybatis与springboot集成的时候,报错:java.lang.AbstractMethodError: org.mybatis.spring.transaction.SpringManag ...
随机推荐
- Deep compression code
https://github.com/songhan/SqueezeNet-Deep-Compression import sys import os import numpy as np impor ...
- openerp 中文乱码及界面翻译不全
openerp中文报表乱码问题,即是字体问题,环境是ubuntu 12.04 openerp 6.1, deb all in one安装方式 一.cd usr/share/fonts/truetype ...
- Ubuntu12.04+OpenERP7.0安装笔记
不经意的一次看到OpenERP这个开源ERP,就被其丰富的功能,简洁的画面,熟悉的语言所吸引.迫不及待的多方查询资料,自己架设一个测试环境来进行了解.以下为测试安装时候的步骤说明,以备查询,并供有需要 ...
- eclipse c++ 经常使用快捷键
atl+/ //自己主动补全 ctrl+/ //凝视,或者去凝视 ctrl+shift+F //代码整理 ctrl+shift+G //跳转到调用的地方,或者,右键+Reference+Project ...
- 函数式编程工具:filter和reduce
# -*- coding: utf-8 -*- #python 27 #xiaodeng #函数式编程工具:filter和reduce #python内置函数中,map函数是用来进行函数式编程这类工具 ...
- CentOS 6.8 ftp服务安装配置 基于本地用户和虚拟用户
CentOS 6.8 ftp服务安装配置 基于本地用户和虚拟用户 一.安装ftp服务 1.检查是否已经安装 # rpm -qa | grep ftp ftp-0.17-54.el6.x86_64 vs ...
- 【微信小程序】实现类似WEB端【返回顶部】功能
1.原理:利用小程序自带的<scroll-view>组件,该组件的bindScroll和scroll-top方法.属性进行联合操作 2.效果图: 3.wxml: <scroll-vi ...
- ScriptManager.RegisterAsyncPostBackControl 方法
来源:VS2012帮助文档 用途: 将控件注册为异步回发的触发器 语法: public void RegisterAsyncPostBackControl( Control control ) 参数 ...
- 什么是RESTfull?理解RESTfull架构【转】
越来越多的人开始意识到,网站即软件,而且是一种新型的软件. 这种"互联网软件"采用客户端/服务器模式,建立在分布式体系上,通过互联网通信,具有高延时(high latency).高 ...
- 转 如何使用Windows Media Load Simulator进行Windows Media服务器性能测试和监控
Windows Media Load Simulator(WMLS)有两个主要的用途:作为极值或者压力测试工具和在线监视器. 1 极值和压力压力测试:你能够在达到期望的极值压力条件下测试离线的 ...