mybatis 学习之多数据源整合

继续上篇文章如何使用mybatis3+spring3并且配置多数据源呢

先上代码在讲解吧
替换上一篇中spring中datasource的配置
Java代码 收藏代码
  1. <!--数据源配置-->
  2. <beanid="ds1"class="org.apache.commons.dbcp.BasicDataSource"
  3. destroy-method="close">
  4. <propertyname="driverClassName"value="com.mysql.jdbc.Driver"/>
  5. <propertyname="url"
  6. value="jdbc:mysql://localhost:3306/payoffdatabase?useUnicode=true&amp;characterEncoding=UTF-8"/>
  7. <propertyname="username"value="root"/>
  8. <propertyname="password"value="root"/>
  9. <propertyname="defaultAutoCommit"value="true"></property>
  10. </bean>
  11. <beanid="ds2"class="org.apache.commons.dbcp.BasicDataSource"
  12. destroy-method="close">
  13. <propertyname="driverClassName"value="com.mysql.jdbc.Driver"/>
  14. <propertyname="url"
  15. value="jdbc:mysql://localhost:3306/test?useUnicode=true&amp;characterEncoding=UTF-8"/>
  16. <propertyname="username"value="root"/>
  17. <propertyname="password"value="root"/>
  18. <propertyname="defaultAutoCommit"value="true"></property>
  19. </bean>
  20. <beanid="dataSource"class="a.b.router.DynamicDataSource">
  21. <propertyname="targetDataSources">
  22. <mapkey-type="java.lang.String">
  23. <entryvalue-ref="ds1"key="ds1"></entry>
  24. <entryvalue-ref="ds2"key="ds2"></entry>
  25. </map>
  26. </property>
  27. <propertyname="defaultTargetDataSource"ref="ds1"></property>
  28. </bean>


新的类DynamicDataSource
Java代码 收藏代码
  1. packagea.b.router;
  2. importorg.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
  3. publicclassDynamicDataSourceextendsAbstractRoutingDataSource{
  4. @Override
  5. protectedObjectdetermineCurrentLookupKey(){
  6. returnDataSourceContextHolder.getDbType();
  7. }
  8. }

新的类DataSourceContextHolder
Java代码 收藏代码
  1. packagea.b.router;
  2. publicclassDataSourceContextHolder{
  3. privatestaticfinalThreadLocal<String>contextHolder=newThreadLocal<String>();
  4. publicstaticvoidsetDbType(StringdbType){
  5. contextHolder.set(dbType);
  6. }
  7. publicstaticStringgetDbType(){
  8. return((String)contextHolder.get());
  9. }
  10. publicstaticvoidclearDbType(){
  11. contextHolder.remove();
  12. }
  13. }


原来的单元测试新添加一行信息,修改为
Java代码 收藏代码
  1. @Test
  2. publicvoidaddTest()throwsException{
  3. UserLoginuserLogin=newUserLogin();
  4. userLogin.setPassword("102");
  5. userLogin.setUsername("102");
  6. DataSourceContextHolder.setDbType("ds2");
  7. service.add(userLogin);
  8. }


最主要的变化是DynamicDataSource 类,这个类继承了AbstractRoutingDataSource,我们再继续考察,发现这个类实现了datasource这个接口。

再仔细研究,发现我配置了多个数据源给DynamicDataSource,默认的数据源是ds1。
我们研究下AbstractRoutingDataSource类的代码,主要是两个实现datasource的方法
Java代码 收藏代码
  1. publicConnectiongetConnection()throwsSQLException{
  2. returndetermineTargetDataSource().getConnection();
  3. }
  4. publicConnectiongetConnection(Stringusername,Stringpassword)throwsSQLException{
  5. returndetermineTargetDataSource().getConnection(username,password);
  6. }

根据这段代码发现主要玄机都在determineTargetDataSource()方法上。

Java代码 收藏代码
  1. protectedDataSourcedetermineTargetDataSource(){
  2. Assert.notNull(this.resolvedDataSources,"DataSourcerouternotinitialized");
  3. ObjectlookupKey=determineCurrentLookupKey();
  4. DataSourcedataSource=this.resolvedDataSources.get(lookupKey);
  5. if(dataSource==null&&(this.lenientFallback||lookupKey==null)){
  6. dataSource=this.resolvedDefaultDataSource;
  7. }
  8. if(dataSource==null){
  9. thrownewIllegalStateException("CannotdeterminetargetDataSourceforlookupkey["+lookupKey+"]");
  10. }
  11. returndataSource;
  12. }

根据这段代码发现,首先在使用数据源之前,首先判断使用数据源的key,也就是我们配置给
Java代码 收藏代码
  1. privateMap<Object,Object>targetDataSources;

这个map中的key值,找到key值之后再找到对应的datasource然后并使用这个数据源。


从上面我们发现,实际上DynamicDataSource只是在内部封装了数据源,然后调用它,只不过在内部他加了一些控制而已。(此处不知道是否可以理解为代理模式)

再深一步想想,此处使用的orm层是mybatis,如果换成hibernate呢,或者jdbctemplate呢。
实际上这个方法都适用。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值