Spring 使用MyBatis时如何自动更新创建/修改日期等字段?

Spring 使用MyBatis时如何自动更新创建/修改日期等字段?,spring,aop,dry,mybatis,Spring,Aop,Dry,Mybatis,我正在使用MyBatis,希望在每个“已创建”、“已修改”表上实现2个字段。它们都是日期字段。有没有办法在插入或更新时自动更新这些字段?当然,我可以调整映射,但我想知道是否有一种更通用、更枯燥的方法可以做到这一点?否,mybatis没有自动执行此操作的机制,而无需编写sql映射来更新列 另一种选择是。不过,我不确定我会推荐这样做,我们只是在sql映射中对其进行编码 您可以在SQL映射中这样编码 <insert id="someInsert"> insert into

我正在使用MyBatis,希望在每个“已创建”、“已修改”表上实现2个字段。它们都是日期字段。有没有办法在插入或更新时自动更新这些字段?当然,我可以调整映射,但我想知道是否有一种更通用、更枯燥的方法可以做到这一点?

否,mybatis没有自动执行此操作的机制,而无需编写sql映射来更新列

另一种选择是。不过,我不确定我会推荐这样做,我们只是在sql映射中对其进行编码

您可以在SQL映射中这样编码

<insert id="someInsert">    
     insert into dummy_table    
     ( 
         SOME_COLUMN,
         CREATED_DT    
     )    
     values
    (
        #{someValue},
        sysdate    
     ) 
</insert>

插入到虚拟表中
( 
某个专栏,
创建
)    
价值观
(
#{someValue},
系统日期
) 
或者


更新一些表
设置某个_列=#{someValue},modified=sysdate
其中some_id=#{someId}

您可以使用mybatis拦截器
下面是我的示例(使用springboot):
在mycase中,BaseEntity是所有实体的超类,我需要在mybatis更新或插入数据库之前做一些事情。
步骤1:在BaseEntity中创建init方法以进行更新或插入

public class BaseEntity{
    private Date created;
    private Date updated;

    //getter,setter
    public void initCreateEntity() {  
        this.created = new Date()
        this.updated = new Date()
    }

    public void initUpdateEntity() {  
        this.created = new Date()
        this.updated = new Date()
    }
  }  
   baseDao.update(new BaseEntity);
步骤2:添加mybatis拦截器

import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;

    /**
     * add time interceptor for update
     */
    @Intercepts(@Signature(type = Executor.class, method = "update", args={MappedStatement.class, Object.class}))
    public class BaseEntityInterceptor implements Interceptor {
        @Override
        public Object intercept(Invocation invocation) throws Throwable {
            MappedStatement mappedStatement = (MappedStatement)invocation.getArgs()[0];
            // get sql
            SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
            // get parameter , this is the target object that you want to handle
            Object parameter = invocation.getArgs()[1];
            // make sure super class is BaseEntity 
            if (parameter instanceof BaseEntity) {
                //init 
                BaseEntity baseEntity = (BaseEntity) parameter;
                if (SqlCommandType.INSERT.equals(sqlCommandType)) {
                    baseEntity.initCreateEntity();
                } else if (SqlCommandType.UPDATE.equals(sqlCommandType)) {
                    baseEntity.initUpdateEntity();
                }
            }
    
            return invocation.proceed();
       }
    
        @Override
        public Object plugin(Object o) {
            return Plugin.wrap(o, this);
        }
    
        @Override
        public void setProperties(Properties properties) {
    
        }
      }
步骤3:添加到springboot配置中的bean上下文

@Configuration
public class MyBatisConfig {

    @Bean
    public BaseEntityInterceptor baseEntityInterceptor() {
        return new BaseEntityInterceptor();
    }
}
步骤4:Dao和Mapper.xml

//base update or insert sql incloude column created and updated
例:刀

@Mapper
   public interface BaseDao {
      int update(BaseEntity baseEntity);
   }
Mapper.xml

    <update id="update" parameterType="com.package.to.BaseEntity">
        update baseentity_table set created = #{createTime, jdbcType=TIMESTAMP}
updated = #{createTime, jdbcType=TIMESTAMP} 
    </update>

这里有更多信息:

非常有意义!谢谢你的例子。这似乎很容易做到,然后结束:)。我走错了方向。出现的另一个问题是,首选什么存储这些查询。我开始使用注释,但现在倾向于使用xml映射器。我没有什么经验,所以对此有任何想法都是值得赞赏的。再次感谢你的例子!我想知道我是否也应该使日期值成为对象的一部分?您是在实际的业务对象中嵌入数据属性,还是只是修改数据库上的记录,然后查看域/对象模型中不需要的元数据?这取决于,在我们的用例中,我们不需要在域模型中创建日期(但),所以我们只将其存储在数据库中以供参考。我想我更喜欢使用sysdate(或另一个数据库命令)获取插入和更新的时间戳。然后在查询数据时只使用模型中的日期对象。不过,我认为你提到的两种方法都不坏。
   baseDao.update(new BaseEntity);