1.1 introducing pom dependency
- When introducing SpringBoot and SpringCloud versions, pay special attention to their compatibility
Reference: https://spring.io/projects/spring-cloud
<!--introduce springboot Parent project dependency--> <!--Introduce dependency: It can be omitted version Tag to get some reasonable default configuration --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.2.RELEASE</version> </parent> <!--Because use eureka,yes springCloud Yes, so it is introduced springCloud Version locking--> <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 edition springBoott and springCloud The versions should correspond--> <spring-cloud.version>Hoxton.SR10</spring-cloud.version> </properties> <!--introduce Spring Cloud rely on--> <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> <!--introduce eureka-client jar Bag, this is eureka client--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!--Because you want to start this project, you need to start the class--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--use@Data reduce JavaBean get...set...method--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <!--link Spring Boot and 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> <!--Two for testing jar package--> <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 configuration
- It mainly configures multiple mysql addresses and eureka registration addresses
- For eureka configuration, refer to: EurekaService server creation EurekaClient client creation
- Here is spring datasource. Master and spring datasource. The branch path is customized to read this data source from the code
server: #Client port number port: 8080 mybatis-plus: mapper-locations: classpath*:mappings/*/*.xml #Scan mapper type-aliases-package: com.it.mhh.entity #Scan entity class global-config: banner: false db-config: id-type: ID_WORKER #Primary key type NONE: "database ID self increment", INPUT: "user INPUT ID", ID_WORKER: "globally unique ID (unique ID of digital type)", UUID: "globally unique ID UUID", AUTO: MP determines automatically; logic-not-delete-value: normal #Logical delete configuration logic-delete-value: deleted #Logical delete configuration 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: #Client registration name, the name of the Application in the registration center name: client-general-mapper eureka: client: #Because it is a client, it needs to register itself and register in Eureka server. Default: true register-with-eureka: true #Pull a service from the client. Later, you use more than one service. You may call other services in the server through the feign interface, so you need to pull the service. Default: true fetch-registry: true service-url: defaultZone: http://localhost:8761/eureka # registry address. If there is a cluster, write several, separated by commas instance: # Prefer ip addresses to host names prefer-ip-address: true #Name of test item Status in the registry instance-id: ${eureka.instance.ip-address} # ip address this is the registered address of the client. eureka will establish a pipeline through this address ip-address: 127.0.0.1 #Default 0.0.0.0.0.1 # Indicates the frequency of heartbeat sent by eureka client to the server. The renewal interval is 30 seconds by default (as long as the server does not receive it, it will not be directly eliminated, and the Status will be changed to Down first) lease-renewal-interval-in-seconds: 5 # Indicates the timeout time for eureka server to wait for the next heartbeat after receiving the client's heartbeat last time. If the next heartbeat is not received within this time, the instance will be removed lease-expiration-duration-in-seconds: 15
1.3 JavaBean objects
1.3.1 the first data source Master JavaBean object
- mybatisplus annotations are used
- @There are five in Data
- This javaBean object corresponds to a table in MySql. Specify the table name with the @ TableName annotation
- @TableField(fill = FieldFill. *) fill in this annotation is the filling policy of the fields of the specified database table
- To implement the myBatisPlus auto fill policy, you need to implement the MetaObjectHandler interface in myBatisPlus
- Here we mainly talk about the configuration of multiple data sources, not more about mybatisplus (specifically written in the later stage)
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 If the developer does not assign a value manually, the database assigns a value to the primary key by self increment. If the developer assigns a value manually, the value is stored. AUTO The default is database self increment, and developers do not need to assign values. ASSIGN_ID MP Automatic assignment, snowflake algorithm. ASSIGN_UUID The data type of the primary key must be String. UUID is automatically generated for assignment * */ @TableId(value = "id",type = IdType.ASSIGN_ID) private long masterId; /* Mapping non primary key field, value mapping field name exist Indicates whether it is a database field false. If the member variable in the entity class does not have a corresponding field in the database, exist, VO and DTO can be used select Indicates whether to query the field fill Indicates whether to automatically fill in. When saving objects into the database, MyBatis Plus automatically assigns values to some fields, create_time,update_time * */ @TableField(value = "name") private String masterName; @TableField(value = "age") private Integer masterAge; // Add fill for the first time @TableField(fill = FieldFill.INSERT) private LocalDateTime createDate; // It is populated when it is added for the first time, but it will also be populated after each update @TableField(fill = FieldFill.INSERT_UPDATE) private LocalDateTime updateDate; }
1.3.2 Branch JavaBean object of the second data source
- mybatisplus annotations are used
- This javaBean object corresponds to a table in MySql. Specify the table name with the @ TableName annotation
- @TableField(fill = FieldFill. *) fill in this annotation is the filling policy of the fields of the specified database table
- To implement the myBatisPlus auto fill policy, you need to implement the MetaObjectHandler interface in myBatisPlus
- Here we mainly talk about the configuration of multiple data sources, not more about mybatisplus (specifically written in the later stage)
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 If the developer does not assign a value manually, the database assigns a value to the primary key by self increment. If the developer assigns a value manually, the value is stored. AUTO The default is database self increment, and developers do not need to assign values. ASSIGN_ID MP Automatic assignment, snowflake algorithm. ASSIGN_UUID The data type of the primary key must be String. UUID is automatically generated for assignment * */ @TableId(value = "id",type = IdType.ASSIGN_ID) private long branchId; /* Mapping non primary key field, value mapping field name exist Indicates whether it is a database field false. If the member variable in the entity class does not have a corresponding field in the database, exist, VO and DTO can be used select Indicates whether to query the field fill Indicates whether to automatically fill in. When saving objects into the database, MyBatis Plus automatically assigns values to some fields, create_time,update_time * */ @TableField(value = "name") private String branchName; @TableField(value = "address") private String branchAddress; @TableField(value = "teacher") private String branchTeacher; // Add fill for the first time @TableField(fill = FieldFill.INSERT) private Date createTime; // It is populated when it is added for the first time, but it will also be populated after each update @TableField(fill = FieldFill.INSERT_UPDATE) private Date updateTime; }
1.4 myBatisPlus auto fill strategy
- This is mainly combined with the fill attribute in @ TableField() in JavaBean object
- @The fill attribute in TableField() is fieldfill Insert means that the value is assigned only when adding for the first time, and the insertFill method of the processing class will be filled automatically
- @The fill attribute in TableField() is fieldfill INSERT_ Update means that the value will be assigned automatically when adding or modifying. Follow the updateFill method of the self filling processing class below
- The MetaObjectHandler interface is required to implement the auto fill policy
- Setfieldvalbyname (string fieldname, object fieldval, metaobject, metaobject) three input parameters. The first is to assign a value to which attribute, fill in the attribute name, the second is to automatically fill in the value, and the third is a meta object
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; /** * Auto fill processing class * @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 data source configuration
1.5.1 Master data source configuration
- A big hole: I use mybatisplus. Mybatisplus has its own data source MybatisSqlSessionFactoryBean. Using SqlSessionFactoryBean will report Invalid bound statement not found * * error
- Hump naming: mybatisconfiguration setMapUnderscoreToCamelCase(true); Because the DataSource is written by yourself now, all yml configured data sources no longer work
- Import auto fill class: note that the user-defined auto fill class just written is imported. Because it is a handwritten DataSource, java will not import it manually. Otherwise, it will not take effect
- Configure mapper's xml format file: the location of mapper's xml format file must be configured, otherwise an error will be reported: no statement, because it is your own handwriting DataSource now, and all yml configurations are no longer functional
- @Attribute configuration in MapperScan annotation: basePackages attribute: the core I need to specify which package to scan, then all mappers under this package will go through this configuration. sqlSessionFactoryRef attribute: since we know which mappers under those packages go through those configurations, this attribute is the specified data source, and @ Bean has specified the name of the data source
- @Primary: indicates that this data source is the default data source. This annotation must be added, because if it is not added, spring will not be able to distinguish the primary data source (default data source)
- @ConfigurationProperties note: the prefix property in specifies the address, account and password of MySql configured in yml
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 // Indicates that this data source is the default data source, and this annotation must be added, because if it is not added, spring will not be able to distinguish the primary data source (the default data source) @Bean("masterDataSource") @ConfigurationProperties(prefix = "spring.datasource.master") //Read application The configuration parameters in YML are mapped into an object 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); //Hump naming //org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration(); MybatisConfiguration mybatisConfiguration = new MybatisConfiguration(); mybatisConfiguration.setMapUnderscoreToCamelCase(true); //Introduce custom to automatically populate classes GlobalConfig globalConfig=new GlobalConfig(); globalConfig.setMetaObjectHandler(myMetaObjectHandler); bean.setGlobalConfig(globalConfig); //configuration.setMapUnderscoreToCamelCase(true); bean.setConfiguration(mybatisConfiguration); // The location of the mapper's xml file must be configured, or an error will be reported: no statement (this error may also be caused by the inconsistency between the namespace and the project path in the mapper's xml) 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 data source configuration
- A big hole: I use mybatisplus. Mybatisplus has its own data source MybatisSqlSessionFactoryBean. Using SqlSessionFactoryBean will report Invalid bound statement not found * * error
- Hump naming: mybatisconfiguration setMapUnderscoreToCamelCase(true); Because the DataSource is written by yourself now, all yml configured data sources no longer work
- Import auto fill class: note that the user-defined auto fill class just written is imported. Because it is a handwritten DataSource, java will not import it manually. Otherwise, it will not take effect
- Configure mapper's xml format file: the location of mapper's xml format file must be configured, otherwise an error will be reported: no statement, because it is your own handwriting DataSource now, and all yml configurations are no longer functional
- @Attribute configuration in MapperScan annotation: basePackages attribute: the core I need to specify which package to scan, then all mappers under this package will go through this configuration. sqlSessionFactoryRef attribute: since we know which mappers under those packages go through those configurations, this attribute is the specified data source, and @ Bean has specified the name of the data source
- @Primary: indicates that this data source is the default data source. This annotation must be added, because if it is not added, spring will not be able to distinguish the primary data source (default data source)
- @ConfigurationProperties note: the prefix property in specifies the address, account and password of MySql configured in yml
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); //Hump naming //org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration(); MybatisConfiguration mybatisConfiguration = new MybatisConfiguration(); mybatisConfiguration.setMapUnderscoreToCamelCase(true); //configuration.setMapUnderscoreToCamelCase(true); //Introduce custom to automatically populate classes GlobalConfig globalConfig=new GlobalConfig(); globalConfig.setMetaObjectHandler(myMetaObjectHandler); bean.setGlobalConfig(globalConfig); bean.setConfiguration(mybatisConfiguration); // The location of the mapper's xml file must be configured, or an error will be reported: no statement (this error may also be caused by the inconsistency between the namespace and the project path in the mapper's xml) 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 algorithm tools
snowFlake.nextId(): get value, Long type
public class SnowFlake { // Starting timestamp private final static long START_STMP = 1577808000000L; //2020-01-01 // The number of bits occupied by each part is three private final static long SEQUENCE_BIT = 12; //Number of digits occupied by serial number private final static long MACHINE_BIT = 5; //Number of digits occupied by machine identification private final static long DATACENTER_BIT = 5; //Number of bits occupied by data center // Maximum value of each part 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); // Displacement of each part to the left 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; //Data center private long machineId; //Machine identification private long sequence = 0L; //serial number private long lastStmp = -1L; //Last timestamp 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; } //Generate next ID public synchronized long nextId() { long currStmp = timeGen(); if (currStmp < lastStmp) { throw new RuntimeException("Clock moved backwards. Refusing to generate id"); } if (currStmp == lastStmp) { //The if condition indicates that the current call and the last call fall in the same milliseconds, and can only be judged by the third part, and the serial number is added from the same time, so +1. sequence = (sequence + 1) & MAX_SEQUENCE; //The number of sequences in the same millisecond has reached the maximum. You can only wait for the next millisecond if (sequence == 0L) { currStmp = getNextMill(); } } else { //Within different milliseconds, the serial number is set to 0 //The premise of executing this branch is currtimestamp > lasttimestamp, which means that compared with the last call, this call is no longer within the same millisecond, and the serial number can be reset to 0 at this time. sequence = 0L; } lastStmp = currStmp; //It is spliced with relative milliseconds, machine ID and self incrementing sequence number return (currStmp - START_STMP) << TIMESTMP_LEFT //Timestamp part | datacenterId << DATACENTER_LEFT //Data center part | machineId << MACHINE_LEFT //Machine identification part | sequence; //Serial number part } private long getNextMill() { long mill = timeGen(); while (mill <= lastStmp) { mill = timeGen(); } return mill; } private long timeGen() { return System.currentTimeMillis(); } }
1.7 xml configuration
Note that it must correspond to the xml file location of the mapper of the handwritten data source
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 startup class configuration
- The snowflake algorithm tool class is introduced into ioc
- Two values of the snowflake algorithm input parameter: machine Id, as long as it does not duplicate other machine IDS (range: 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 data source test
1.9.1 Master data source test
Controller layer: 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 layer: MasterServiceImpl
Mybatis plus's general Service: the implementation class inherits serviceimpl < < Mapper interface of operating entity, specific entity class >, and finally adds the annotation @ Service to take this class as a Bean under the Spring container.
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 layer: MasterDaoMapper
- Under which package: Here I intercepted the package path, corresponding to the basePackages attribute in the @ MapperScan annotation of the handwritten data source
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> { }
Test:
- You can see that the date is also added. I didn't assign a value to the date, indicating that the above myBatisPlus automatic filling policy takes effect
- Through @ MapperScan annotation scanning, it can be seen that the configuration of masterSqlSessionFactory is followed; The MySql address and table configured by masterSqlSessionFactory are localhost:3306/mhh_master
- Test mode test results:
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; //Master data source @Autowired private SnowFlake snowFlake; //Snowflake algorithm @Test public void masterInsert() { Boolean aBoolean = masterController.insertMaster(new StudentMaster(snowFlake.nextId(), "Xiaobai", 12)); System.out.println(aBoolean); } }
1.9.2 Branch data source test
Controller layer: 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 layer: MasterServiceImpl
Mybatis plus's general Service: the implementation class inherits serviceimpl < < Mapper interface of operating entity, specific entity class >, and finally adds the annotation @ Service to take this class as a Bean under the Spring container.
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 layer: MasterDaoMapper
- Under which package: Here I intercepted the package path, corresponding to the basePackages attribute in the @ MapperScan annotation of the handwritten data source
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> { }
Test:
- You can see that the date is also added. I didn't assign a value to the date, indicating that the above myBatisPlus automatic filling policy takes effect
- Through @ MapperScan annotation scanning, it can be seen that the configuration of masterSqlSessionFactory is followed; The MySql address and table configured by masterSqlSessionFactory are localhost:3306/mhh_branch
- Test mode test results:
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; //Branch data source @Autowired private SnowFlake snowFlake; //Snowflake algorithm @Test public void branchInsaert(){ Boolean aBoolean = branchController.insertBranch(new StudentBranch(snowFlake.nextId(), "Xiao Hei", "Shandong","Blue ")); System.out.println(aBoolean);//true } }