设为首页 收藏本站
查看: 755|回复: 0

[经验分享] spring+mybatis 多数据源整合(转)

[复制链接]

尚未签到

发表于 2016-11-26 08:29:43 | 显示全部楼层 |阅读模式
spring+mybatis 多数据源整合
  原文地址:http://yunjkj.com/javajc/2596.html
  一、配置文件


<!-- 数据源配置 -->
<bean id="ds1" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">  
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />  
<property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl" />  
<property name="username" value="test" />  
<property name="password" value="test" />  
<property name="defaultAutoCommit" value="false"></property>  
</bean>  
<bean id="ds2" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">  
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />  
<property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl" />  
<property name="username" value="test" />  
<property name="password" value="test" />  
<property name="defaultAutoCommit" value="false"></property>  
</bean>  
<bean id="dataSource" class="app.platform.mybatis.DynamicDataSource">  
<property name="targetDataSources">  
<map key-type="java.lang.String">  
<entry value-ref="ds1" key="ds1"></entry>  
<entry value-ref="ds2" key="ds2"></entry>  
</map>  
</property>
<!-- 默认使用ds1的数据源 -->
<property name="defaultTargetDataSource" ref="ds1"></property>     
</bean>  
<!-- mybatis配置 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:/mybatis/mybatis-config.xml" />
<property name="mapperLocations" value="classpath*:app/mapper/**/*.xml"/>
</bean>
<!-- 事务管理器配置,单数据源事务 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 事务拦截的类及方法 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true" />
<tx:method name="find*" read-only="true" />
<tx:method name="query*" read-only="true" />
<tx:method name="is*" read-only="true" />
<tx:method name="do*" propagation="REQUIRES_NEW" rollback-for="java.lang.Exception"/>
<tx:method name="save*" propagation="REQUIRED" rollback-for="java.lang.Exception" />
<tx:method name="update*" propagation="REQUIRED" rollback-for="java.lang.Exception" />
<tx:method name="delete*" propagation="REQUIRED" rollback-for="java.lang.Exception" />
</tx:attributes>
</tx:advice>
<aop:config proxy-target-class="true">
<aop:advisor pointcut="execution(* app..service..*.*(..))" advice-ref="txAdvice" />
</aop:config>
  重点是上面的数据源配置。
  二、下面的类是在数据源中用到的
  注:将下面类让照路径加入到项目中

package app.platform.mybatis;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource {  
@Override  
protected Object determineCurrentLookupKey() {  
return DataSourceContextHolder.getDbType();  
}  
}

package app.platform.mybatis;
public class DataSourceContextHolder {  
private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();  
public static void setDbType(String dbType) {  
contextHolder.set(dbType);  
}  
public static String getDbType() {  
return ((String) contextHolder.get());  
}  
public static void clearDbType() {  
contextHolder.remove();  
}  
}  

  这样准备工作就做好了,下面是一个单元测试的例子。
  三、测试

public class Test{
@Autowired
private TestService testService;
@Test  
public void addTest() throws Exception {  
User user = new User();  
user.setUsername("admin");  
user.setPassword("123456");  
//注意这里在调用service前切换到ds2的数据源
DataSourceContextHolder.setDbType("ds2");
testService.add(user);  
}  
}
  
  四、总结
  最主要的变化是DynamicDataSource 类,这个类继承了AbstractRoutingDataSource,我们再继续考察,发现这个类实现了datasource这个接口。
    再仔细研究,发现我配置了多个数据源给DynamicDataSource,默认的数据源是ds1。
我们研究下AbstractRoutingDataSource类的代码,主要是两个实现datasource的方法

public Connection getConnection() throws SQLException {  
return determineTargetDataSource().getConnection();  
}  
public Connection getConnection(String username, String password) throws SQLException {  
return determineTargetDataSource().getConnection(username, password);  
}  
  根据这段代码发现主要玄机都在determineTargetDataSource()方法上。

protected DataSource determineTargetDataSource() {  
Assert.notNull(this.resolvedDataSources, "DataSource router not initialized");  
Object lookupKey = determineCurrentLookupKey();  
DataSource dataSource = this.resolvedDataSources.get(lookupKey);  
if (dataSource == null && (this.lenientFallback || lookupKey == null)) {  
dataSource = this.resolvedDefaultDataSource;  
}  
if (dataSource == null) {  
throw new IllegalStateException("Cannot determine target DataSource for lookup key [" + lookupKey + "]");  
}  
return dataSource;  
}  
  根据这段代码发现,首先在使用数据源之前,首先判断使用数据源的key,也就是我们配置给

private Map<Object, Object> targetDataSources;  
       这个map中的key值,找到key值之后再找到对应的datasource然后并使用这个数据源。
    从上面我们发现,实际上DynamicDataSource只是在内部封装了数据源,然后调用它,只不过在内部他加了一些控制而已。(此处不知道是否可以理解为代理模式)
    再深一步想想,此处使用的orm层是mybatis,如果换成hibernate呢,或者jdbctemplate呢。 
实际上这个方法都适用。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-305663-1-1.html 上篇帖子: spring和mybatis整合,简单配置文件 下篇帖子: springmvc,mybatis,shiro综合配置示例
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表