首页 > 其他分享 >多数据源配置MyBatis(十七)

多数据源配置MyBatis(十七)

时间:2022-11-10 15:32:00浏览次数:69  
标签:十七 name 数据源 user import MyBatis org public


二八佳人体似酥,腰间仗剑斩愚夫。虽然不见人头落,暗里教君骨髓枯。

上一章简单介绍了多数据源配置Jpa(十六),如果没有看过,​​请观看上一章​​

工作中,在业务的发展或业务数据隔离的场景下,通常需要一个项目中引入多个数据源,

但SpringBoot默认的自动化配置是单数据源的,可以通过一些额外的配置,进行处理。

一. 多数据源配置前的工作准备

一.一 准备两个数据库 springboot 和springboot2

springboot 数据库里面存放着 user 表

springboot2 数据库表里面存放着 dept 表

-- 在 springboot 数据库里面 创建 user 表
use springboot;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(15) DEFAULT NULL,
`sex` varchar(20) DEFAULT NULL,
`age` int(6) DEFAULT NULL,
`description` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;

-- 在 springboot2 数据库里面 创建 dept 表
use springboot2;
CREATE TABLE `dept` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(200) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

一.二 准备对应的实体 User.java 和 Dept.java

User.java

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
/**
* @param id id编号
* @param name 姓名
* @param sex 性别
* @param age 年龄
* @param description 描述
*/
private Integer id;
private String name;
private String sex;
private Integer age;
private String description;
}

Dept.java

@Data
public class Dept {
/**
* @param id id编号
* @param name 部门名称
*/
private Integer id;
private String name;
}

一.三 Mybatis 的使用

关于 Mybatis 的使用,可以看老蝴蝶以前写的文章: ​​SpringBoot整合MyBatis(七)​​

项目目录:

多数据源配置MyBatis(十七)_数据库

二. Mybatis 多数据源配置

二.一 pom.xml 添加依赖

<!--mysql的依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--引入springboot与mybatis整合的依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.6</version>
</dependency>
<!-- 引入pagehelper分页插件 注意版本号要与 mybatis-plus 进行匹配到 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.12</version>
</dependency>

二.二 application.yml 配置多数据源

# 引入 数据库的相关配置
#spring:
# datasource:
# driver-class-name: com.mysql.cj.jdbc.Driver
# url: jdbc:mysql://localhost:3306/springboot?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8&useSSL=false&allowMultiQueries=true
# username: root
# password: abc123
# 配置成多数据源的形式
spring:
datasource:
# 配置第一个数据库
one:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/springboot?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8&useSSL=false
username: root
password: abc123
type: com.alibaba.druid.pool.DruidDataSource
# 配置第二个数据库
two:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/springboot2?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8&useSSL=false
username: root
password: abc123
type: com.alibaba.druid.pool.DruidDataSource
#整合mybatis时使用的
mybatis:
# 包别名 需要去掉
# type-aliases-package: top.yueshushu.learn.pojo
#映射文件路径 不能使用了
# mapper-locations: classpath:mybatis/**/*.xml
configuration:
#日志信息
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

二.三 实体配置

在 pojo 包下, 分别创建两个包 one 和 two 包。

one 包下面放置所有使用 one 数据库实体的信息, two 包下面放置所有使用two数据库实体的信息

多数据源配置MyBatis(十七)_数据库_02

二.三.一 User.java 用户实体

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {
/**
* @param id id编号
* @param name 姓名
* @param sex 性别
* @param age 年龄
* @param description 描述
*/
private Integer id;
private String name;
private String sex;
private Integer age;
private String description;
}

二.三.二 Dept.java 部门实体

@Data
public class Dept implements Serializable {
/**
* @param id id编号
* @param name 部门名称
*/
private Integer id;
private String name;
}

二.四 mapper 和其映射文件 配置

在 mapper 包下, 创建 one 包和 two包

