本节将针对上节总增加的immortal-maqiao-core-mybatis 模块进行封装,最终封装成starter组件。
二:详细过程:由于网上对springboot原理已经有很详细的源码级别的解析,这里不进行描述,只描述经过哪些步骤可以实现对immortal-maqiao-core-mybatis的starter封装。
1>创建模块immortal-maqiao-core-starter-db,创建完成后如下图:
2>对应的POM文件,其中版本在之前的文章中创建的immortal-maqiao-depencies模块管理,模块对应pom文件如下:
immortal-maqiao-core-starter-db POM文件:
immortal-maqiao-core immortal-maqiao 1.0-SNAPSHOT 4.0.0 immortal-maqiao-core-starter-dbimmortal.maqiao immortal-maqiao-core-commoncom.baomidou mybatis-plus-boot-startercom.baomidou mybatis-plus-extensioncom.alibaba druid-spring-boot-startermysql mysql-connector-javaimmortal-maqiao immortal-maqiao-core-mybatisjakarta.servlet jakarta.servlet-api
immortal-maqiao-depencies中需要增加的自身包:
至此模块项目创建集成完成。
3>具体编码:
在immortal-maqiao-core-mybatis 这个模块中只是对mybatis进行了一些封装,但是并没有配置数据库连接,连接池等内容,因此这些配置要在本模块中实现,数据库选用mysql , 连接池中间件选用druid。
增加一个DruidConfiguration配置类,配置druid,如下:
package immortal.maqiao.core.db;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import immortal.maqiao.factory.YamlPropertySourceFactory;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Configuration
@PropertySource(factory = YamlPropertySourceFactory.class, value = "classpath:immortal-maqiao-druid.yml")
public class DruidConfiguration {
@Bean
public ServletRegistrationBean DruidStatViewServle() {
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
//添加初始化参数:initParams
//白名单:
servletRegistrationBean.addInitParameter("allow", "127.0.0.1");
//IP黑名单 (存在共同时,deny优先于allow) : 如果满足deny的话提示:Sorry, you are not permitted to view this page.
servletRegistrationBean.addInitParameter("deny", "192.168.0.114");
//登录查看信息的账号密码.
servletRegistrationBean.addInitParameter("loginUsername", "admin");
servletRegistrationBean.addInitParameter("loginPassword", "mqimmortal");
//是否能够重置数据.
servletRegistrationBean.addInitParameter("resetEnable", "false");
return servletRegistrationBean;
}
@Bean
public FilterRegistrationBean druidStatFilter() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
//添加过滤规则.
filterRegistrationBean.addUrlPatterns("/*");
//添加不需要忽略的格式信息.
filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
return filterRegistrationBean;
}
}
其中@PropertySource(factory = YamlPropertySourceFactory.class, value = "classpath:mq-immortal-druid.yml") 注解YamlPropertySourceFactory类为immortal-maqiao-core-common中提供的yaml文件解析工具,value为druid配置文件的路径,位于该模块src/main/resources目录下,内容如下:
spring:
datasource:
druid:
enable: true
# druid begin
username: ${mq.immortal.db.username}
password: ${mq.immortal.db.password}
driver-class-name: ${spring.datasource.driver-class-name}
url: ${mq.immortal.db.url}
db-type: mysql
initialSize: 10
minIdle: 10
maxActive: 500
max-wait: 60000
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
validation-query: SELECT 'x'
test-on-borrow: false
test-on-return: false
test-while-idle: true
time-between-eviction-runs-millis: 60000 #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
min-evictable-idle-time-millis: 300000 #配置一个连接在池中最小生存的时间,单位是毫秒
filters: stat,wall
filter:
wall:
enabled: true
config:
commentAllow: true
multiStatementAllow: true
nonebaseStatementAllow: true
# druid end
# StatViewServlet配置
web-stat-filter:
enabled: true
url-pattern: /*
exclusions: "*.js , *.gif ,*.jpg ,*.png ,*.css ,*.ico , /druid/*"
session-stat-max-count: 1000
profile-enable: true
session-stat-enable: false
# 配置DruidStatViewServlet
stat-view-servlet:
# 新版需要配置这个属性才能访问监控页面
enabled: true
url-pattern: /druid/*
# 禁用HTML页面上的“Reset All”功能
reset-enable: true
# 登录名
login-username: admin
# 登录密码
login-password: mqImmortal
# IP白名单(没有配置或者为空,则允许所有访问)
allow: 127.0.0.1
# IP黑名单 (存在共同时,deny优先于allow)
deny: 192.168.0.1
配置文件中
${mq.immortal.db.username}
${mq.immortal.db.password}
${spring.datasource.driver-class-name}
${mq.immortal.db.url}
为数据库连接信息,可根据格式在配置中心nacos中进行配置即可,这样就完成了数据库连接的配置。但是目前启动时并不会自动加载配置文件,需要进行第二步配置starter.
在该模块src/main/resources路径下新建meta-INF文件夹,同时在文件夹下创建spring.factories文件,文件内容为:
org.springframework.boot.autoconfigure.EnableAutoConfiguration= immortal.maqiao.core.db.config.MybatisPlusConfiguration
这样在引入该starter模块后就会加载druid配置类,同时根据自定义数据库配置信息创建数据库连接信息,至此完成了对数据库连接池的配置集成。
增加一个MybatisPlusConfiguration配置类,配置MybatisPlus的内容,包括immortal-maqiao-core-mybatis模块中的自定义方法sql注入,sql日志是否启用,自动填充时间戳等。
增加一个MybatisPlusConfiguration配置类,对mp进行配置:
package immortal.maqiao.core.db;
import immortal.maqiao.core.mybatis.props.ImmortalMyBatisProps;
import immortal.maqiao.factory.YamlPropertySourceFactory;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Order(Ordered.HIGHEST_PRECEDENCE)
@Configuration
@EnableTransactionManagement
@EnableConfigurationProperties(ImmortalMyBatisProps.class)
@PropertySource(factory = YamlPropertySourceFactory.class, value = "classpath:immortal-maqiao-db.yml")
@MapperScan("immortal.maqiao.**.mapper.**")
public class MybatisPlusConfiguration {
}
其中MqImmortalBybatisProps为上一节immortal-maqiao-core-mybatis模块中的类,该类中包含
@ConfigurationProperties("mq.immortal.mybatis") 可根据该配置格式在配置中心配置相关内容。
immortal-maqiao-db.yml为mp的配置文件,内容如下:
#mybatis-plus配置
mybatis-plus:
mapper-locations: classpath*:immortal/maqiao/prod/mapper/*.xml
#实体扫描,多个package用逗号或者分号分隔
typeAliasesPackage: immortal.maqiao.prod.**.entity
global-config:
# 关闭MP3.0自带的banner
banner: false
db-config:
#主键类型 0:"数据库ID自增", 1:"不操作", 2:"用户输入ID",3:"数字型snowflake", 4:"全局唯一ID UUID", 5:"字符串型snowflake";
id-type: 0
#字段策略
insert-strategy: not_null
update-strategy: not_null
select-strategy: not_empty
#驼峰下划线转换
table-underline: true
# 逻辑删除配置
# 逻辑删除全局值(1表示已删除,这也是Mybatis Plus的默认配置)
logic-delete-value: 1
# 逻辑未删除全局值(0表示未删除,这也是Mybatis Plus的默认配置)
logic-not-delete-value: 0
configuration:
map-underscore-to-camel-case: true
cache-enabled: false
由于在immortal-maqiao-core-mybatis模块中增加了自定义的日志输出,需要关闭mp原有的日志输出,同时注入新的日志输出,需要对MybatisPlusConfiguration增加如下内容:
//sql注入
@Bean
public ISqlInjector sqlInjector() {
return new MqImmortalSqlInjector();
}
//sql日志
@Bean
@ConditionalOnProperty(value = "mybatis-plus.sql-log.enable", matchIfMissing = true)
public SqlLogInterceptor sqlLogInterceptor() {
return new SqlLogInterceptor();
}
其中sql日志需要根据配置确定是否开启。
@Bean
public ConfigurationCustomizer configurationCustomizer() {
return configuration -> {
configuration.setDefaultEnumTypeHandler(EnumTypeHandler.class);
// 关闭 mybatis 默认的日志
configuration.setLogPrefix("log.mybatis");
};
}
关闭原有默认日志。
自动填充时间戳:
@Bean
@ConditionalOnMissingBean(MqImmortalObjectHandler.class)
public MqImmortalObjectHandler mqImmortalObjectHandler() {
return new MqImmortalObjectHandler();
}
增加MP 乐观锁和分页插件同时限制单页最多2000条
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); // 乐观锁插件
// DbType:数据库类型(根据类型获取应使用的分页方言)
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 分页插件
return interceptor;
}
metaObjectHandler接口是mybatisPlus为我们提供的的一个扩展接口,我们可以利用这个接口在我们插入或者更新数据的时候,为一些字段指定默认值。
通过该接口实现自动时间戳:
@Component
public class ImmortalObjectHandler implements metaObjectHandler {
@Override
public void insertFill(metaObject metaObject) {
this.strictInsertFill(metaObject,"createTime", LocalDateTime.class, LocalDateTime.now());
}
@Override
public void updateFill(metaObject metaObject) {
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
}
}
MybatisPlusConfiguration完整内容如下:
@Order(Ordered.HIGHEST_PRECEDENCE)
@Configuration
@EnableTransactionManagement
@EnableConfigurationProperties(ImmortalMyBatisProps.class)
@PropertySource(factory = YamlPropertySourceFactory.class, value = "classpath:immortal-maqiao-db.yml")
@MapperScan("immortal.maqiao.**.mapper.**")
public class MybatisPlusConfiguration {
//单页分页条数限制为2000条
private static final Long MAX_LIMIT = 2000L;
//sql注入
@Bean
public ISqlInjector sqlInjector() {
return new ImmortalMqSqlInjector();
}
//sql日志
@Bean
@ConditionalOnProperty(value = "mybatis-plus.sql-log.enable", matchIfMissing = true)
public SqlLogInterceptor sqlLogInterceptor() {
return new SqlLogInterceptor();
}
@Bean
public ConfigurationCustomizer configurationCustomizer() {
return configuration -> {
configuration.setDefaultEnumTypeHandler(EnumTypeHandler.class);
// 关闭 mybatis 默认的日志
configuration.setLogPrefix("log.mybatis");
};
}
//注册乐观锁和分页插件
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); // 乐观锁插件
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
paginationInnerInterceptor.setMaxLimit(MAX_LIMIT);
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 分页插件
return interceptor;
}
@Bean
@ConditionalOnMissingBean(ImmortalObjectHandler.class)
public ImmortalObjectHandler immortalObjectHandler() {
return new ImmortalObjectHandler();
}
}
最后吧MybatisPlusConfiguration配置到spring.factories中即可。
spring.factories完整内容为:
org.springframework.boot.autoconfigure.EnableAutoConfiguration= immortal.maqiao.core.db.config.MybatisPlusConfiguration, immortal.maqiao.core.db.config.DruidConfiguration
至此该模块集成完成,同时可以在改模块中增加 baseEntity baseSearch PageUtil 等数据库业务操作类方便使用。
4>测试
新建一个独立的 springboot 工程 引入该starter 对进行测试(后期所有的starter都可以用该项目进行测试),如下:
application.yml
实体类:
@Data
@TableName("test_table")
@EqualsAndHashCode(callSuper = true)
public class Test extends baseEntity {
private static final long serialVersionUID = 4774426299064291274L;
private String name;
}
mapper:
package immortal.maqiao.mapper; import com.baomidou.mybatisplus.core.mapper.baseMapper; import immortal.maqiao.entity.Test; public interface TestMapper extends baseMapper{ }
xml
id, create_by, update_by, create_time, update_time
service:
package immortal.maqiao.service; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import immortal.maqiao.entity.Test; import immortal.maqiao.mapper.TestMapper; import org.springframework.stereotype.Service; import java.util.List; @Service public class TestService extends ServiceImpl{ public List findAll(){ return this.baseMapper.selectList(null); } }
test:
package dbmodule;
import immortal.Application;
import immortal.maqiao.service.TestService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
@SpringBootTest(classes={Application.class})
public class DBTest {
@Autowired
private TestService testService;
@Test
public void selectTest(){
testService.findAll();
immortal.maqiao.entity.Test bo = new immortal.maqiao.entity.Test();
bo.setName("11");
bo.setCreateBy("1");
bo.setUpdateBy("11");
testService.insertInt(bo);
testService.deleteById(bo);
}
}
执行TEST后会看到配置打印的日志如下:
至此DB模块完成。



