前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >mybatis仿jpa 使用@createDate @updateDate

mybatis仿jpa 使用@createDate @updateDate

作者头像
分享干货的你
发布2021-04-06 16:42:08
1K0
发布2021-04-06 16:42:08
举报
文章被收录于专栏:分享干货的你

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

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

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

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

里面 两个参数

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

看一下代码

自定义拦截器

代码语言:javascript
复制
@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<ParameterMapping> 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) {

    }
}

实体:

现在把

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

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

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

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

我们看一下mybatis 官网

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

我们来写一个测试类

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

打印sql

启动调用一下接口

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

再跑一下

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-10-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 分享干货的你 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档