one 包下面放置所有使用 one 数据库的信息, two 包下面放置所有使用two数据库的信息

多数据源配置MyBatis(十七)_数据库_03

多数据源配置MyBatis(十七)_spring_04

二. 四.一 UserMapper 和其映射文件

二.四.一.一 UserMapper.java 接口

//@Mapper 不进行配置扫描
public interface UserMapper {
// 其他的方法. 具体使用可以参考 Mybatis 章节
void addUser(@Param("user") User user);
List<User> listUser();
}

二.四.一.二 UserMapper.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="top.yueshushu.learn.mapper.mapper1.UserMapper">

<insert id="addUser">
insert into user(name,sex,age,description) values(
#{user.name},#{user.sex},#{user.age},#{user.description}
)
</insert>
<select id="listUser" resultType="top.yueshushu.learn.pojo.one.User">
select * from user
</select>
</mapper>

二.四.二 DeptMapper 和其映射文件

二.四.二.一 DeptMapper.java 接口

// @Mapper 不进行配置扫描
public interface DeptMapper {
// 其他的方法. 具体使用可以参考 Mybatis 章节
void addDept(@Param("dept") Dept dept);
List<Dept> listDept();
}

二.四.二.二 DeptMapper.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="top.yueshushu.learn.mapper.mapper2.DeptMapper">
<insert id="addDept">
insert into dept(name) values(
#{dept.name}
)
</insert>
<select id="listDept" resultType="top.yueshushu.learn.pojo.two.Dept">
select * from dept
</select>
</mapper>

二.五 启动类 去掉 MapperScan 扫描注解

// @MapperScan(value = "top.yueshushu.learn.mapper")  //去掉扫描注解
@SpringBootApplication
public class MyBatisApplication {
public static void main(String[] args) {
SpringApplication.run(MyBatisApplication.class,args);
System.out.println("运行 Mybatis 多数据源配置文件");
}
}

二.六 数据多数据源配置

主要配置 数据源 DataSource 和关于扫描库,扫描Mapper接口。

多数据源配置MyBatis(十七)_spring boot_05

二.六.一 DataSource 数据源配置

package top.yueshushu.learn.config;

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import javax.sql.DataSource;

/**
* @ClassName:DataSourceConfig
* @Description TODO
* @Author zk_yjl
* @Date 2021/9/2 11:50
* @Version 1.0
* @Since 1.0
**/
@Configuration
public class DataSourceConfig {
/**
* Mybatis 多数据源配置 springboot 数据库
* @return
*/
@Bean(name="dataSourceOne")
@ConfigurationProperties("spring.datasource.one")
@Primary
public DataSource dataSourceOne(){
return DruidDataSourceBuilder.create().build();
}

/**
* Mybatis 多数据源配置 springboot2 数据库
* @return
*/
@Bean(name="dataSourceTwo")
@ConfigurationProperties("spring.datasource.two")
public DataSource dataSourceTwo(){
return DruidDataSourceBuilder.create().build();
}
}

在 dataSourceOne() 方法上,多添加了一个注解 @Primary ,指定默认的库。 默认库为 springboot

二.六.二 配置扫描库和扫描实体

二.六.二.一 配置主库 dataSourceOne 扫描Mapper和事务

package top.yueshushu.learn.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.sql.DataSource;

