SpringBoot结合Mybatis+Druid多数据源

1、分析

在Spring中配置MyBatis SqlSessionFactory的配置:

1
2
3
4
5
<!-- mybatis 的SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" scope="prototype">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>

所以实际上在Spring Boot中配置MyBatis多数据源的关键在于创建SqlSessionFactory的时候为其分配不同数据源。

2、整合过程

2.1 引入相关依赖(pom.xml)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>

<!-- oracle驱动 -->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>6.0</version>
</dependency>

<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>

<!-- druid数据源驱动 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.6</version>
</dependency>

2.2 多数据源配置

2.2.1 配置application.yml文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
server:
servlet:
context-path: /web #访问路径以/web开始 如:localhost:8080/web/xxx
spring:
datasource:
druid:
#数据库访问配置,使用druid数据源
#数据源1 mysql
mysql:
type: com.alibaba.druid.pool.DruidDataSource #数据库访问配置,使用druid数据源
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/test_dev
username: root
password: root
#数据源2 oracle
oracle:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: oracle.jdbc.driver.OracleDriver
url: jdbc:oracle:thin:@localhost:1521:ORCL
username: scott
password: ABab12

# 连接池配置
initial-size: 5 #初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者第一次getConnection时
min-idle: 5 # 最小连接池数量
max-active: 20 # 最大连接池数量
# 连接等待超时时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降
max-wait: 30000
# 配置检测可以关闭的空闲连接间隔时间
time-between-eviction-runs-millis: 60000
# 配置连接在池中的最小生存时间
min-evictable-idle-time-millis: 300000
# 验证数据库服务可用性的sql.用来检测连接是否有效的sql 因数据库方言而差, 例如 oracle 应该写成 SELECT 1 FROM DUAL
validation-query: select '1' from dual
# 申请连接时检测空闲时间,根据空闲时间再检测连接是否有效.建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRun
test-while-idle: true
# 申请连接时直接检测连接是否有效.申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
test-on-borrow: false
# 归还连接时检测连接是否有效.归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
test-on-return: false
# 打开PSCache,并且指定每个连接上PSCache的大小
pool-prepared-statements: true
max-open-prepared-statements: 20
max-pool-prepared-statement-per-connection-size: 20
# 配置监控统计拦截的filters, 去掉后监控界面sql无法统计, 'wall'用于防火墙
filters: stat,wall
# Spring监控AOP切入点,如x.y.z.service.*,配置多个英文逗号分隔
aop-patterns: com.lyq.servie.*


# WebStatFilter配置
web-stat-filter:
enabled: true
# 添加过滤规则
url-pattern: /*
# 忽略过滤的格式
exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*'

# StatViewServlet配置
stat-view-servlet:
enabled: true
# 访问路径为/druid时,跳转到StatViewServlet
url-pattern: /druid/*
# 是否能够重置数据
reset-enable: false
# 需要账号密码才能访问控制台
login-username: druid
login-password: druid123
# IP白名单
# allow: 127.0.0.1
# IP黑名单(共同存在时,deny优先于allow)
# deny: 192.168.1.218

# 配置StatFilter
filter:
stat:
log-slow-sql: true

2.2.2 创建数据源配置类

MysqlDataSourceConfig.java 与 OrclDataSourceConfig.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
@Configuration
@MapperScan(basePackages = MysqlDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "mysqlSqlSessionFactory")
public class MysqlDataSourceConfig {
// mysqldao扫描路径
static final String PACKAGE = "com.lyq.mysqldao";
// mybatis mapper扫描路径
static final String MAPPER_LOCATION = "classpath:mapper/mysql/*.xml";

/**
* @Primary 标志这个Bean,如果存在多个同类Bean候选时,该bean被优先考虑。
* 多数据源的时候,必须要有一个主数据源,采用@Primary标志该Bean
* @return
*/
@Primary
@Bean(name = "mysqlDataSource")
@ConfigurationProperties("spring.datasource.druid.mysql")
public DataSource mysqlDataSource() {
return DruidDataSourceBuilder.create().build();
}

