继上一篇关于Mybatis Plus基础,这一篇介绍关于MP的插件
https://blog.csdn.net/xiaozhegaa/article/details/85040659
目录
插件扩展
热加载
3.0.6
版本上移除了该功能,不过最新快照版已加回来并打上废弃标识,预计3.1.0
版本上完全移除
开启动态加载 mapper.xml
- 多数据源配置多个 MybatisMapperRefresh 启动 bean
- 默认情况下,eclipse保存会自动编译,idea需自己手动编译一次
参数说明:
sqlSessionFactory:session工厂
mapperLocations:mapper匹配路径
enabled:是否开启动态加载 默认:false
delaySeconds:项目启动延迟加载时间 单位:秒 默认:10s
sleepSeconds:刷新时间间隔 单位:秒 默认:20s
提供了两个构造,挑选一个配置进入spring配置文件即可:
构造1:
<bean class="com.baomidou.mybatisplus.spring.MybatisMapperRefresh">
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>
<constructor-arg name="mapperLocations" value="classpath*:mybatis/mappers/*/*.xml"/>
<constructor-arg name="enabled" value="true"/>
</bean>
构造2:
<bean class="com.baomidou.mybatisplus.spring.MybatisMapperRefresh">
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>
<constructor-arg name="mapperLocations" value="classpath*:mybatis/mappers/*/*.xml"/>
<constructor-arg name="delaySeconds" value="10"/>
<constructor-arg name="sleepSeconds" value="20"/>
<constructor-arg name="enabled" value="true"/>
</bean>
逻辑删除
SpringBoot 配置方式:
-
application.yml 加入配置(如果你的默认值和mp默认的一样,该配置可无):
mybatis-plus: global-config: db-config: logic-delete-value: 1 # 逻辑已删除值(默认为 1) logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
-
注册 Bean:
import com.baomidou.mybatisplus.core.injector.ISqlInjector; import com.baomidou.mybatisplus.extension.injector.LogicSqlInjector; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MyBatisPlusConfiguration { @Bean public ISqlInjector sqlInjector() { return new LogicSqlInjector(); } }
-
实体类字段上加上
@TableLogic
注解@TableLogic private Integer deleted;
通用枚举扫描并自动关联注入
解决了繁琐的配置,让 mybatis 优雅的使用枚举属性!
1、申明通用枚举属性
方式一: 使用 @EnumValue 注解枚举属性
方式二: 枚举属性,实现 IEnum 接口如下:
public enum AgeEnum implements IEnum<String> {
...
@Override
public String getValue() {
return this.value;
}
}
2、配置扫描通用枚举
- 注意!! spring mvc 配置参考,安装集成 MybatisSqlSessionFactoryBean 枚举包扫描,spring boot 例子配置如下:
示例工程:
配置文件 resources/application.yml
mybatis-plus:
# 支持统配符 * 或者 ; 分割
typeEnumsPackage: com.baomidou.springboot.entity.enums
....
3、JSON序列化处理
一、Jackson
1.在需要响应描述字段的get方法上添加@JsonValue注解即可
二、Fastjson
1.全局处理方式
FastJsonConfig config = new FastJsonConfig();
//设置WriteEnumUsingToString
config.setSerializerFeatures(SerializerFeature.WriteEnumUsingToString);
converter.setFastJsonConfig(config);
2.局部处理方式
@JSONField(serialzeFeatures= SerializerFeature.WriteEnumUsingToString)
private UserStatus status;
以上两种方式任选其一,然后在枚举中复写toString方法即可.
自动填充功能
示例工程:
? mybatis-plus-sample-auto-fill-metainfo
-
实现元对象处理器接口:com.baomidou.mybatisplus.core.handlers.MetaObjectHandler
-
注解填充字段
@TableField(.. fill = FieldFill.INSERT)
生成器策略部分也可以配置!
public class User {
// 注意!这里需要标记为填充字段
@TableField(.. fill = FieldFill.INSERT)
private String fillField;
....
}
- 自定义实现类 MyMetaObjectHandler
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(MyMetaObjectHandler.class);
@Override
public void insertFill(MetaObject metaObject) {
LOGGER.info("start insert fill ....");
this.setFieldValByName("operator", "Jerry", metaObject);//版本号3.0.6以及之前的版本
//this.setInsertFieldValByName("operator", "Jerry", metaObject);//@since 快照:3.0.7.2-SNAPSHOT, @since 正式版暂未发布3.0.7
}
@Override
public void updateFill(MetaObject metaObject) {
LOGGER.info("start update fill ....");
this.setFieldValByName("operator", "Tom", metaObject);
//this.setUpdateFieldValByName("operator", "Tom", metaObject);//@since 快照:3.0.7.2-SNAPSHOT, @since 正式版暂未发布3.0.7
}
}
注意事项:
- 字段必须声明
TableField
注解,属性fill
选择对应策略,该申明告知Mybatis-Plus
需要预留注入SQL
字段 - 填充处理器
MyMetaObjectHandler
在 Spring Boot 中需要声明@Component
注入 - 必须使用父类的setFieldValByName()或者setInsertFieldValByName/setUpdateFieldValByName方法,否则不会根据注解FieldFill.xxx来区分
public enum FieldFill {
/**
* 默认不处理
*/
DEFAULT,
/**
* 插入填充字段
*/
INSERT,
/**
* 更新填充字段
*/
UPDATE,
/**
* 插入和更新填充字段
*/
INSERT_UPDATE
}
Sql 注入器
注入器配置
全局配置 sqlInjector
用于注入 ISqlInjector
接口的子类,实现自定义方法注入。
例如逻辑删除注入器 LogicSqlInjector
- SQL 自动注入器接口
ISqlInjector
public interface ISqlInjector {
/**
* <p>
* 检查SQL是否注入(已经注入过不再注入)
* </p>
*
* @param builderAssistant mapper 信息
* @param mapperClass mapper 接口的 class 对象
*/
void inspectInject(MapperBuilderAssistant builderAssistant, Class<?> mapperClass);
/**
* <p>
* 注入 SqlRunner 相关
* </p>
*
* @param configuration 全局配置
* @see ISqlRunner
*/
void injectSqlRunner(Configuration configuration);
}
- 实现接口抽象类
AbstractSqlInjector
public abstract class AbstractSqlInjector implements ISqlInjector {
@Override
public void inspectInject(MapperBuilderAssistant builderAssistant, Class<?> mapperClass) {
String className = mapperClass.toString();
Set<String> mapperRegistryCache = GlobalConfigUtils.getMapperRegistryCache(builderAssistant.getConfiguration());
if (!mapperRegistryCache.contains(className)) {
List<AbstractMethod> methodList = this.getMethodList();
Assert.notEmpty(methodList, "No effective injection method was found.");
// 循环注入自定义方法
methodList.forEach(m -> m.inject(builderAssistant, mapperClass));
mapperRegistryCache.add(className);
/**
* 初始化 SQL 解析
*/
if (GlobalConfigUtils.getGlobalConfig(builderAssistant.getConfiguration()).isSqlParserCache()) {
SqlParserHelper.initSqlParserInfoCache(mapperClass);
}
}
}
@Override
public void injectSqlRunner(Configuration configuration) {
// to do nothing
}
/**
* <p>
* 获取 注入的方法
* </p>
*
* @return 注入的方法集合
*/
public abstract List<AbstractMethod> getMethodList();
}
自定义自己的通用方法可以实现接口 ISqlInjector
也可以继承抽象类AbstractSqlInjector
注入通用方法 SQL 语句
然后继承 BaseMapper
添加自定义方法,全局配置 sqlInjector
注入 MP 会自动将类所有方法注入到 mybatis
容器中。
性能分析插件
性能分析拦截器,用于输出每条 SQL 语句及其执行时间
- 使用如下:
<plugins>
....
<!-- SQL 执行性能分析,开发环境使用,线上不推荐。 maxTime 指的是 sql 最大执行时长 -->
<plugin interceptor="com.baomidou.mybatisplus.plugins.PerformanceInterceptor">
<property name="maxTime" value="100" />
<!--SQL是否格式化 默认false-->
<property name="format" value="true" />
</plugin>
</plugins>
//Spring boot方式
@EnableTransactionManagement
@Configuration
@MapperScan("com.baomidou.cloud.service.*.mapper*")
public class MybatisPlusConfig {
/**
* SQL执行效率插件
*/
@Bean
@Profile({"dev","test"})// 设置 dev test 环境开启
public PerformanceInterceptor performanceInterceptor() {
return new PerformanceInterceptor();
}
}
注意!参数说明
- 参数:maxTime SQL 执行最大时长,超过自动停止运行,有助于发现问题。
- 参数:format SQL SQL是否格式化,默认false。
!> 注意!该插件只用于开发环境,不建议生产环境使用。。。
乐观锁插件
主要适用场景
意图:
当要更新一条记录的时候,希望这条记录没有被别人更新
乐观锁实现方式:
- 取出记录时,获取当前version
- 更新时,带上这个version
- 执行更新时, set version = newVersion where version = oldVersion
- 如果version不对,就更新失败
乐观锁配置需要2步 记得两步
1.插件配置
spring xml:
<bean class="com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor"/>
spring boot:
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
2.注解实体字段 @Version
必须要!
@Version
private Integer version;
特别说明:
- 支持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime
- 整数类型下
newVersion = oldVersion + 1
newVersion
会回写到entity
中- 仅支持
updateById(id)
与update(entity, wrapper)
方法 - 在
update(entity, wrapper)
方法下,wrapper
不能复用!!!
示例
示例Java代码(参考test case代码)
int id = 100;
int version = 2;
User u = new User();
u.setId(id);
u.setVersion(version);
u.setXXX(xxx);
if(userService.updateById(u)){
System.out.println("Update successfully");
}else{
System.out.println("Update failed due to modified by others");
}
示例SQL原理
update tbl_user set name = 'update',version = 3 where id = 100 and version = 2
多租户 SQL 解析器
- 这里配合 分页拦截器 使用, spring boot 例子配置如下:
示例工程:
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
paginationInterceptor.setLocalPage(true);// 开启 PageHelper 的支持
/*
* 【测试多租户】 SQL 解析处理拦截器<br>
* 这里固定写成住户 1 实际情况你可以从cookie读取,因此数据看不到 【 麻花藤 】 这条记录( 注意观察 SQL )<br>
*/
List<ISqlParser> sqlParserList = new ArrayList<>();
TenantSqlParser tenantSqlParser = new TenantSqlParser();
tenantSqlParser.setTenantHandler(new TenantHandler() {
@Override
public Expression getTenantId() {
return new LongValue(1L);
}
@Override
public String getTenantIdColumn() {
return "tenant_id";
}
@Override
public boolean doTableFilter(String tableName) {
// 这里可以判断是否过滤表
/*
if ("user".equals(tableName)) {
return true;
}*/
return false;
}
});
sqlParserList.add(tenantSqlParser);
paginationInterceptor.setSqlParserList(sqlParserList);
paginationInterceptor.setSqlParserFilter(new ISqlParserFilter() {
@Override
public boolean doFilter(MetaObject metaObject) {
MappedStatement ms = PluginUtils.getMappedStatement(metaObject);
// 过滤自定义查询此时无租户信息约束【 麻花藤 】出现
if ("com.baomidou.springboot.mapper.UserMapper.selectListBySQL".equals(ms.getId())) {
return true;
}
return false;
}
});
return paginationInterceptor;
}
- 相关 SQL 解析如多租户可通过
@SqlParser(filter=true)
排除 SQL 解析,注意!!全局配置 sqlParserCache 设置为 true 才生效。
# 开启 SQL 解析缓存注解生效
mybatis-plus:
global-config:
sql-parser-cache: true
MybatisX 快速开发插件
MybatisX 是一款基于 IDEA 的快速开发插件,为效率而生。
安装方法:打开 IDEA,进入 File -> Settings -> Plugins -> Browse Repositories,输入 mybatisx
搜索并安装。
TIP
如果各位觉得好用,请为该插件打一个五分好评 哦! 源码地址:MybatisX 源码
功能
- Java 与 XML 调回跳转
- Mapper 方法自动生成 XML
计划支持
- 连接数据源之后 xml 里自动提示字段
- sql 增删改查
- 集成 MP 代码生成
- 其他