/**
* @ClassName:JpaOneConfig
* @Description 数据库 springboot的Jpa 主库 配置信息
* @Author zk_yjl
* @Date 2021/9/6 18:00
* @Version 1.0
* @Since 1.0
**/
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
basePackages = "top.yueshushu.learn.repository.one", // 指定扫描仓库的位置
entityManagerFactoryRef = "localContainerEntityManagerFactoryBeanOne", //指定扫描实体的位置
transactionManagerRef = "platformTransactionManagerOne") //指定事务
public class JpaOneConfig {
@Resource(name="dataSourceOne")
DataSource dataSourceOne;
@Autowired
JpaProperties jpaProperties;

@Primary //配置默认
@Bean(name = "entityManagerPrimaryOne")
public EntityManager entityManagerOne(EntityManagerFactoryBuilder builder) {
return localContainerEntityManagerFactoryBeanOne(builder).getObject().createEntityManager();
}

@Bean
@Primary //配置默认
LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBeanOne(EntityManagerFactoryBuilder builder) {
return builder.dataSource(dataSourceOne)
// 设置实体的包
.packages("top.yueshushu.learn.pojo.one")
//设置配置信息
.properties(jpaProperties.getProperties())
//设置持久化的名称
.persistenceUnit("onePersistenceUnit")
.build();
}
@Bean
@Primary //配置默认
PlatformTransactionManager platformTransactionManagerOne(EntityManagerFactoryBuilder builder) {
LocalContainerEntityManagerFactoryBean factoryBeanOne = localContainerEntityManagerFactoryBeanOne(builder);
return new JpaTransactionManager(factoryBeanOne.getObject());
}
}

二.六.二.二 配置从库 dataSourceTwo 扫描Mapper和事务

package top.yueshushu.learn.config;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.annotation.Resource;
import javax.sql.DataSource;

/**
* @ClassName:DataSourceTwoMapperConfig
* @Description TODO
* @Author zk_yjl
* @Date 2021/9/2 12:29
* @Version 1.0
* @Since 1.0
**/
@Configuration
@MapperScan(
basePackages="top.yueshushu.learn.mapper.mapper2", //配置扫描的mapper接口
sqlSessionFactoryRef = "sqlSessionFactoryTwo", //使用的Factory
sqlSessionTemplateRef = "sqlSessionTemplateTwo") //使用的SqlSessionTemplate
public class DataSourceTwoMapperConfig {
@Resource(name="dataSourceTwo")
private DataSource dataSourceTwo;
/**本数据源扫描的mapper路径*/
static final String MAPPER_LOCATION = "classpath:mybatis/mapper/mapper2/**/*.xml";
/**
* 创建SqlSessionFactory 对象
*/
@Bean(name="sqlSessionFactoryTwo")
public SqlSessionFactory sqlSessionFactoryTwo(){
try{
SqlSessionFactoryBean sqlSessionFactoryBean=new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSourceTwo);
//设置mapper配置文件
sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCATION));
return sqlSessionFactoryBean.getObject();
}catch (Exception e){
e.printStackTrace();
return null;
}
}
/**
* 配置事务
* @param dataSourceTwo
* @return
*/
@Bean
public DataSourceTransactionManager dataSourceTransactionManagerTwo(
@Qualifier("dataSourceTwo") DataSource dataSourceTwo) {
return new DataSourceTransactionManager(dataSourceTwo);
}
/**
* 通过SqlSessionFactory 创建 SqlSessionTemplate
* @return
*/
@Bean(name="sqlSessionTemplateTwo")
public SqlSessionTemplate sqlSessionTemplate(){

return new SqlSessionTemplate(sqlSessionFactoryTwo());
}
}

二.七 接口及其实现

多数据源配置MyBatis(十七)_spring boot_06

二.七.一 UserService 接口及其实现类

UserService.java

public interface UserService {
void addUser(User user);
List<User> listUser();
}

UserServiceImpl.java

@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;

@Override
public void addUser(User user) {
userMapper.addUser(user);
}
@Override
public List<User> listUser() {
return userMapper.listUser();
}
}

二.七.二 DeptService 接口及其实现类

DeptService.java

public interface DeptService {
void addDept(Dept user);
List<Dept> listDept();
}

DeptServiceImpl.java

@Service
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptMapper deptMapper;

@Override
public void addDept(Dept user) {
deptMapper.addDept(user);
}
@Override
public List<Dept> listDept() {
return deptMapper.listDept();
}
}

二.八 测试

二.八.一 创建测试类

