前言,什么是数据源与数据库连接池:
说SpringBoot的多数据源配置之前,我们先了解下DataSource。
在java中,操作数据库有很多方式,在众多方式中除了JDBC外还有DataSource对象。
DataSource可以看作数据源:
它封装了数据库参数,连接数据库,程序中操作DataSource对象即可对数据库进行增删改查操作。
不同方式中使用的DataSource对象不同。列举如下:
不同方式中使用的DataSource对象不同。列举如下:
dbcp框架中的DataSource类是:org.apache.commons.dbcp.BasicDataSource
c3p0框架的DataSource类是:com.mchange.v2.c3p0.ComboPooledDataSource
MyBatis框架的DataSource类是:org.apache.ibatis.datasource.pooled.PooledDataSource
Druid框架的DataSource类是:com.alibaba.druid.pool.DruidDataSource
对于DataSource的一些实现,经常被叫做数据库连接池,
比如Druid官方文档中说“Druid是Java语言中最好的数据库连接池“,本质核心就是DataSource的一个实现类,作为中间层使用,并且基本上都提供了附带的其他的服务,也就是说不仅仅实现了核心建筑,也基于核心之上构建了很多的外围建设。
数据源和数据库连接池的关系:
-
数据源建立多个数据库连接,这些数据库连接会保存在数据库连接池中,
-
当需要访问数据库时,只需要从数据库连接池中获取空闲的数据库连接,
-
当程序访问数据库结束时,数据库连接会放回数据库连接池中。
在最开始学习JDBC的时候,我们自己获取一个数据连接的操作是这样的:
学习JDBC的时候,直接使用DriverManager的这种形式,通常需要将驱动程序硬编码到项目中(JDBC4.0后可以自动注册驱动程序)。而且最重要的是通过DriverManager的getConnection方法获取的连接,是建立与数据库的连接。 但是建立与数据库的连接是一项较耗资源的工作,频繁的进行数据库连接建立操作会产生较大的系统开销。 DataSource中获取的连接来自于连接池中,虽然池中的连接从根本上来说其实也还是从DriverManager获取而来。 DataSource就是DriverManager的一种替代角色,拥有对外提供连接的能力。
接下来看SpringBoot如何整合多数据源。
一,配置文件进行配置:
1,导入依赖:
如果你新增的数据库数据源和目前的数据库不同,记得引入新数据库的驱动依赖,比如 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>
首先,需要在配置文件中配置多数据源的连接信息;
- 这里采用yml配置文件,其他类型配置文件同理
- 我配置了两个数据源,一个名字叫ds1数据源,一个名字叫ds2数据源,如果你想配置更多的数据源,继续加就行了。
spring:
# 数据源配置
datasource:
ds1: #数据源1
driver-class-name: com.mysql.jdbc.Driver # mysql的驱动你可以配置别的关系型数据库
url: jdbc:mysql://ip:3306/db1 #数据源地址
username: root # 用户名
password: root # 密码
ds2: # 数据源2
driver-class-name: com.mysql.jdbc.Driver # mysql的驱动你可以配置别的关系型数据库
url: jdbc:mysql://ip:3307/db2#数据源地址
username: root # 用户名
password: root # 密码
二,编写配置类:
编写Springboot的配置类:
mybatis多数据源切换的原理是根据不同包,调用不同的数据源,
你只需要把你的mapper.java和mapper.xml 写在某个package中,springboot自动帮你实现数据源切换。
核心代码就这两句:
1,用来指定包扫描、指定sqlSessionTemplateRef;
@MapperScan(basePackages ="com.web.ds2.**.dao", sqlSessionTemplateRef = "ds2SqlSessionTemplate")
2,用来指定mapper.xml的路径;
sqlSessionFactory.
setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:com/web/ds2/**/*.xml"));
详细代码如下:
Mybatis主数据源ds1配置:
/**
* Mybatis主数据源ds1配置
* 多数据源配置依赖数据源配置
* @see DataSourceConfig
*/
@Configuration
@MapperScan(basePackages ="com.web.ds1.**.dao", sqlSessionTemplateRef = "ds1SqlSessionTemplate")
public class MybatisPlusConfig4ds1 {
@Bean(name = "dataSource1")
@ConfigurationProperties(prefix = "spring.datasource.ds1")
@Primary
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
//主数据源 ds1数据源
@Primary
@Bean("ds1SqlSessionFactory")
public SqlSessionFactory ds1SqlSessionFactory(@Qualifier("ds1DataSource") DataSource dataSource) throws Exception {
MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
sqlSessionFactory.setDataSource(dataSource);
sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().
getResources("classpath*:com/web/ds1/**/*.xml"));
return sqlSessionFactory.getObject();
}
@Primary
@Bean(name = "ds1TransactionManager")
public DataSourceTransactionManager ds1TransactionManager(@Qualifier("ds1DataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Primary
@Bean(name = "ds1SqlSessionTemplate")
public SqlSessionTemplate ds1SqlSessionTemplate(@Qualifier("ds1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
Mybatis第二个ds2数据源配置:
/**
* Mybatis 第二个ds2数据源配置
* 多数据源配置依赖数据源配置
* @see DataSourceConfig
*/
@Configuration
@MapperScan(basePackages ="com.web.ds2.**.dao", sqlSessionTemplateRef = "ds2SqlSessionTemplate")
public class MybatisPlusConfig4ds2 {
@Bean(name = "dataSource2")
@ConfigurationProperties(prefix = "spring.datasource.ds2")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
//ds2数据源
@Bean("ds2SqlSessionFactory")
public SqlSessionFactory ds2SqlSessionFactory(@Qualifier("ds2DataSource") DataSource dataSource) throws Exception {
MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
sqlSessionFactory.setDataSource(dataSource);
sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().
getResources("classpath*:com/web/ds2/**/*.xml"));
return sqlSessionFactory.getObject();
}
//事务支持
@Bean(name = "ds2TransactionManager")
public DataSourceTransactionManager ds2TransactionManager(@Qualifier("ds2DataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "ds2SqlSessionTemplate")
public SqlSessionTemplate ds2SqlSessionTemplate(@Qualifier("ds2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
代码解释:
-
@ConfigurationProperties(prefix = "spring.datasource.ds1"):使用spring.datasource.ds1开头的配置。
@Qualifier:指定数据源名称,与Bean中的name属性原理相同,主要是为了确保注入成功; @Primary:声明这是一个主数据源(默认数据源),多数据源配置时必不可少。
-
@Primary :声明这是一个主数据源(默认数据源),多数据源配置时必不可少。
-
@Qualifier:显式选择传入的 Bean。
注意
因为已经在两个数据源中分别配置了扫描的 Mapper 路径,如果你之前在 SpringBoot 启动类中也使用了 Mapper 扫描注解,需要删掉。
四,测试与使用:
Service层:
@Service
public class TestService {
@Resource
private ClusterMapper clusterMapper;
@Resource
private MasterMapper masterMapper;
public List<HashMap<String, Object>> queryBooks() {
return masterMapper.queryBooks(); //指定的配置类扫描的是一个包
}
public List<HashMap<String, Object>> queryOrders() {
return clusterMapper.queryOrders(); //指定的配置类扫描的是另一个包
}
}
Controller层:
@RestController
@RequestMapping(value = "/test", method = RequestMethod.POST)
public class TestController {
@Resource
private TestService testService;
@RequestMapping("/books")
public List<HashMap<String, Object>> queryBooks() {
return testService.queryBooks();
}
@RequestMapping("/orders")
public List<HashMap<String, Object>> queryOrders() {
return testService.queryOrders();
}
}
五,拓展
mybatis-plus集合多数据源
特性
- 数据源分组 ,适用于多种场景 纯粹多库 读写分离 一主多从 混合模式。
- 支持数据库敏感配置信息 加密 ENC()。
- 支持每个数据库独立初始化表结构schema和数据库database。
- 支持无数据源启动,支持懒加载数据源(需要的时候再创建连接)。
- 支持 自定义注解 ,需继承DS(3.2.0+)。
- 提供并简化对Druid,HikariCp,BeeCp,Dbcp2的快速集成。
- 提供对Mybatis-Plus,Quartz,ShardingJdbc,P6sy,Jndi等组件的集成方案。
- 供 自定义数据源来源 方案(如全从数据库加载)。
- 提供项目启动后 动态增加移除数据源 方案。
- 提供Mybatis环境下的 纯读写分离 方案。
- 提供使用 spel动态参数 解析数据源方案。内置spel,session,header,支持自定- 义。
- 支持 多层数据源嵌套切换 。(ServiceA >>> ServiceB >>> ServiceC)。
- 提供 **基于seata的分布式事务方案。
使用方法
1.引入依赖:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.5.0</version>
</dependency>
2.配置数据源
spring:
datasource:
dynamic:
primary: master #设置默认的数据源或者数据源组,默认值即为master
strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
datasource:
master:
url: jdbc:mysql://xx.xx.xx.xx:3306/dynamic
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver # 3.2.0开始支持SPI可省略此配置
slave_1:
url: jdbc:mysql://xx.xx.xx.xx:3307/dynamic
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
slave_2:
url: ENC(xxxxx) # 内置加密,使用请查看详细文档
username: ENC(xxxxx)
password: ENC(xxxxx)
driver-class-name: com.mysql.jdbc.Driver
#......省略
#以上会配置一个默认库master,一个组slave下有两个子库slave_1,slave_2
3.使用 @DS 切换数据源
@DS 可以注解在方法上或类上,同时存在就近原则 方法上注解 优先于 类上注解
代码:
package com.wl.demo.service.impl;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wl.demo.entity.User;
import com.wl.demo.service.UserService;
import com.wl.demo.mapper.UserMapper;
import org.springframework.stereotype.Service;
/**
* @author 13058
* @description 针对表【tb_user】的数据库操作Service实现
* @createDate 2022-07-22 21:11:28
*/
@Service
@DS("slave_1")
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
implements UserService{
}
标签:springboot,多个,数据源,数据库,配置,DataSource,com,public
From: https://www.cnblogs.com/guozhiqiang/p/16943315.html