二. MyBatisPlus 多数据源配置
MyBatisPlus 的多数据源配置时,不用像 Jpa或者MyBatis 那样,配置不同的DataSource 和 Factory.与平常的 MyBatisPlus 开发基本一致。
MyBatisPlus 提供了 一个插件 dynamic-datasource-spring-boot-starter ,可以方便我们进行多数据源配置。
具体可以见官网文档: MyBatisPlus多数据源
将其与 Druid 进行整合,切换数据源。
二.一 pom.xml 依赖
<!--引入springboot与mybatis-plus整合的依赖。 去掉mybatis的依赖--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.3.2</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> <!--引入动态数据源配置--> <dependency> <groupId>com.baomidou</groupId> <artifactId>dynamic-datasource-spring-boot-starter</artifactId> <version>3.3.2</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: autoconfigure: # 去掉Druid 配置 //第一部分点 exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure # 自动配置,例外处理 datasource: # 配置数据源类型 type: com.alibaba.druid.pool.DruidDataSource dynamic: primary: one #设置默认的数据源或者数据源组,默认值即为master。 为了统一,设置成one strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源 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 # 配置第二个数据库 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 druid: # 其他的 Druid 连接池配置信息 max-active: 30 min-idle: 5 #整合mybatis时使用的 mybatis-plus: # 配置 mapper文件的位置 mapper-locations: classpath:mybatis/mapper/**/*Mapper.xml # 配置日志 configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl map-underscore-to-camel-case: true # 配置别名设置 global-config: db-config: logic-delete-field: flag # 逻辑删除的字段 logic-not-delete-value: 1 # 正常状态下,该字段的值 logic-delete-value: 0 # 删除后,该字段的值 table-underline: true # 驼峰方式转换 #分页插件 pagehelper: helperDialect: mysql reasonable: true supportMethodsArguments: true params: count=countSql
注意,第一部分的内容,即 spring.autoconfigure.exclude 去掉了 Druid的自动配置。
如果在 yml 配置文件中不去掉的话,那么则需要在启动类时进行去掉。
@MapperScan(value = "top.yueshushu.learn.mapper") @SpringBootApplication(exclude = {DruidDataSourceAutoConfigure.class}) public class MyBatisApplication { public static void main(String[] args) { SpringApplication.run(MyBatisApplication.class,args); System.out.println("运行 MybatisPlus 多数据源配置文件"); } }
注意,在启动类上,加上 @MapperScan 扫描。 这个不要忘记了, Mybatis多数据源配置时,需要去掉。
二.三 实体配置
在 pojo 包下, 分别创建两个包 one 和 two 包。
one 包下面放置所有使用 one 数据库实体的信息, two 包下面放置所有使用two数据库实体的信息
二.三.一 User.java 用户实体
@Data @NoArgsConstructor @AllArgsConstructor @TableName("user") public class User implements Serializable { /** * @param id id编号 * @param name 姓名 * @param sex 性别 * @param age 年龄 * @param description 描述 */ @TableId(value = "id",type =IdType.AUTO) private Integer id; @TableField("name") private String name; @TableField("sex") private String sex; @TableField("age") private Integer age; @TableField("description") private String description; }
二.三.二 Dept.java 部门实体
@Data @TableName("dept") public class Dept implements Serializable { /** * @param id id编号 * @param name 部门名称 */ @TableId(value = "id",type = IdType.AUTO) private Integer id; @TableField("name") private String name; }
二.四 mapper 和其映射文件 配置
在 mapper 包下, 创建 one 包和 two包
one 包下面放置所有使用 one 数据库的信息, two 包下面放置所有使用two数据库的信息
二. 四.一 UserMapper 和其映射文件
二.四.一.一 UserMapper.java 接口
//扫描由启动类进行扫描配置 public interface UserMapper extends BaseMapper<User> { //一个走 xml的方法 void batchAdd(@Param("userList") List<User> userList); }
二.四.一.二 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="batchAdd"> insert into user(name,sex,age,description) values <foreach collection="userList" item="user" open="" close="" separator=","> (#{user.name},#{user.sex},#{user.age},#{user.description}) </foreach> </insert> </mapper>
二.四.二 DeptMapper 和其映射文件
二.四.二.一 DeptMapper.java 接口
//扫描由启动类进行扫描配置 public interface DeptMapper extends BaseMapper<Dept> { //走 xml 的配置 void batchAdd(@Param("deptList") List<Dept> deptList); }
二.四.二.二 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="batchAdd"> insert into dept(name) values <foreach collection="deptList" item="user" open="" close="" separator=","> (#{user.name}) </foreach> </insert> </mapper>
二.五 接口及其实现
注意,在实现类上或者实现类的方法上,添加 @DS(“数据库的别名”) 的注解信息
二.五.一 UserService接口和其实现类
UserService.java
public interface UserService { void batchAddUser(List<User> userList); List<User> listUser(); //查询 springboot2 数据库的方法 List<Dept> listDept(); }
UserServiceImpl.java 实现类
@Service //在类上添加注解,表示类中所有的方法都走这个数据源。 @DS("one") public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Autowired private DeptMapper deptMapper; @Override public void batchAddUser(List<User> userList) { userMapper.batchAdd(userList); } @Override public List<User> listUser() { return userMapper.selectList(null); } //在方法上添加注解,表示这个方法走定义的数据源 @DS("two") @Override public List<Dept> listDept() { return deptMapper.selectList(null); } }
@DS(“数据库别名”) 注解到类上, 表示这个类中的所有的方法都默认走这个数据库。如果不填写的话,表示走默认配置的那个数据库。
注解到方法上,表示这个方法单独走自定义的数据库。 优先级比类上的注解高。
二.五.二 DeptService接口和其实现类
DeptService.java
public interface DeptService { void batchAddDept(List<Dept> deptList); List<Dept> listDept(); //走 springboot 数据库的方法 List<User> listUser(); }
DeptServiceImpl.java
@Service //采用 springboot2 的数据库 @DS("two") public class DeptServiceImpl implements DeptService { @Autowired private DeptMapper deptMapper; @Autowired private UserMapper userMapper; @Override public void batchAddDept(List<Dept> deptList) { deptMapper.batchAdd(deptList); } @Override public List<Dept> listDept() { return deptMapper.selectList(null); } //单独另外采用 springboot 的数据库 @DS("one") @Override public List<User> listUser() { return userMapper.selectList(null); } }
二.六 测试
二.六. 一 测试类编写
@SpringBootTest @RunWith(SpringJUnit4ClassRunner.class) @Log4j2 public class MyBatisPlusTests { @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("一个小坏蛋"); User user1=new User(); user1.setName("小泽霖"); user1.setAge(25); user1.setSex("男"); user1.setDescription("一个大坏蛋"); //这是修改的操作,id=2已经存在这条记录了。 User user2=new User(); user2.setName("岳泽霖"); user2.setAge(25); user2.setSex("男性"); user2.setDescription("一个快乐的程序员"); //2. 放置到集合里面 List<User> userList=new ArrayList<>(); userList.add(user); userList.add(user1); userList.add(user2); userService.batchAddUser(userList); } @Test public void listUserTest(){ System.out.println("User实现类:>>>>>>>>>>>查询员工"); List<User> userList=userService.listUser(); userList.forEach(n->log.info(n)); System.out.println("User实现类:>>>>>>>>>>>>查询部门"); List<Dept> deptList=userService.listDept(); deptList.forEach(n->log.info(n)); } @Test public void addDeptTest(){ //1. 构建对象 Dept dept=new Dept(); dept.setName("信息管理部"); Dept dept1=new Dept(); dept1.setName("研发部"); Dept dept2=new Dept(); dept2.setName("测试部"); //2. 放置到集合里面 List<Dept> deptList=new ArrayList<>(); deptList.add(dept); deptList.add(dept1); deptList.add(dept2); deptService.batchAddDept(deptList); log.info("添加部门成功"); } @Test public void listDeptTest(){ System.out.println("Dept实现类:>>>>>>>查询部门"); List<Dept> deptList=deptService.listDept(); deptList.forEach(n->log.info(n)); System.out.println("Dept实现类:>>>>>>>>>>>查询员工"); List<User> userList=deptService.listUser(); userList.forEach(n->log.info(n)); } /** * 数据源切换配置 */ @Test public void allDataSourceTest(){ addUserTest(); listDeptTest(); addDeptTest(); listUserTest(); } }
二.六.二 测试
员工的批量添加 和部门的批量添加
员工 addUserTest
对应 的数据库里面有相应的信息:
部门 addDeptTest
对应的数据库里面的信息
进行查询
User实现类 进行查询 listUserTest
Dept实现类 进行查询 listDeptTest
同时切换数据源 allDataSourceTest
也是成功的,数据表里面也有相应的数据。