SpringBoot的MyBatis多数据源配置
点赞再看,动⼒⽆限。Hello world : ) 搜「」。
本⽂和已经收录,有很多知识点和系列⽂章。
最近在项⽬开发中,需要为⼀个使⽤ MySQL 数据库的 SpringBoot 项⽬,新添加⼀个 PLSQL 数据库数据源,那么就需要进⾏ SpringBoot 的多数据源开发。代码很简单,下⾯是实现的过程。
环境准备
实验环境:
JDK 1.8
SpringBoot 2.4.1plsql12配置数据库连接
Maven 3.6.3
MySQL 5.7
因为我本地只有 MySQL 数据库,为了⽅便演⽰,我会在启动⼀个本地 MySQL,在 MySQL 创建两个数据库,每个库中均有⼀个表,以此进⾏演⽰。
数据准备
本地 MySQL 端⼝默认不做改动,端⼝号 3306。
创建数据库 demo1,demo2。在 demo1 数据库中创建表 book。
-- create table
create table Book
(
id          int auto_increment
primary key,
author      varchar(64)  not null comment '作者信息',
name        varchar(64)  not null comment '书籍名称',
price      decimal      not null comment '价格',
createTime  datetime    null comment '上架时间',
description varchar(128) null comment '书籍描述'
);
-- insert data
INSERT INTO demo1.Book (id, author, name, price, createTime, description) VALUES (1, '⾦庸', '笑傲江湖', 13, '2020-12-19 15:26:51', '武侠⼩说');
INSERT INTO demo1.Book (id, author, name, price, createTime, description) VALUES (2, '罗贯中', '三国演义', 14, '2020-12-19 15:28:36', '历史⼩说');
在 demo2 数据库中创建表 user。
-- create table
create table User
(
id      int auto_increment
primary key,
name    varchar(32) null comment '⽤户名称',
birthday date        null comment '出⽣⽇期'
)
comment '⽤户信息表';
-- insert data
INSERT INTO demo2.User (id, name, birthday) VALUES (1, '⾦庸', '1924-03-10');
INSERT INTO demo2.User (id, name, birthday) VALUES (2, '罗贯中', '1330-01-10');
数据准备完毕,表中都新增了两条数据。
项⽬准备
这⾥直接从 Spring 官⽅上初始化⼀个添加了 web、lombok、mybatis、mysql 依赖的 SpringBoot 项⽬。
如果你⼿上已经有了⼀个 SpringBoot 项⽬,既然你想改造成多数据源,那么你应该已经有了⼀个数据源了,如果新增的数据源数据库和⽬前的⼀致,你可以直接使⽤你的项⽬进⾏改造测试。
多数据源
SpringBoot 的多数据源开发⼗分简单,如果多个数据源的数据库相同,⽐如都是 MySQL,那么依赖是不需要任何改动的,只需要进⾏多数据源配置即可。
如果你新增的数据库数据源和⽬前的数据库不同,记得引⼊新数据库的驱动依赖,⽐如 MySQL 和 PGSQL。
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.7</version>
</dependency>
连接配置
既然有多个数据源,因为数据库⽤户名密码可能不相同,所以是需要配置多个数据源信息的,直接在properties/yml中配置即可。这⾥要注意根据配置的属性名进⾏区分,同时因为数据源要有⼀个默认使⽤的数据源,最好在名称上有所区分(这⾥使⽤ primary 作为主数据源标识)。
>>>>># 主数据源 >>>>>>####
spring.datasource.primary.jdbc-url=jdbc:mysql://127.0.0.1:3306/demo1?characterEncoding=utf-8&serverTimezone=GMT%2B8
spring.datasource.primary.sql.jdbc.Driver
spring.datasource.primary.username=root
spring.datasource.primary.password=
>>>>># 第⼆个数据源 >>>>>>#
spring.datasource.datasource2.jdbc-url=jdbc:mysql://127.0.0.1:3306/demo2?characterEncoding=utf-8&serverTimezone=GMT%2B8
spring.datasource.datasource2.sql.jdbc.Driver
spring.datasource.datasource2.username=root
spring.datasource.datasource2.password=
# mybatis
mybatis.mapper-locations=classpath:mapper/*.xml
注意,配置中的数据源连接 url 末尾使⽤的是jdbc-url.
因为使⽤了 Mybatis 框架,所以 Mybatis 框架的配置信息也是少不了的,指定扫描⽬录mapper下的mapper xml配置⽂件。
Mybatis 配置
如何编写 Mybatis Mapper 或者如何使⽤⼯具⽣成Mybatis Mapper不是本⽂的重点,如果你不知道可以参考 Mybatis 官⽅⽂档或者我之前的⽂章。
链接⼀:
链接⼆:
下⾯我已经按照上⾯的两个库中的两个表,Book 和 User 表分别编写相应的 Mybatis 配置。
创建l和l放到配置⽂件配置的路径 mapper ⽬录下。创建 UserMapper
和 BookMapper 接⼝操作类放在不同的⽬录。这⾥注意 Mapper 接⼝要按数据源分开放在不同的⽬录中。后续好使⽤不同的数据源配置扫描不同的⽬录,这样就可以实现不同的Mapper 使⽤不同的数据源配置。
Service 层没有变化,这⾥ BookMapper 和 UserMapper 都有⼀个selectAll()⽅法⽤于查询测试。
多数据源配置
上⾯你应该看到了,到⽬前为⽌和 Mybatis 单数据源写法唯⼀的区别就是 Mapper 接⼝使⽤不同的⽬录分开了,那么这个不同点⼀定会在数据源配置中体现。
主数据源
开始配置两个数据源信息,先配置主数据源,配置扫描的MapperScan⽬录为com.wdbyte.mapper.primary
/**
* 主数据源配置
*
* @author niujinpeng
* @website: www.wdbyte
* @date 2020/12/19
*/
@Configuration
@MapperScan(basePackages = {"com.wdbyte.mapper.primary"}, sqlSessionFactoryRef = "sqlSessionFactory")
public class PrimaryDataSourceConfig {
@Bean(name = "dataSource")
@ConfigurationProperties(prefix = "spring.datasource.primary")
@Primary
public DataSource dataSource() {
ate().build();
}
@Bean(name = "sqlSessionFactory")
@Primary
public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
Object();
}
@Bean(name = "transactionManager")
@Primary
public DataSourceTransactionManager transactionManager(@Qualifier("dataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "sqlSessionTemplate")
@Primary
public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
和单数据源不同的是这⾥把
dataSource
sqlSessionFactory
transactionManager
sqlSessionTemplate
都单独进⾏了配置,简单的 bean 创建,下⾯是⽤到的⼀些注解说明。
@ConfigurationProperties(prefix = "spring.datasource.primary"):使⽤spring.datasource.primary 开头的配置。
@Primary:声明这是⼀个主数据源(默认数据源),多数据源配置时必不可少。
@Qualifier:显式选择传⼊的 Bean。
第⼆个数据源
第⼆个数据源和主数据源唯⼀不同的只是MapperScan扫描路径和创建的 Bean 名称,同时没有@Primary主数据源的注解。
/**
* 第⼆个数据源配置
*
* @author niujinpeng
* @website: www.wdbyte
* @date 2020/12/19
*/
@Configuration
@MapperScan(basePackages = {"com.wdbyte.mapper.datasource2"}, sqlSessionFactoryRef = "sqlSessionFactory2")
public class SecondDataSourceConfig {
@Bean(name = "dataSource2")
@ConfigurationProperties(prefix = "spring.datasource.datasource2")
public DataSource dataSource() {
ate().build();
}
@Bean(name = "sqlSessionFactory2")
public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource2") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
Object();
}
@Bean(name = "transactionManager2")
public DataSourceTransactionManager transactionManager(@Qualifier("dataSource2") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "sqlSessionTemplate2")
public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactory2") SqlSessionFactory
sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
注意:因为已经在两个数据源中分别配置了扫描的 Mapper 路径,如果你之前在 SpringBoot 启动类中也使⽤了 Mapper 扫描注解,需要删
掉。
访问测试
编写两个简单的查询 Controller 然后进⾏访问测试。// BookController
@RestController
public class BookController {
@Autowired
private BookService bookService;
@GetMapping(value = "/books")
public Response selectAll() throws Exception {
List<Book> books = bookService.selectAll();
return ResponseUtill.success(books);
}
}
// UserController
@RestController
public class UserController {
@Autowired
private UserService userService;
@ResponseBody
@GetMapping(value = "/users")
public Response selectAll() {
List<User> userList = userService.selectAll();
return ResponseUtill.success(userList);
}
}
访问测试,我这⾥直接 CURL 请求。
➜  ~ curl localhost:8080/books
{
"code": "0000",
"message": "success",
"data": [
{
"id": 1,
"author": "⾦庸",
"name": "笑傲江湖",
"price": 13,
"createtime": "2020-12-19T07:26:51.000+00:00",
"description": "武侠⼩说"
},
{
"id": 2,
"author": "罗贯中",
"name": "三国演义",
"price": 14,
"createtime": "2020-12-19T07:28:36.000+00:00",
"description": "历史⼩说"
}
]
}
➜  ~ curl localhost:8080/users
{
"code": "0000",
"message": "success",
"data": [
{
"id": 1,
"name": "⾦庸",
"birthday": "1924-03-09T16:00:00.000+00:00"
},
{
"id": 2,
"name": "罗贯中",
"birthday": "1330-01-09T16:00:00.000+00:00"
}
]
}
➜  ~
⾄此,多数据源配置完成,测试成功。
连接池
其实在多数据源改造中,我们⼀般情况下都不会使⽤默认的 JDBC 连接⽅式,往往都需要引⼊连接池进⾏连接优化,不然你可能会经常遇到数据源连接被断开等报错⽇志。其实数据源切换连接池数据源也是⼗分简单的,直接引⼊连接池依赖,然后把创建 dataSource 的部分换成连接池数据源创建即可。
下⾯以阿⾥的 Druid 为例,先引⼊连接池数据源依赖。
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
添加 Druid 的⼀些配置。
spring.datasource.datasource2.initialSize=3 # 根据⾃⼰情况设置
spring.datasource.datasource2.minIdle=3
spring.datasource.datasource2.maxActive=20
改写 dataSource Bean 的创建代码部分。
@Value("${spring.datasource.datasource2.jdbc-url}")
private String url;
@Value("${spring.datasource.datasource2.driver-class-name}")
private String driverClassName;
@Value("${spring.datasource.datasource2.username}")
private String username;
@Value("${spring.datasource.datasource2.password}")
private String password;
@Value("${spring.datasource.datasource2.initialSize}")
private int initialSize;
@Value("${spring.datasource.datasource2.minIdle}")
private int minIdle;
@Value("${spring.datasource.datasource2.maxActive}")
private int maxActive;
@Bean(name = "dataSource2")
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(url);
dataSource.setDriverClassName(driverClassName);
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSource.setInitialSize(initialSize);
dataSource.setMinIdle(minIdle);
dataSource.setMaxActive(maxActive);
return dataSource;
}
这⾥只是简单的提⼀下使⽤连接池的重要性,Druid 的详细⽤法还请参考官⽅⽂档。
<;完>
Hello world : ) 我是阿朗,⼀线技术⼯具⼈,认认真真写⽂章。
点赞的个个都是⼈才,不仅长得帅⽓好看,说话还好听。
⽂章持续更新,可以关注「」或访问「」。
回复【资料】有我准备的各系列知识点和必看书籍。
本⽂已经收录,有很多知识点和系列⽂章,欢迎Star。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。

发表评论