@Bean(name = "mysqlTransactionManager")
@Primary
public DataSourceTransactionManager mysqlTransactionManager() {
return new DataSourceTransactionManager(mysqlDataSource());
}

@Bean(name = "mysqlSqlSessionFactory")
@Primary
public SqlSessionFactory mysqlSqlSessionFactory(
@Qualifier("mysqlDataSource") DataSource dataSource)
throws Exception {
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
//如果不使用xml的方式配置mapper,则可以省去下面这行mapper location的配置。
sessionFactory.setMapperLocations(
new PathMatchingResourcePatternResolver()
.getResources(MysqlDataSourceConfig.MAPPER_LOCATION));
return sessionFactory.getObject();
}
}

上面代码配置了一个名为mysqlDataSource的数据源,对应application.yml中spring.datasource.druid.mysql*前缀配置的数据库。然后创建了一个名为*mysqlSqlSessionFactory的Bean,并且注入了mysqldatasource。与此同时,还分别定了两个扫描路径PACKAGE和MAPPER_LOCATION,前者为Mysql数据库对应的mapper接口地址后者为对应的mapper xml文件路径**。

@Primary标志这个Bean如果在多个同类Bean候选时,该Bean优先被考虑。多数据源配置的时候,必须要有一个主数据源,用*@Primary*标志该Bean。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
@Configuration
@MapperScan(basePackages = OrclDataSourceConfig.PACKAGE,
sqlSessionFactoryRef = "orclSqlSessionFactory")
public class OrclDataSourceConfig {

// oracledao扫描路径
static final String PACKAGE = "com.lyq.orcldao";
// mybatis mapper扫描路径
static final String MAPPER_LOCATION = "classpath:mapper/orcl/*.xml";

@Bean(name = "orcldatasource")
@ConfigurationProperties("spring.datasource.druid.oracle")
public DataSource orclDataSource() {
return DruidDataSourceBuilder.create().build();
}

@Bean(name = "orclTransactionManager")
public DataSourceTransactionManager oracleTransactionManager() {
return new DataSourceTransactionManager(orclDataSource());
}

@Bean(name = "orclSqlSessionFactory")
public SqlSessionFactory oracleSqlSessionFactory(
@Qualifier("orcldatasource") DataSource dataSource) throws Exception {
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
//如果不使用xml的方式配置mapper,则可以省去下面这行mapper location的配置。
sessionFactory.setMapperLocations(
new PathMatchingResourcePatternResolver()
.getResources(OrclDataSourceConfig.MAPPER_LOCATION));
return sessionFactory.getObject();
}
}

2.3 配置Dao层接口

分别在com.springboot.mysqldao路径和com.springboot.oracledao路径下创建两个mapper接口:

MysqlStudentMapper.java

1
2
3
4
5
6
7
8
@Mapper
public interface MysqlStudentMapper {
int add(Student student);
int update(Student student);
int deleteByIds(String sno);
Student queryStudentById(String sno);
List<Map<String, Object>> getAllStudents();
}

​ OrclStudentMapper.java

1
2
3
4
5
6
7
8
@Mapper
public interface OrclStudentMapper {
int add(Student student);
int update(Student student);
int deleteByIds(String sno);
Student queryStudentById(String sno);
List<Map<String, Object>> getAllStudents();
}

2.4 创建Mapper接口对应的实现

在src/main/resource/mapper/mysql/路径下创建MysqlStudentMapper.xml:

1
2
3
4
5
6
7
8
<?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.lyq.mysqldao.MysqlStudentMapper">
<select id="getAllStudents" resultType="java.util.Map">
select * from student
</select>
</mapper>

在src/main/resource/mapper/oracle/路径下创建OrclStudentMapper.xml:

1
2
3
4
5
6
7
8
<?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.lyq.orcldao.OrclStudentMapper">
<select id="getAllStudents" resultType="java.util.Map">
select * from student
</select>
</mapper>

2.5 控制层及业务层

不再赘述

3、测试

新建一些测试数据,运行SpringBoot应用,发起对应请求

点击这里查看示例代码


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!