目录
- 1.1 引入pom依赖
- 1.2 application.yml 配置
- 1.3 JavaBean对象
- 1.3.1 `第一个数据源Master` JavaBean对象
- 1.3.2 `第二个数据源Branch` JavaBean对象
- 1.4 myBatisPlus自动填充策略
- 1.5 数据源配置
- 1.5.1 Master数据源配置
- 1.5.1 branch数据源配置
- 1.6 雪花算法工具类
- 1.7 xml配置
- 1.8 启动类配置
- 1.9 数据源测试
- 1.9.1 Master数据源测试
- 1.9.2 Branch数据源测试
- 链接:[以 MyBatis-Plus 为框架 搭建最简易多数据源(不同包下走不同的数据源)祥例使用 源代码下载地址]()
1.1 引入pom依赖
- 引入SpringBoot和SpringCloud版本时特别注意下他们的
兼容
参考: https://spring.io/projects/spring-cloud
<!--引入springboot父工程依赖-->
<!--引入依赖作用:
可以省去version标签来获得一些合理的默认配置
-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
</parent>
<!--因为用eureka,是springCloud的,所以引入springCloud版本锁定-->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<!--spring cloud 版本 springBoott和springCloud版本要对应起来-->
<spring-cloud.version>Hoxton.SR10</spring-cloud.version>
</properties>
<!--引入Spring Cloud 依赖-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!--引入eureka-client jar包 这是eureka客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--因为要启动此项目,所以需要启动类-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--用@Data 减少JavaBean get...set...方法-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--链接Spring Boot和MyBatis-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.2</version>
</dependency>
<!--两个用来做测试的jar包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
1.2 application.yml 配置
- 主要配置
多个mysql地址
和eureka注册地址- eureka配置可参考: EurekaService服务端创建 EurekaClient客户端创建
- 这里
spring.datasource.master
和spring.datasource.branch
路径是自定义的 用来从代码中读取到此数据源
server:
#客户端端口号
port: 8080
mybatis-plus:
mapper-locations: classpath*:mappings/*/*.xml #扫描mapper
type-aliases-package: com.it.mhh.entity #扫描实体类
global-config:
banner: false
db-config:
id-type: ID_WORKER #主键类型 NONE:"数据库ID自增", INPUT:"用户输入ID", ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID", AUTO: MP自动决定;
logic-not-delete-value: normal #逻辑删除配置
logic-delete-value: deleted #逻辑删除配置
configuration:
map-underscore-to-camel-case: true
spring:
datasource:
master:
driver-class-name: com.mysql.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3306/mhh_master?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
username: root
password: root
branch:
driver-class-name: com.mysql.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3306/mhh_branch?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
username: root
password: root
application:
#客户端注册名字 ,在注册中心Application的名字
name: client-general-mapper
eureka:
client:
#因为是客户端,所以需要自我注册,注册到eureka-server中 默认:true
register-with-eureka: true
#从客户端拉取服务,后面你不止用自己一个服务,可能会通过feign接口调用server中别的服务,所以需要拉取服务 默认:true
fetch-registry: true
service-url:
defaultZone: http://localhost:8761/eureka #注册中心地址,如果集群,有几个写几个,逗号分隔
instance:
# 更倾向使用ip地址,而不是host名
prefer-ip-address: true
#注册中心中测项目Status的名字
instance-id: ${eureka.instance.ip-address}
# ip地址 这是客户端的注册地址, eureka 会通过这个地址建立管道
ip-address: 127.0.0.1 #默认0.0.0.0.0.0.1
# 表示eureka client发送心跳给server端的频率,续约间隔,默认30秒(只要服务端没有接收到,并不会直接剔除,会先把Status变为Down状态)
lease-renewal-interval-in-seconds: 5
# 表示eureka server至上一次收到client的心跳之后,等待下一次心跳的超时时间,在这个时间内若没收到下一次心跳,则将移除该instance
lease-expiration-duration-in-seconds: 15
1.3 JavaBean对象
1.3.1 第一个数据源Master
JavaBean对象
- 用的都是mybatisplus注解
- @Data中有五
- 此javaBean对象对应的是MySql中的表 用@TableName注解指定表名
- @TableField(fill = FieldFill.*)这个注解中的 fill 是
指定数据库表的字段的填充策略
- 实现myBatisPlus自动填充策略
要实现myBatisPlus里的MetaObjectHandler接口
- 这里主要说下多数据源的配置 就不多说myBatisPlus的东西了(后期专门写个MyBatisPlus的)
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
@Data
@TableName("student")
public class StudentMaster implements Serializable {
public StudentMaster(long masterId, String masterName, Integer masterAge) {
this.masterId = masterId;
this.masterName = masterName;
this.masterAge = masterAge;
}
/*
INPUT 如果开发者没有手动赋值,则数据库通过自增的方式给主键赋值,如果开发者手动赋值,则存入该值。
AUTO 默认就是数据库自增,开发者无需赋值。
ASSIGN_ID MP 自动赋值,雪花算法。
ASSIGN_UUID 主键的数据类型必须是 String,自动生成 UUID 进行赋值
* */
@TableId(value = "id",type = IdType.ASSIGN_ID)
private long masterId;
/*
映射非主键字段,value 映射字段名
exist 表示是否为数据库字段 false,如果实体类中的成员变量在数据库中没有对应的字段,则可以使用 exist,VO、DTO
select 表示是否查询该字段
fill 表示是否自动填充,将对象存入数据库的时候,由 MyBatis Plus 自动给某些字段赋值,create_time、update_time
* */
@TableField(value = "name")
private String masterName;
@TableField(value = "age")
private Integer masterAge;
// 第一次添加填充
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createDate;
// 第一次添加的时候填充,但之后每次更新也会进行填充
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateDate;
}
1.3.2 第二个数据源Branch
JavaBean对象
- 用的都是mybatisplus注解
- 此javaBean对象对应的是MySql中的表 用@TableName注解指定表名
- @TableField(fill = FieldFill.*)这个注解中的 fill 是
指定数据库表的字段的填充策略
- 实现myBatisPlus自动填充策略
要实现myBatisPlus里的MetaObjectHandler接口
- 这里主要说下多数据源的配置 就不多说myBatisPlus的东西了(后期专门写个MyBatisPlus的)
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.util.Date;
@Data
@TableName("student")
public class StudentBranch {
public StudentBranch(long branchId, String branchName, String branchAddress, String branchTeacher) {
this.branchId = branchId;
this.branchName = branchName;
this.branchAddress = branchAddress;
this.branchTeacher = branchTeacher;
}
/*
INPUT 如果开发者没有手动赋值,则数据库通过自增的方式给主键赋值,如果开发者手动赋值,则存入该值。
AUTO 默认就是数据库自增,开发者无需赋值。
ASSIGN_ID MP 自动赋值,雪花算法。
ASSIGN_UUID 主键的数据类型必须是 String,自动生成 UUID 进行赋值
* */
@TableId(value = "id",type = IdType.ASSIGN_ID)
private long branchId;
/*
映射非主键字段,value 映射字段名
exist 表示是否为数据库字段 false,如果实体类中的成员变量在数据库中没有对应的字段,则可以使用 exist,VO、DTO
select 表示是否查询该字段
fill 表示是否自动填充,将对象存入数据库的时候,由 MyBatis Plus 自动给某些字段赋值,create_time、update_time
* */
@TableField(value = "name")
private String branchName;
@TableField(value = "address")
private String branchAddress;
@TableField(value = "teacher")
private String branchTeacher;
// 第一次添加填充
@TableField(fill = FieldFill.INSERT)
private Date createTime;
// 第一次添加的时候填充,但之后每次更新也会进行填充
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
}
1.4 myBatisPlus自动填充策略
- 这个主要是配合JavaBean对象中@TableField()中 fill 属性
- @TableField()中 fill 属性为 FieldFill.INSERT表示只在第一次新增添加时赋值 走下面自己自动填充处理类 insertFill方法
- @TableField()中 fill 属性为 FieldFill.INSERT_UPDATE 表示 新增修改时都会自动赋值 走下面自己自动填充处理类 updateFill方法
实现自动填充策略 需实现MetaObjectHandler接口
- setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject)三个入参 第一个 给哪个属性赋值,把属性名填上,第二个 要自动填充什么值,第三个 为 元对象
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.Date;
/**
* 自动填充处理类
* @author Mhh
* @version 1.0
* @see
**/
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
private static final Logger logger = LoggerFactory.getLogger(MyMetaObjectHandler.class);
public MyMetaObjectHandler() {
}
public void insertFill(MetaObject metaObject) {
this.setFieldValByName("createDate", LocalDateTime.now(), metaObject);
this.setFieldValByName("createTime", new Date(), metaObject);
this.setFieldValByName("updateDate", LocalDateTime.now(), metaObject);
this.setFieldValByName("updateTime", new Date(), metaObject);
}
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("updateDate", LocalDateTime.now(), metaObject);
this.setFieldValByName("updateTime", new Date(), metaObject);
}
}
1.5 数据源配置
1.5.1 Master数据源配置
一个大坑:
我用的是MyBatisPlusMyBatisPlus有自己的数据源MybatisSqlSessionFactoryBean
用SqlSessionFactoryBean会报Invalid bound statement not found ** 错误驼峰命名:
mybatisConfiguration.setMapUnderscoreToCamelCase(true);因为现在是自己手写DataSource了 所有yml配置的不再有作用引入自动填充类:
注意引入一下刚才写的自定义自动填充类 因为现在是自己手写DataSource, java不会在自己帮我们引入 需要手动引入设置下否则不生效
配置mapper的xml形式文件:
mapper的xml形式文件位置必须要配置不然将报错:no statement
,因为现在是自己手写DataSource了 所有yml配置的不再有作用@MapperScan注解中属性配置:
basePackages属性:
我需要的核心 指定扫描哪个包 那么这个包下的所有mapper就走此配置,sqlSessionFactoryRef属性:
既然知道那些包下的mapper走那些配置了 那么这个属性就是指定的走那个数据源,@Bean已经指定数据源的名字了@Primary:
表示这个数据源是默认数据源, 这个注解必须要加,因为不加的话spring将分不清楚那个为主数据源(默认数据源)@ConfigurationProperties注解:
中prefix 属性指定的就是 yml里配置的MySql的地址、账号和密码
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.it.mhh.utils.MyMetaObjectHandler;
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.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import javax.sql.DataSource;
@Configuration
@MapperScan(basePackages = "com.it.mhh.master.dao", sqlSessionFactoryRef = "masterSqlSessionFactory")
public class MasterDataSourceConfig {
@Autowired
private MyMetaObjectHandler myMetaObjectHandler;
@Primary // 表示这个数据源是默认数据源, 这个注解必须要加,因为不加的话spring将分不清楚那个为主数据源(默认数据源)
@Bean("masterDataSource")
@ConfigurationProperties(prefix = "spring.datasource.master") //读取application.yml中的配置参数映射成为一个对象
public DataSource getmasterDataSource(){
return DataSourceBuilder.create().build();
}
@Primary
@Bean("masterSqlSessionFactory")
public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource dataSource) throws Exception {
//SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
bean.setDataSource(dataSource);
//驼峰命名
//org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
MybatisConfiguration mybatisConfiguration = new MybatisConfiguration();
mybatisConfiguration.setMapUnderscoreToCamelCase(true);
//引入自定以自动填充类
GlobalConfig globalConfig=new GlobalConfig();
globalConfig.setMetaObjectHandler(myMetaObjectHandler);
bean.setGlobalConfig(globalConfig);
//configuration.setMapUnderscoreToCamelCase(true);
bean.setConfiguration(mybatisConfiguration);
// mapper的xml形式文件位置必须要配置,不然将报错:no statement (这种错误也可能是mapper的xml中,namespace与项目的路径不一致导致)
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mappings/master/*.xml"));
return bean.getObject();
}
@Primary
@Bean("masterSqlSessionTemplate")
public SqlSessionTemplate masterSqlSessionTemplate(@Qualifier("masterSqlSessionFactory") SqlSessionFactory sqlSessionFactory){
return new SqlSessionTemplate(sqlSessionFactory);
}
}
1.5.1 branch数据源配置
一个大坑:
我用的是MyBatisPlusMyBatisPlus有自己的数据源MybatisSqlSessionFactoryBean
用SqlSessionFactoryBean会报Invalid bound statement not found ** 错误驼峰命名:
mybatisConfiguration.setMapUnderscoreToCamelCase(true);因为现在是自己手写DataSource了 所有yml配置的不再有作用引入自动填充类:
注意引入一下刚才写的自定义自动填充类 因为现在是自己手写DataSource, java不会在自己帮我们引入 需要手动引入设置下否则不生效
配置mapper的xml形式文件:
mapper的xml形式文件位置必须要配置不然将报错:no statement
,因为现在是自己手写DataSource了 所有yml配置的不再有作用@MapperScan注解中属性配置:
basePackages属性:
我需要的核心 指定扫描哪个包 那么这个包下的所有mapper就走此配置,sqlSessionFactoryRef属性:
既然知道那些包下的mapper走那些配置了 那么这个属性就是指定的走那个数据源,@Bean已经指定数据源的名字了@Primary:
表示这个数据源是默认数据源, 这个注解必须要加,因为不加的话spring将分不清楚那个为主数据源(默认数据源)@ConfigurationProperties注解:
中prefix 属性指定的就是 yml里配置的MySql的地址、账号和密码
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.it.mhh.utils.MyMetaObjectHandler;
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.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import javax.sql.DataSource;
@Configuration
@MapperScan(basePackages = "com.it.mhh.branch.dao", sqlSessionFactoryRef = "branchSqlSessionFactory")
public class BranchDataSourceConfig {
@Autowired
private MyMetaObjectHandler myMetaObjectHandler;
@Bean("branchDataSource")
@ConfigurationProperties(prefix = "spring.datasource.branch")
public DataSource getBranchDataSource(){
return DataSourceBuilder.create().build();
}
@Bean("branchSqlSessionFactory")
public SqlSessionFactory branchSqlSessionFactory(@Qualifier("branchDataSource") DataSource dataSource) throws Exception {
MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
bean.setDataSource(dataSource);
//驼峰命名
//org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
MybatisConfiguration mybatisConfiguration = new MybatisConfiguration();
mybatisConfiguration.setMapUnderscoreToCamelCase(true);
//configuration.setMapUnderscoreToCamelCase(true);
//引入自定以自动填充类
GlobalConfig globalConfig=new GlobalConfig();
globalConfig.setMetaObjectHandler(myMetaObjectHandler);
bean.setGlobalConfig(globalConfig);
bean.setConfiguration(mybatisConfiguration);
// mapper的xml形式文件位置必须要配置,不然将报错:no statement (这种错误也可能是mapper的xml中,namespace与项目的路径不一致导致)
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mappings/branch/*.xml"));
return bean.getObject();
}
@Bean("branchSqlSessionTemplate")
public SqlSessionTemplate branchSqlSessionTemplate(@Qualifier("branchSqlSessionFactory") SqlSessionFactory sqlSessionFactory){
return new SqlSessionTemplate(sqlSessionFactory);
}
}
1.6 雪花算法工具类
snowFlake.nextId():
获得值,Long类型
public class SnowFlake {
// 起始的时间戳
private final static long START_STMP = 1577808000000L; //2020-01-01
// 每一部分占用的位数,就三个
private final static long SEQUENCE_BIT = 12; //序列号占用的位数
private final static long MACHINE_BIT = 5; //机器标识占用的位数
private final static long DATACENTER_BIT = 5; //数据中心占用的位数
// 每一部分最大值
private final static long MAX_DATACENTER_NUM = -1L ^ (-1L << DATACENTER_BIT);
private final static long MAX_MACHINE_NUM = -1L ^ (-1L << MACHINE_BIT);
private final static long MAX_SEQUENCE = -1L ^ (-1L << SEQUENCE_BIT);
// 每一部分向左的位移
private final static long MACHINE_LEFT = SEQUENCE_BIT;
private final static long DATACENTER_LEFT = SEQUENCE_BIT + MACHINE_BIT;
private final static long TIMESTMP_LEFT = DATACENTER_LEFT + DATACENTER_BIT;
private long datacenterId; //数据中心
private long machineId; //机器标识
private long sequence = 0L; //序列号
private long lastStmp = -1L; //上一次时间戳
public SnowFlake(long datacenterId, long machineId) {
if (datacenterId > MAX_DATACENTER_NUM || datacenterId < 0) {
throw new IllegalArgumentException("datacenterId can't be greater than MAX_DATACENTER_NUM or less than 0");
}
if (machineId > MAX_MACHINE_NUM || machineId < 0) {
throw new IllegalArgumentException("machineId can't be greater than MAX_MACHINE_NUM or less than 0");
}
this.datacenterId = datacenterId;
this.machineId = machineId;
}
//产生下一个ID
public synchronized long nextId() {
long currStmp = timeGen();
if (currStmp < lastStmp) {
throw new RuntimeException("Clock moved backwards. Refusing to generate id");
}
if (currStmp == lastStmp) {
//if条件里表示当前调用和上一次调用落在了相同毫秒内,只能通过第三部分,序列号自增来判断为唯一,所以+1.
sequence = (sequence + 1) & MAX_SEQUENCE;
//同一毫秒的序列数已经达到最大,只能等待下一个毫秒
if (sequence == 0L) {
currStmp = getNextMill();
}
} else {
//不同毫秒内,序列号置为0
//执行到这个分支的前提是currTimestamp > lastTimestamp,说明本次调用跟上次调用对比,已经不再同一个毫秒内了,这个时候序号可以重新回置0了。
sequence = 0L;
}
lastStmp = currStmp;
//就是用相对毫秒数、机器ID和自增序号拼接
return (currStmp - START_STMP) << TIMESTMP_LEFT //时间戳部分
| datacenterId << DATACENTER_LEFT //数据中心部分
| machineId << MACHINE_LEFT //机器标识部分
| sequence; //序列号部分
}
private long getNextMill() {
long mill = timeGen();
while (mill <= lastStmp) {
mill = timeGen();
}
return mill;
}
private long timeGen() {
return System.currentTimeMillis();
}
}
1.7 xml配置
这里注意的是 一定要和手写数据源的mapper的xml形式文件位置对应起来
MasterDaoMapper
<?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.it.mhh.master.dao.MasterDaoMapper">
</mapper>
BranchDaoMapper
<?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.it.mhh.branch.dao.BranchDaoMapper">
</mapper>
1.8 启动类配置
- 将雪花算法工具类引入到 ioc中
雪花算法入参的两个值:
机器Id,只要不和别的机器Id重复就行(范围:0-32 0-32)
import com.it.mhh.utils.SnowFlake;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
@EnableEurekaClient
@SpringBootApplication
public class MultipleDataSourcesApplication {
public static void main(String[] args) {
SpringApplication.run(MultipleDataSourcesApplication.class,args);
}
@Bean
public SnowFlake snowFlake(){
return new SnowFlake(0,0);
}
}
1.9 数据源测试
1.9.1 Master数据源测试
Controller层:MasterController
import com.it.mhh.entity.StudentMaster;
import com.it.mhh.master.service.MasterService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("master")
public class MasterController {
@Autowired
private MasterService masterService;
@RequestMapping("/insertMaster")
public Boolean insertMaster(@RequestBody StudentMaster studentMaster) {
return masterService.insertMaster(studentMaster);
}
public Boolean updateMaster(@RequestBody StudentMaster studentMaster) {
return masterService.updateMaster(studentMaster);
}
}
ServiceImpl层:MasterServiceImpl
MyBatis-Plus的通用service:
实现类继承ServiceImpl<操作实体的Mapper接口,具体实体类>,最后添加注解@Service将该类作为Spring容器下的Bean。
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.it.mhh.entity.StudentMaster;
import com.it.mhh.master.dao.MasterDaoMapper;
import com.it.mhh.master.service.MasterService;
import org.springframework.stereotype.Service;
@Service
public class MasterServiceImpl extends ServiceImpl<MasterDaoMapper, StudentMaster> implements MasterService {
@Override
public Boolean insertMaster(StudentMaster studentMaster) {
return this.baseMapper.insert(studentMaster)>0?true:false;
}
@Override
public Boolean updateMaster(StudentMaster studentMaster) {
return this.baseMapper.updateById(studentMaster)>0?true:false;
}
}
dao层:MasterDaoMapper
哪个包下:
这里我特意把包路径也截取了过来 对应手写数据源@MapperScan注解中的basePackages属性
package com.it.mhh.master.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.it.mhh.entity.StudentMaster;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface MasterDaoMapper extends BaseMapper<StudentMaster> {
}
测试:
- 可以看到日期也添加进去了 我没有给日期赋值 表明上面的myBatisPlus自动填充策略
生效
- 通过@MapperScan注解扫描,可知是走的masterSqlSessionFactory此配置;
masterSqlSessionFactory配置的MySql地址和表是localhost:3306/mhh_master
test方式测试结果:
import com.it.mhh.entity.StudentMaster;
import com.it.mhh.master.controller.MasterController;
import com.it.mhh.utils.SnowFlake;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@SpringBootTest
@RunWith(SpringRunner.class)
public class MultipleDataSourcesApplicationTest {
@Autowired
private MasterController masterController; //主数据源
@Autowired
private SnowFlake snowFlake; //雪花算法
@Test
public void masterInsert() {
Boolean aBoolean = masterController.insertMaster(new StudentMaster(snowFlake.nextId(), "小白", 12));
System.out.println(aBoolean);
}
}
1.9.2 Branch数据源测试
Controller层:MasterController
import com.it.mhh.branch.service.BranchService;
import com.it.mhh.entity.StudentBranch;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("branch")
public class BranchController {
@Autowired
private BranchService branchService;
@RequestMapping(value = "insertBranch")
public Boolean insertBranch(@RequestBody StudentBranch studentBranch) {
return branchService.insertBranch(studentBranch);
}
}
ServiceImpl层:MasterServiceImpl
MyBatis-Plus的通用service:
实现类继承ServiceImpl<操作实体的Mapper接口,具体实体类>,最后添加注解@Service将该类作为Spring容器下的Bean。
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.it.mhh.branch.dao.BranchDaoMapper;
import com.it.mhh.branch.service.BranchService;
import com.it.mhh.entity.StudentBranch;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class BranchServiceImpl extends ServiceImpl<BranchDaoMapper, StudentBranch> implements BranchService {
/* @Autowired
private BranchDaoMapper branchDaoMapper;*/
public Boolean insertBranch(StudentBranch studentBranch) {
return this.baseMapper.insert(studentBranch)>0?true:false;
}
}
dao层:MasterDaoMapper
哪个包下:
这里我特意把包路径也截取了过来 对应手写数据源@MapperScan注解中的basePackages属性
package com.it.mhh.branch.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.it.mhh.entity.StudentBranch;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface BranchDaoMapper extends BaseMapper<StudentBranch> {
}
测试:
- 可以看到日期也添加进去了 我没有给日期赋值 表明上面的myBatisPlus自动填充策略
生效
- 通过@MapperScan注解扫描,可知是走的masterSqlSessionFactory此配置;
masterSqlSessionFactory配置的MySql地址和表是localhost:3306/mhh_branch
test方式测试结果:
import com.it.mhh.branch.controller.BranchController;
import com.it.mhh.entity.StudentBranch;
import com.it.mhh.utils.SnowFlake;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@SpringBootTest
@RunWith(SpringRunner.class)
public class MultipleDataSourcesApplicationTest {
@Autowired
private BranchController branchController; //分支数据源
@Autowired
private SnowFlake snowFlake; //雪花算法
@Test
public void branchInsaert(){
Boolean aBoolean = branchController.insertBranch(new StudentBranch(snowFlake.nextId(), "小黑", "山东","小蓝"));
System.out.println(aBoolean);//true
}
}