zoukankan      html  css  js  c++  java
  • springboot + mybatis + 多数据源

    在实际开发中,我们一个项目可能会用到多个数据库,通常一个数据库对应一个数据源。

    代码结构:

    简要原理:

    1)DatabaseType列出所有的数据源的key---key

    2)DatabaseContextHolder是一个线程安全的DatabaseType容器,并提供了向其中设置和获取DatabaseType的方法

    3)DynamicDataSource继承AbstractRoutingDataSource并重写其中的方法determineCurrentLookupKey(),在该方法中使用DatabaseContextHolder获取当前线程的DatabaseType

    4)MyBatisConfig中生成2个数据源DataSource的bean---value

    5)MyBatisConfig中将1)和4)组成的key-value对写入到DynamicDataSource动态数据源的targetDataSources属性(当然,同时也会设置2个数据源其中的一个为DynamicDataSource的defaultTargetDataSource属性中)

    6)将DynamicDataSource作为primary数据源注入到SqlSessionFactory的dataSource属性中去,并且该dataSource作为transactionManager的入参来构造DataSourceTransactionManager

    7)使用的时候,在dao层或service层先使用DatabaseContextHolder设置将要使用的数据源key,然后再调用mapper层进行相应的操作,建议放在dao层去做(当然也可以使用spring aop+自定注解去做)

    注意:在mapper层进行操作的时候,会先调用determineCurrentLookupKey()方法获取一个数据源(获取数据源:先根据设置去targetDataSources中去找,若没有,则选择defaultTargetDataSource),之后在进行数据库操作。

    1、假设有两个数据库,配置如下

    application.properties

    复制代码
     1 #the first datasource
     2 jdbc.driverClassName = com.mysql.jdbc.Driver
     3 jdbc.url = jdbc:mysql://xxx:3306/mytestdb?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8
     4 jdbc.username = root
     5 jdbc.password = 123
     6 
     7 #the second datasource
     8 jdbc2.driverClassName = com.mysql.jdbc.Driver
     9 jdbc2.url = jdbc:mysql://xxx:3306/mytestdb2?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8
    10 jdbc2.username = root
    11 jdbc2.password = 123
    复制代码

    说明:在之前的配置的基础上,只增加了上述的第二个数据源。

    2、DatabaseType

     View Code

    作用:列举数据源的key。

    3、DatabaseContextHolder

     View Code

    作用:构建一个DatabaseType容器,并提供了向其中设置和获取DatabaseType的方法

    4、DynamicDataSource

     View Code

    作用:使用DatabaseContextHolder获取当前线程的DatabaseType

    5、MyBatisConfig

     View Code

    作用:

    • 通过读取application.properties文件生成两个数据源(myTestDbDataSource、myTestDb2DataSource)
    • 使用以上生成的两个数据源构造动态数据源dataSource
      • @Primary:指定在同一个接口有多个实现类可以注入的时候,默认选择哪一个,而不是让@Autowire注解报错(一般用于多数据源的情况下)
      • @Qualifier:指定名称的注入,当一个接口有多个实现类的时候使用(在本例中,有两个DataSource类型的实例,需要指定名称注入)
      • @Bean:生成的bean实例的名称是方法名(例如上边的@Qualifier注解中使用的名称是前边两个数据源的方法名,而这两个数据源也是使用@Bean注解进行注入的)
    • 通过动态数据源构造SqlSessionFactory和事务管理器(如果不需要事务,后者可以去掉)

    6、使用

    ShopMapper:

     View Code

    ShopDao:

     View Code

    注意:首先设置了数据源的key,然后调用mapper(在mapper中会首先根据该key从动态数据源中查询出相应的数据源,之后取出连接进行数据库操作)

    ShopService:

     View Code

    ShopController:

     View Code

    补:其实DatabaseContextHolder和DynamicDataSource完全可以合为一个类

    参考:

    http://www.cnblogs.com/lzrabbit/p/3750803.html

    遗留:在实际开发中,一个dao类只会用到一个数据源,如果dao类中的方法很多的话,每一个方法前边都要添加一个设置数据源的一句话,代码有些冗余,可以使用AOP切面。

    具体的实现方式见 第九章 springboot + mybatis + 多数据源 (AOP实现)

    很多朋友反映遇到数据源循环依赖的问题,可以试一下将MyBatisConfig中的相关代码换成这样试试

     View Code

       https://www.cnblogs.com/java-zhao/p/5413845.html

  • 相关阅读:
    2008年DIY配台电脑
    Ubuntu替换清华源或者阿里源
    Flex里[Exclude]标签的作用:对外忽略/隐藏内部某对象
    UML中关联,依赖,聚集,组成的联系和区别
    在URLRequest中构造HTTP协议发送数据
    get flash object in different browser
    认识UML类图元素
    Intellisense – Making your components work with the Flash Builder IDE
    ACTIONSCRIPT 3.0著名开源库 大集合
    利用 StarUML 创建 AS3 代码
  • 原文地址:https://www.cnblogs.com/sjqq/p/10080130.html
Copyright © 2011-2022 走看看