springboot工程一般都是通过入口类Application启动项目,根据对应目录下的xml、yml、注解等配置文件初始化相关的配置和实例化相关的bean放入IOC容器进行管理(约定大于配置
),还会将依赖的starter的相关bean实例化放入容器进行统一管理(自定义starter的开箱即用,无需重复进行相关配置
)。
在工作中使用微服务架构,以前DAO持久层使用的是mybatis在很多微服务模块都有独立引入mybatis的依赖,时间久了出现mybatis在不同微服务版本不一致导致的兼容性问题。现在有时间我就将DAO层相关依赖抽离并封装成一个starter给各个微服务依赖,还支持mybatis-plus的高级功能,实现了模块之间的松耦合,统一管理版本号。
提示:自定义starter基础我就不细说了,懂得都懂
采取父子工程项目结构,父工程统一管理公共的依赖和boot版本号,子工程直接使用父工程对应版本的依赖
父工程common的pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ibatis</groupId>
<artifactId>common-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>common-dao</module>
<module>common-dao-starter</module>
</modules>
<properties>
<boot-version>2.6.7</boot-version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${boot-version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
common-dao的pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>common-demo</artifactId>
<groupId>com.ibatis</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>common-dao</artifactId>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
</dependencies>
</project>
这个模块主要是配置mybatis-plus的相关配置,比如BaseEntity管理一些基础字段
package com.ibatis.common.dao.entity;
import com.baomidou.mybatisplus.annotation.*;
import java.io.Serializable;
import java.util.Date;
public abstract class BaseEntity implements Serializable {
@TableId(type = IdType.AUTO)
private Long id;
@TableField(fill = FieldFill.INSERT)
private Long operatorId;
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
@TableField(fill = FieldFill.INSERT)
@TableLogic
private int deleteFlag;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getOperatorId() {
return operatorId;
}
public void setOperatorId(Long operatorId) {
this.operatorId = operatorId;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public Integer getDeleteFlag() {
return deleteFlag;
}
public void setDeleteFlag(Integer deleteFlag) {
this.deleteFlag = deleteFlag;
}
}
字段填充处理器MybatisFillHandler
package com.ibatis.common.dao.handler;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import java.util.Date;
public class MybatisFillHandler implements MetaObjectHandler {
public void insertFill(MetaObject metaObject) {
this.strictInsertFill(metaObject , "createTime" , Date::new , Date.class);
this.strictInsertFill(metaObject , "updateTime" , Date::new , Date.class);
}
public void updateFill(MetaObject metaObject) {
this.strictInsertFill(metaObject , "updateTime" , Date::new , Date.class);
}
}
common-dao-starter的pom.xml,这里依赖common-dao的相关配置类
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>common-demo</artifactId>
<groupId>com.ibatis</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>common-dao-starter</artifactId>
<dependencies>
<dependency>
<groupId>com.ibatis</groupId>
<artifactId>common-dao</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>2.6.7</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.3.19</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.20</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.29</version>
</dependency>
</dependencies>
</project>
mybatis相关配置类MybatisConfig,这里demo使用了mybatis-plus的多租户tenant插件和属性自动填充处理器handler
package com.ibatis.common.dao.starter.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
import com.ibatis.common.dao.handler.MybatisFillHandler;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@EnableTransactionManagement(proxyTargetClass = true)
public class MybatisConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//多租户插件
interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(new TenantLineHandler() {
public Expression getTenantId() {
//测试默认1
return new LongValue(1);
}
//过滤白名单
public boolean ignoreTable(String tableName) {
//测试用户表以外租户隔离
return !"user".equals(tableName);
}
}));
//分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
@Bean
public MybatisFillHandler mybatisFillHandler(){
return new MybatisFillHandler();
}
}
spring.factories对config进行被动注册:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.ibatis.common.dao.starter.config.MybatisConfig
demo-boot的pom.xml,依赖common-dao-starter免去重复配置(开箱即用)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.7</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo-boot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo-boot</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.ibatis</groupId>
<artifactId>common-dao-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.properties配置数据源相关信息
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/liang?useSSL=FALSE&serverTimezone=UTC&allowPublicKeyRetrieval=true
spring.datasource.username=root
spring.datasource.password=
entity-User.java
package com.example.demoboot.entity;
import com.ibatis.common.dao.entity.BaseEntity;
public class User extends BaseEntity {
private Long tenantId;
private String name;
public Long getTenantId() {
return tenantId;
}
public void setTenantId(Long tenantId) {
this.tenantId = tenantId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
mapper-UserMapper.java
package com.example.demoboot.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demoboot.entity.User;
public interface UserMapper extends BaseMapper<User> {
}
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="com.example.demoboot.mapper.UserMapper">
</mapper>
UserService
package com.example.demoboot.service;
import com.example.demoboot.entity.User;
import com.example.demoboot.mapper.UserMapper;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
@RestController
@RequestMapping("/user")
public class UserServiceImpl {
@Resource
private UserMapper userMapper;
@GetMapping("get-all-user")
public List<User> getAllUser() {
return userMapper.selectList(null);
}
}
模拟数据:插入2条用户信息
使用postman接口调用测试是否正常使用
接口调用正常