@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
@Log4j2
public class MyBatisTests {
@Autowired
private UserService userService;
@Autowired
private DeptService deptService;
@Test
public void addUserTest(){
//1. 构建对象
User user=new User();
user.setName("欢欢");
user.setAge(22);
user.setSex("女");
user.setDescription("一个非常可爱的女孩纸");
//2. 添加方法
userService.addUser(user);
log.info("添加员工成功");
}

@Test
public void listUserTest(){
List<User> userList=userService.listUser();
userList.forEach(n->log.info(n));
}
@Test
public void addDeptTest(){
//1. 构建对象
Dept dept=new Dept();
dept.setName("信息管理部");
//2. 添加方法
deptService.addDept(dept);
log.info("添加部门成功");
}

@Test
public void listDeptTest(){
List<Dept> deptList=deptService.listDept();
deptList.forEach(n->log.info(n));
}
/**
* 数据源切换配置
*/
@Test
public void allDataSourceTest(){
addUserTest();
listDeptTest();
addDeptTest();
listUserTest();
}
}

二.八.二 测试数据源

数据库源1

添加

多数据源配置MyBatis(十七)_数据库_07

查询

多数据源配置MyBatis(十七)_java_08

数据库 springboot 的 user 表里面,也只存储了这一条

多数据源配置MyBatis(十七)_java_09

数据源2

添加

多数据源配置MyBatis(十七)_java_10

查询

多数据源配置MyBatis(十七)_Mybatis多数据源_11

数据库 springboot2 的 dept 表里面,也只存储了这一条数据

多数据源配置MyBatis(十七)_java_12

数据源切换配置 测试

多数据源配置MyBatis(十七)_spring_13

再次查询数据库表

多数据源配置MyBatis(十七)_java_14

多数据源配置MyBatis(十七)_spring_15

数据源切换配置成功.

二.九 解决日志失效的问题

原因: 我们配置多数据源时,重新定义了 SqlSessionFactory.

如果需要打印的话,在配置SqlSessionFactory 时,添加 MyBatisProperties

经老蝴蝶测试, 发现配置日志时,只能配置在从数据库 即 dataSourceTwo 数据库上面。

sqlSessionFactoryOne 保持不变。

二.九.一 只能配置到 从数据源 dataSourceTwo

/**
* 创建SqlSessionFactory 对象
*/
@Bean(name="sqlSessionFactoryTwo")
//引入参数 MyBatisProperties,用于解决日志失效的问题
public SqlSessionFactory sqlSessionFactoryTwo(MybatisProperties mybatisProperties){
try{
SqlSessionFactoryBean sqlSessionFactoryBean=new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSourceTwo);
//设置mapper配置文件
sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCATION));
// 将 mybatis的配置,传递过来。
sqlSessionFactoryBean.setConfiguration(mybatisProperties.getConfiguration());
return sqlSessionFactoryBean.getObject();
}catch (Exception e){
e.printStackTrace();
return null;
}
}
//省略了事务的配置
/**
* 通过SqlSessionFactory 创建 SqlSessionTemplate
* @return
*/
//引入参数 MyBatisProperties,用于解决日志失效的问题
@Bean(name="sqlSessionTemplateTwo")
public SqlSessionTemplate sqlSessionTemplate(MybatisProperties mybatisProperties){
return new SqlSessionTemplate(sqlSessionFactoryTwo(mybatisProperties));
}

此时再次进行操作的话, 做查询操作

多数据源配置MyBatis(十七)_Mybatis多数据源_16

多数据源配置MyBatis(十七)_spring boot_17

本章节的代码放置在 github 上:

​https://github.com/yuejianli/springboot/tree/develop/MultipeDataSource_MyBatis​

谢谢您的观看,如果喜欢,请关注我,再次感谢 !!!


标签:十七,name,数据源,user,import,MyBatis,org,public
From: https://blog.51cto.com/u_13420484/5841799

相关文章