开发者

MyBatis-Plus实现自动填充功能的示例代码

目录
  • 01 引言
  • 02 自动填充实现
    • 2.1 MyBATis-Plus 简单搭建
    • 2.2 标记自动填充的字段
    • 2.3 实现MetaObjectHandler
    • 2.4 测试
    • 2.5 思考
  • 03 实现原理
    • 3.1 MybatisParameterHandler
    • 3.2 实例化
  • 04 小结

    01 引言

    在数据库设计中,常常有一些字段每次都需要赋值,如创建时间、更新时间、操作人、删除标识等。很多时候,为了赶项目匆匆的赋值了一些业务字段,而漏掉了这些字段,导致查询问题的时候,时间点或者操作人对不上,加大了定位问题的难度。

    有没有框架级的技术,全局处理这样的统一字段呢?当然有。

    Mybatis-Plus自动填充技术帮我们解决问题。

    02 自动填充实现

    使用Mybtis-Plus之前,我们需要简单的搭建环境。

    2.1 Mybatis-Plus 简单搭建

    Maven

    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>${mybatis-plus.version}</version>
    </dependency>
    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
        <scope>runtime</scope>
    </dependency>
    

    配置

    # 数据源
    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test
    spring.datasource.username=root
    spring.datasource.password=root
    
    # 日志实现
    mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdo编程客栈ut.StdOutImpl
    # 开启驼峰匹配
    mybatis-plus.configuration.map-underscore-to-camel-case=true
    # 配置全局数据库主键
    mybatis-plus.global-config.db-config.id-type=auto
    

    启动类增加Mapper扫描

    @MapperScan("com.simonking.boot.mybaits.mapper")

    实体

    @Data
    @TableName("user_info")
    public class UserInfo {
        
        /**
         * 主键ID
         **/
        @TableId
        private Integer id;
    
        /**
         * 姓名
         **/
        private String name;
    
        /**
         * 年龄
         **/
        private Integer age;
    
    
        /**
         * 性别
         **/
        private String sex;
    
        /**
         * 工作
         **/
        private String job;
    
        /**
         * 生日
         **/
        private LocalDateTime birthday;
    
        /**
         * 创建时间
         **/
        pripythonvate LocalDateTime createdTime;
    
        /**
         * 更新时间
         **/
        private LocalDateTime updateTime;
    }
    

    继承BaseMapper

    public interface UserInfoMapper extends BaseMapper<UserInfo> {
    
    }
    

    到这里,Mybatis-Plus就搭建好了,可以注解注入xxxMapper调用方法了。

    2.2 标记自动填充的字段

    在实体类中,你需要使用 @TableField 注解来标记哪些字段需要自动填充,并指定填充的策略。

    @Data
    @TableName("user_info")
    public class UserInfo {
        
        // 其他字段...
    
        /**
         * 创建时间
         **/
        @TableField(fill = FieldFill.INSERT)
        private LocalDateTime createdTime;
    
        /**
         * 更新时间
         **/
        @TableField(fill = FieldFill.INSERT_UPDATE)
        private LocalDateTime updateTime;
    }
    

    FieldFill填充的枚举:

    public enum FieldFill {
        DEFAULT,       // 默XFMzH认不处理
        INSERT,        // 插入填充字段
        UPDATE,        // 更新填充字段
        INSERT_UPDATE  // 插入和更新填充字段
    }
    

    2.3 实现MetaObjectHandler

    创建一个类来实现 MetaObjectHandler 接口,并重写 insertFillupdateFill 方法。并确保实现类被Spring管理,http://www.devze.com可以通过 @Component@Bean 注解来实现。

    @Slf4j
    @Component
    public class AutoFillMetaObjectHandler implements MetaObjectHandler {
        @Override
        public void insertFill(MetaObject metaObject) {
            log.info("insertFill 开始自动填充......");
            this.strictInsertFill(metaObject, "createdTime", LocalDateTime.class, LocalDateTime.now());
            this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
        }
    
        @Override
        public void updateFill(MetaObject metaObject) {
            log.info("updateFill 开始自动填充......");
            this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
        }
    }
    

    2.4 测试

     @Test
    void contextLoads01() {
        UserInfo userInfo = new UserInfo();
        userInfo.setName("test");
        userInfo.setAge(18);
        userInfoMapper.insert(userInfo);
    }
    

    MyBatis-Plus实现自动填充功能的示例代码

    从运行结果来看,cteated_timeupdate_time已经被赋值了。

    2.5 思考

    这种全局的自动填充有什么问题呢?

    先看截图:

    MyBatis-Plus实现自动填充功能的示例代码

    这里填充的时候,需要指定字段的名称。但是如果因为开发人员定义错字段,如update_time -> updated_time等,这里就需要穷举所有的字段。

    有人可能说是开发规范的问题,的确是。但是这种问题确实有点别扭。

    能不能通过注解字段指定别名,统一自动赋值的字段呢?官方暂时不支持这种方式。

    03 实现原理

    自动赋值的的触发机制是如何实现的呢?第一反应,应该是使用了Mybatis的拦截器插件,细看了之后,并不是。我们一起来看看。

    Mybatis-Plus自动填充调用MetaObjectHandler,涉及了两个的类:

    • com.baomidou.mybatisplus.core.MybatisParameterHandler

    3.1 MybatisParameterHandler

    com.baomidou.mybatisplus.core.MybatisParameterHandler是对Mybaits原生的org.apache.ibatis.scripting.defaults.DefaultParameterHandler的增强。DefaultParameterHandlerMybatis处理SQL参数的核心类,负责:

    • Java 对象转换为 JDBC 参数
    • 设置 PreparedStatement 的参数值
    • 处理类型转换器(TypeHandler

    MybatisParameterHandler自然也就具备了这些功能。构造函数的功能:

    MyBatis-Plus实现自动填充功能的示例代码

    MyBatis-Plus实现自动填充功能的示例代码

    MyBatis-Plus实现自动填充功能的示例代码

    www.devze.com

    我们从源码中可以看到,在创建MybatisParameterHandler对象的时候,就会根据sqlCommandType执行insertFill()还是updateFill()

    3.2 实例化

    我们来看看org.apache.ibatis.executor.parameter.ParameterHandler是怎么实例化的:

    MyBatis-Plus实现自动填充功能的示例代码

    MyBatis-Plus实现自动填充功能的示例代码

    MyBatis-Plus实现自动填充功能的示例代码

    04 小结

    上面就是Mybatis-Plus自动填充的实现和源码分析,下一期,我们将自己通过拦截器或者注解的方式,实现属于我们自己的自动填充的功能。

    到此这篇关于MyBatis-Plus实现自动填充功能的示例代码的文章就介绍到这了,更多相关MyBatis-Plus自动填充内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