最近在使用mybatis的时候发现一个问题,就是好多的时候保存实体的时候,都要set create 和update,这样很麻烦,有没有可能类似jap 使用注解自动生成。jpa 的注解原理也拦截sql ,把sql 里面的参数绑定给修改一下。
了解了原理,我们也就自己可以可以自己仿照jpa 实现一下了。
先自定义两个注解@createDate,@updateDate
项目原理,使用mybatis 的拦截器,拦截Executor,的update 方法,
里面 两个参数

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


自定义拦截器
@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) {    }}实体:

现在把
这个插件加入mybatis 的配置中。
一般情况下我们是这样配置的

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

类型转换错误,这是因为他要的是类mybatis.configuration.interceptors 不是字符串,
我们看一下mybatis 官网

我们只要声明他是一个bean会自动注入的。
我们来写一个测试类

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

打印sql
启动调用一下接口

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

再跑一下

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