最近在使用mybatis的时候发现一个问题,就是好多的时候保存实体的时候,都要set create 和update,这样很麻烦,有没有可能类似jap 使用注解自动生成。jpa 的注解原理也拦截sql ,把sql 里面的参数绑定给修改一下。 

了解了原理,我们也就自己可以可以自己仿照jpa 实现一下了。

先自定义两个注解@createDate,@updateDate

项目原理,使用mybatis 的拦截器,拦截Executor,的update 方法,

里面 两个参数

7c7bc05fad08b55e3bda76e2f4de76e4.png

根据MappedStatement 获取sql 的注解枚举类型, Object 是入参, 在根据入参 object 获取属性列表,看属性上面是否存在 自定义的注解,不同的注解使用场合不同,在用反射给filed set值。 

看一下代码

6efcb1981fc46efd903700f283c87b51.png

d299b573abbf339a2d97e7859a907de8.png

自定义拦截器

@Intercepts({        @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}),})public class DatePlugin implements Interceptor {    @Override    public Object intercept(Invocation invocation) throws Exception {        MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];        // 获取 SQL 命令        SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();        // 获取参数        Object parameter = invocation.getArgs()[1];        List parameterMappings = mappedStatement.getParameterMap().getParameterMappings();        // 获取私有成员变量        Field[] declaredFields = parameter.getClass().getDeclaredFields();        // 插入要修改两个值        for (Field field : declaredFields) {            if (SqlCommandType.INSERT.equals(sqlCommandType)) {                if (!ObjectUtils.isEmpty(field.getAnnotation(CreateDate.class))) {                    field.setAccessible(true);                    field.set(parameter, new Timestamp(System.currentTimeMillis()));                }               if (!ObjectUtils.isEmpty(field.getAnnotation(UpdateDate.class))) {                    field.setAccessible(true);                    field.set(parameter, new Timestamp(System.currentTimeMillis()));                }            }            // update 只要修改一个值            if (SqlCommandType.UPDATE.equals(sqlCommandType)) {                if (!ObjectUtils.isEmpty(field.getAnnotation(UpdateDate.class))) {                    field.setAccessible(true);                    field.set(parameter,  new Timestamp(System.currentTimeMillis()));                }            }        }        return invocation.proceed();    }    @Override    public Object plugin(Object target) {        return Plugin.wrap(target, this);    }    @Override    public void setProperties(Properties properties) {    }}

实体:

324400568ea829a6707f552fe8bc8a46.png

现在把 

这个插件加入mybatis 的配置中。

一般情况下我们是这样配置的

ac1679986709cadeca9ed66817c86516.png

但是这样是有问题的,我们启动看一下

ecc14a00f59c546f8c6b8cfa6192fac3.png

类型转换错误,这是因为他要的是类mybatis.configuration.interceptors 不是字符串, 

我们看一下mybatis 官网

e69a02d1770c9afb6abb911b8a0aa97b.png

我们只要声明他是一个bean会自动注入的。

我们来写一个测试类

efaa882d912a210e6ee2736519bef685.png

启动项目运行一下,别忘记了

9aa238e6a30adf074dc93202e239a127.png

打印sql 

启动调用一下接口 

4184d38f28124dccf7a66499c6afd3b2.png

creatdate 和updatedate 没有值, 在把实体的注解加上

75f49f8414fc7c1150692e228f85cf27.png

再跑一下

2034f79c51fb1cd975cf7bd05f0856c9.png

成功了,喜欢,点赞,转发。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