• springboot + mybatis + 多数据源


    此文已由作者赵计刚薪授权网易云社区发布。

    欢迎访问网易云社区,了解更多网易技术产品运营经验


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

    代码结构:

    2018120614100691f362d7-d379-415a-87b8-ce62d5a9443f.png


    简要原理:

    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

     View Code

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

     

    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

    或者看看评论区已经解决了问题的朋友的方案。


    免费领取验证码、内容安全、短信发送、直播点播体验包及云服务器等套餐

    更多网易技术、产品、运营经验分享请点击


    相关文章:
    【推荐】 交互设计如何为业务赋能——谈谈网易严选企业采购的主页设计
    【推荐】 数据分析思路的套路攻略

  • 相关阅读:
    A1066 Root of AVL Tree (25 分)
    A1099 Build A Binary Search Tree (30 分)
    A1043 Is It a Binary Search Tree (25 分) ——PA, 24/25, 先记录思路
    A1079; A1090; A1004:一般树遍历
    A1053 Path of Equal Weight (30 分)
    A1086 Tree Traversals Again (25 分)
    A1020 Tree Traversals (25 分)
    A1091 Acute Stroke (30 分)
    A1103 Integer Factorization (30 分)
    A1032 Sharing (25 分)
  • 原文地址:https://www.cnblogs.com/twodog/p/12135383.html
Copyright © 2020-2023  润新知