所谓多数据源,就是一个 Java EE 项目中采用了不同数据库实例中的多个库,或者同一个数据库实例中多个不同的库。MyBatis 也可以配置多数据源,下面通过样例进行演示。
三、多数据源的配置与使用
1,添加依赖
首先编辑 pom.xml 文件,添加相关依赖:注意:跟前文相比,这里的数据库连接池依赖改用 druid-spring-boot-starter。druid-spring-boot-starter 可以帮助开发者在 Spring Boot 项目中轻松集成 Druid 数据库连接池和监控。
<!-- MyBatis依赖 --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency> <!-- 数据库驱动依赖 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- 数据库连接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency>
2,指明 xml 资源的位置
由于在 Maven 工程中,XML 配置文件建议写在 resources 目录下,但和前文一样我们 Mapper 映射文件写在包下,Maven 在运行时会忽略包下的 XML 文件。因此需要同样需要在 pom.xml 文件中重新指明资源文件位置,配置如下:
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> <!-- 重新指明资源文件位置 --> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> <resource> <directory>src/main/resources</directory> </resource> </resources> </build>
3,配置数据库链接
(1)假设我们需要同时连接如下 hangge、hangge2 这两个数据库。
(2)在 application.properties 中配置数据库连接信息:
# 数据源 1 spring.datasource.one.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.one.url=jdbc:mysql://localhost:3306/hangge spring.datasource.one.username=root spring.datasource.one.password=hangge1234 # 数据源 2 spring.datasource.two.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.two.url=jdbc:mysql://localhost:3306/hangge2 spring.datasource.two.username=root spring.datasource.two.password=hangge1234
4,配置数据源
创建 DataSourceConfig 配置数据源,根据 application.properties 中的配置生成两个数据源:
代码说明:
- DataSourceConfig 中提供了两个数据源:dsOne 和 dsTwo ,默认方法名即为实例名。
- @ConfigurationProperties 注解表示使用不同前缀的配置文件来创建不同的 DataSource 实例。
@Configuration public class DataSourceConfig { @Bean @ConfigurationProperties("spring.datasource.one") DataSource dsOne() { return DruidDataSourceBuilder.create().build(); } @Bean @ConfigurationProperties("spring.datasource.two") DataSource dsTwo() { return DruidDataSourceBuilder.create().build(); } }
5,配置 MyBatis
(1)配置 MyBatis,主要是提供 SqlSessionFactory 实例和 SqlSessionTemplate 实例。下面是第一个数据库的配置类:
代码说明:
- 在 @MapperScan 注解中指定 Mapper 接口所在的位置,同时指定 SqlSessionFactory 的实例名,则该位置下的 Mapper 将使用 SqlSessionFactory 实例。
- 提供 SqlSessionFactory 的实例,直接创建出来,同时将 DataSource 的实例设置给 SqlSessionFactory,这里创建的 SqlSessionFactory 实例也就是 @MapperScan 注解中 sqlSessionFactoryRef 参数指定的实例。
- 提供一个 SqlSessionTemplate 实例。这是一个线程安全类,主要用来管理 MyBatis 中的 SqlSession 操作。
@Configuration @MapperScan(value = "com.example.demo.mapper1", sqlSessionFactoryRef = "sqlSessionFactoryBean1") public class MyBatisConfigOne { @Autowired @Qualifier("dsOne") DataSource dsOne; @Bean SqlSessionFactory sqlSessionFactoryBean1() throws Exception { SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean(); factoryBean.setDataSource(dsOne); return factoryBean.getObject(); } @Bean SqlSessionTemplate sqlSessionTemplate1() throws Exception { return new SqlSessionTemplate(sqlSessionFactoryBean1()); } }
(2)下面是另一个数据库的配置类:
@Configuration @MapperScan(value = "com.example.demo.mapper2", sqlSessionFactoryRef = "sqlSessionFactoryBean2") public class MyBatisConfigTwo { @Autowired @Qualifier("dsTwo") DataSource dsTwo; @Bean SqlSessionFactory sqlSessionFactoryBean2() throws Exception { SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean(); factoryBean.setDataSource(dsTwo); return factoryBean.getObject(); } @Bean SqlSessionTemplate sqlSessionTemplate2() throws Exception { return new SqlSessionTemplate(sqlSessionFactoryBean2()); } }
6,创建实体类
(1)假设两个数据库中都要 Users 表,结构如下:
(2)创建对应的 User 实体类:
@Setter @Getter @NoArgsConstructor @ToString public class User { private Integer id; private String userName; private String passWord; }
7,创建数据库访问层
(1)首先分别在 com.example.demo.mapper1 和 com.example.demo.mapper2 包下创建两个不同的 Mapper。
- 下面是 com.example.demo.mapper1 下的 UserMapper1:
public interface UserMapper1 { ListgetAllUsers(); }
- 下面是 com.example.demo.mapper2 下的 UserMapper2:
public interface UserMapper2 { ListgetAllUsers(); }
(2)接着需要分别在 com.example.demo.mapper1 和 com.example.demo.mapper2 包下创建相应的 Mapper 映射文件。
- 下面是 com.example.demo.mapper1 下的 UserMapper1.xml:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.example.demo.mapper1.UserMapper1"> <select id="getAllUsers" resultType="com.example.demo.bean.User"> SELECT * FROM users </select> </mapper>
- 下面是 com.example.demo.mapper2 下的 UserMapper2.xml:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.example.demo.mapper2.UserMapper2"> <select id="getAllUsers" resultType="com.example.demo.bean.User"> SELECT * FROM users </select> </mapper>
8,创建 Controller
为方便演示,这里直接将两个 Mapper 注入到了 Controller 中,然后分别查询两个数据库中的数据。
@RestController public class HelloController { @Autowired UserMapper1 userMapper1; @Autowired UserMapper2 userMapper2; @RequestMapping("/test") public void test(){ Listusers1 = userMapper1.getAllUsers(); List users2 = userMapper2.getAllUsers(); System.out.println("数据库1>>>users>>>" + users1); System.out.println("数据库2>>>users>>>" + users2); return; }