在分库的业务场景和跨数据库实例获取信息之类的场景中,我们会遇到处理多个数据源访问的问题,通常情况下可以采用中间件,如cobar, tddl, mycat等。
但取决于业务需求,有时我们需要直接通过MyBatis和SpringData来完成这个任务。即使没有,理解MyBatis多数据源配置的过程也有助于理解其他分库分表操作的原理。
背景依赖如下:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
</dependencies>
要进行多数据源的配置,首先需要了解MyBatis是如何将XML中的Sql语句执行的,是哪些类提供了数据库的连接,又是哪些类提供了配置参数。
首先来看MyBatis的SQL执行过程:
不难看出,与数据源相关的处理是在第4、5步中完成的。第四步获取到的SqlSessionFactory为第五步的SqlSession提供了连接工具,也就是说我们只需要对第四步进行处理,替换掉原生的DefaultSqlSessionFactory即可。
接下来,在SpringBoot框架下,我们可以通过常用的FactoryBean<T>来尝试获取SqlSessionFactory:
通过查找FactoryBean与SqlSessionFactory的交集,不难找到SqlSessionFactoryBean,这个类中包含大量与数据库连接配置相关的字段。
并且因为它实现了FactoryBean<T>,可以通过getObject()方法来获得一个SqlSessionFactory的实例。
通过分析SqlSessionFactoryBean的参数,对于多数据源的处理,基本的可以分为两种思路:
- 不同数据源使用的SQL语句不同(一般见于跨业务实例数据访问),通过不同的SqlSessionFactory管理不同包中的mapper来实现。
- 不同数据源使用的SQL语句相同(一般见于分表场景),通过在语句执行前动态替换线程所使用的数据源来完成。
对于第一种情况,处理方式非常简单,通过配置多个SqlSessionFactory,为每一个配置不同