MyBatis Plus 学习 ~~ 插件扩展

继上一篇关于Mybatis Plus基础,这一篇介绍关于MP的插件

https://blog.csdn.net/xiaozhegaa/article/details/85040659

目录

插件扩展

热加载

逻辑删除

通用枚举扫描并自动关联注入

一、Jackson

二、Fastjson

自动填充功能

Sql 注入器

性能分析插件

乐观锁插件

多租户 SQL 解析器

MybatisX 快速开发插件


插件扩展

热加载

3.0.6版本上移除了该功能,不过最新快照版已加回来并打上废弃标识,预计3.1.0版本上完全移除

开启动态加载 mapper.xml

  • 多数据源配置多个 MybatisMapperRefresh 启动 bean
  • 默认情况下,eclipse保存会自动编译,idea需自己手动编译一次
参数说明:
      sqlSessionFactory:session工厂
      mapperLocations:mapper匹配路径
      enabled:是否开启动态加载  默认:false
      delaySeconds:项目启动延迟加载时间  单位:秒  默认:10s
      sleepSeconds:刷新时间间隔  单位:秒 默认:20s
  提供了两个构造,挑选一个配置进入spring配置文件即可:

构造1:
    
        
        
        
    

构造2:
    
        
        
        
        
        
    

逻辑删除

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 {
    ...
    @Override
    public String getValue() {
        return this.value;
    }
}

2、配置扫描通用枚举

  • 注意!! spring mvc 配置参考,安装集成 MybatisSqlSessionFactoryBean 枚举包扫描,spring boot 例子配置如下:

示例工程:

? mybatisplus-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 {

    /**
     * 

* 检查SQL是否注入(已经注入过不再注入) *

* * @param builderAssistant mapper 信息 * @param mapperClass mapper 接口的 class 对象 */ void inspectInject(MapperBuilderAssistant builderAssistant, Class mapperClass); /** *

* 注入 SqlRunner 相关 *

* * @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 mapperRegistryCache = GlobalConfigUtils.getMapperRegistryCache(builderAssistant.getConfiguration());
        if (!mapperRegistryCache.contains(className)) {
            List 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
    }

    /**
     * 

* 获取 注入的方法 *

* * @return 注入的方法集合 */ public abstract List getMethodList(); }

自定义自己的通用方法可以实现接口 ISqlInjector 也可以继承抽象类AbstractSqlInjector 注入通用方法 SQL 语句 然后继承 BaseMapper 添加自定义方法,全局配置 sqlInjector 注入 MP 会自动将类所有方法注入到 mybatis容器中。

性能分析插件

性能分析拦截器,用于输出每条 SQL 语句及其执行时间

  • 使用如下:

    ....

    
    
        
        
        
    

//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:


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 例子配置如下:

示例工程:

? mybatis-plus-sample-tenant

? mybatisplus-spring-boot

@Bean
public PaginationInterceptor paginationInterceptor() {
    PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
    paginationInterceptor.setLocalPage(true);// 开启 PageHelper 的支持
    /*
     * 【测试多租户】 SQL 解析处理拦截器
* 这里固定写成住户 1 实际情况你可以从cookie读取,因此数据看不到 【 麻花藤 】 这条记录( 注意观察 SQL )
*/ List 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 MyBatis Plus 学习 ~~ 插件扩展_第1张图片

计划支持

  • 连接数据源之后 xml 里自动提示字段
  • sql 增删改查
  • 集成 MP 代码生成
  • 其他

你可能感兴趣的:(MyBatis,Plus)