引入

在实际开发中,总会避免不了操作数据库,而在数据库中每个表都会有create_timeupdate_time字段记录操作时间,我们在操作这两个时间的时候也可能会出现不一致的情况,或者说这两个字段实际上应该是系统生成的,而不是用户去手动处理,于是想着在新增和修改操作的时候能让系统自动处理这两个字段。

实战

1.导入pom文件

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
    &lt;dependency&gt;
&lt;groupId&gt;mysql&lt;/groupId&gt;
&lt;artifactId&gt;mysql-connector-java&lt;/artifactId&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;groupId&gt;com.baomidou&lt;/groupId&gt;
&lt;artifactId&gt;mybatis-plus-boot-starter&lt;/artifactId&gt;
&lt;version&gt;3.1.1&lt;/version&gt;
&lt;/dependency&gt;
&lt;!-- &lt;dependency&gt;--&gt;
&lt;!-- &lt;groupId&gt;org.mybatis.spring.boot&lt;/groupId&gt;--&gt;
&lt;!-- &lt;artifactId&gt;mybatis-spring-boot-starter&lt;/artifactId&gt;--&gt;
&lt;!-- &lt;version&gt;2.0.1&lt;/version&gt;--&gt;
&lt;!-- &lt;/dependency&gt;--&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.projectlombok&lt;/groupId&gt;
&lt;artifactId&gt;lombok&lt;/artifactId&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
&lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt;
&lt;scope&gt;test&lt;/scope&gt;
&lt;/dependency&gt;
&lt;/dependencies&gt;

注意

1.1.实现代码中是基于Mybatis-plus实现;

1.2.如果不使用Mybatis-Plus可以使用注释掉的依赖

2.实现SQL拦截器

@Intercepts(value = {@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})})
public class SqlInterceptor extends AbstractSqlParserHandler implements Interceptor {
/**
* 创建时间
*/
private static final String CREATE_TIME = "createTime";
/**
* 更新时间
*/
private static final String UPDATE_TIME = "updateTime"; @Override
public Object intercept(Invocation invocation) throws Throwable {
MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
// SQL操作命令
SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
// 获取新增或修改的对象参数
Object parameter = invocation.getArgs()[1];
// 获取对象中所有的私有成员变量(对应表字段)
Field[] declaredFields = parameter.getClass().getDeclaredFields();
if (parameter.getClass().getSuperclass() != null) {
Field[] superField = parameter.getClass().getSuperclass().getDeclaredFields();
declaredFields = ArrayUtils.addAll(declaredFields, superField);
}
// mybatis plus判断
boolean plus= parameter.getClass().getDeclaredFields().length == 1 &amp;&amp; parameter.getClass().getDeclaredFields()[0].getName().equals("serialVersionUID"); //兼容mybatis plus
if (plus) {
Map&lt;String, Object&gt; updateParam = (Map&lt;String, Object&gt;) parameter;
Class&lt;?&gt; updateParamType = updateParam.get("param1").getClass();
declaredFields = updateParamType.getDeclaredFields();
if (updateParamType.getSuperclass() != null) {
Field[] superField = updateParamType.getSuperclass().getDeclaredFields();
declaredFields = ArrayUtils.addAll(declaredFields, superField);
}
}
String fieldName = null;
for (Field field : declaredFields) {
fieldName = field.getName();
if (Objects.equals(CREATE_TIME, fieldName)) {
if (SqlCommandType.INSERT.equals(sqlCommandType)) {
field.setAccessible(true);
field.set(parameter, new Timestamp(System.currentTimeMillis()));
}
}
if (Objects.equals(UPDATE_TIME, fieldName)) {
if (SqlCommandType.INSERT.equals(sqlCommandType) || SqlCommandType.UPDATE.equals(sqlCommandType)) {
field.setAccessible(true);
//兼容mybatis plus的update
if (plus) {
Map&lt;String, Object&gt; updateParam = (Map&lt;String, Object&gt;) parameter;
field.set(updateParam.get("param1"), new Timestamp(System.currentTimeMillis()));
} else {
field.set(parameter, new Timestamp(System.currentTimeMillis()));
}
}
}
}
return invocation.proceed();
} @Override
public Object plugin(Object target) {
if (target instanceof Executor) {
return Plugin.wrap(target, this);
}
return target;
} @Override
public void setProperties(Properties properties) {
}

}

注意

2.1.这里写死了CREATE_TIMEUPDATE_TIME 也是遵循约定大于配置的原则,而不需要再写例如字段上增加上增加注解之类的方式实现,让用户使用更加简洁。

2.2.这里继承了Mybatis-Plus中AbstractSqlParserHandler 就可以不用自己重复造轮子去解析SQL,如果不是使用Mybatis-Plus则只需要直接实现Mybatis中的Interceptor 接口,自己实现SQL拦截解析即可。

3.注入自定义SQL拦截器

@Configuration
@MapperScan(value = "com.xx.mapper")
public class MybatisPlusConfig {
@Bean
public SqlInterceptor sqlInterceptor() {
return new SqlInterceptor();
}
}

注意

3.1.如果想要让自定义的SQL拦截器生效,那么这一步必须有,即注入SqlInterceptor

4.工具类

public class ArrayUtils {
/**
* 两个数组相加
* @param target
* @param source
* @return 相加后新的数组集合
*/
public static Field[] addAll(Field[] target, Field[] source) {
if (target != null) {
List&lt;Field&gt; fieldTarget = Stream.of(target).collect(Collectors.toList());
if (source != null) {
List&lt;Field&gt; fieldsSource = Stream.of(source).collect(Collectors.toList());
for (Field field : fieldsSource) {
fieldTarget.add(field);
}
}
target = fieldTarget.toArray(new Field[fieldTarget.size()]);
return target;
}
return target;
}

}

总结

1.导入pom文件,引入相关依赖;

2.继承Mybatis-Plus中AbstractSqlParserHandler 抽象类,实现Mybatis的Interceptor接口,在对象转换成SQL之前赋指定的字段值;

3.想要自定义的SQL拦截器生效,那么就需要注入自定义SQL拦截器。

原文地址:https://blog.csdn.net/caijwjava/article/details/90738471

基于Mybatis-Plus实现自动化操作创建时间和修改时间的更多相关文章

  1. VC++ 获取文件属性创建时间、修改时间和访问时间

    转载:http://blog.sina.com.cn/s/blog_66bf8d8301014ikd.html WIN32_FIND_DATA结构 关于文件的全部属性信息,总计有以下以下9 种:文件的 ...

  2. 如何修改文件的 “创建时间” 和 “修改时间”(Windows Linux macOS)

    请访问原文链接:https://sysin.org/blog/how-to-change-file-date,查看最新版.原创作品,转载请保留出处. 作者:gc(at)sysin.org,主页:www ...

  3. Oracle和SQL server查询数据库中表的创建和最后修改时间

    有时候我们需要查看下数据数据库中表的创建时间和最后修改时间,可以通过以下语句实现: Oracle数据库 -- 查看当前用户下的表 SELECT * FROM USER_TABLES -- 查看数据库中 ...

  4. python 修改文件的创建时间、修改时间、访问时间

    目录 python 修改文件创建.修改.访问时间 方案一 方案二(无法修改文件创建时间) python 修改文件创建.修改.访问时间 突如其来想知道一下 python 如何修改文件的属性(创建.修改. ...

  5. 【转载】在Linux下,一个文件也有三种时间,分别是:访问时间、修改时间、状态改动时间

    在windows下,一个文件有:创建时间.修改时间.访问时间.而在Linux下,一个文件也有三种时间,分别是:访问时间.修改时间.状态改动时间. 两者有此不同,在Linux下没有创建时间的概念,也就是 ...

  6. 在Linux中,没有文件创建时间的概念。只有文件的访问时间、修改时间、状态改变时间

    在Linux中,没有文件创建时间的概念.只有文件的访问时间.修改时间.状态改变时间.也就是说不能知道文件的创建时间.但如果文件创建后就没有修改过,修改时间=创建时间:如果文件创建后,状态就没有改变过, ...

  7. Linux下文件的三种时间标记:访问时间、修改时间、状态改动时间 (转载)

    在windows下,一个文件有:创建时间.修改时间.访问时间. 而在Linux下,一个文件也有三种时间,分别是:访问时间.修改时间.状态改动时间. 两者有此不同,在Linux下没有创建时间的概念,也就 ...

  8. 黄聪:WordPress 多站点建站教程(四):获取子站点相关信息(站点的注册时间,修改时间,总文章数,URL等)

    1.获取子站点blogs表里面的内容信息 $blog_details = get_blog_details(1); echo 'Blog '.$blog_details->blog_id.' i ...

  9. linux 查看系统当前时间,修改时间

    linux 查看系统当前时间,修改时间1. 查看时间和日期命令 : "date"2.设置时间和日期例如:将系统日期设定成2018年6月8日的命令命令 : "date -s ...

  10. 基于facebook-wda的iOS自动化操作实践记录

    [本文出自天外归云的博客园] 原理 对于iOS自动化操作,主要靠WebDriverAgent来完成.在Mac电脑上连接真机iPhone,运行WebDriverAgentRunner会在Mac端启动WD ...

随机推荐

  1. Ambari 管理hadoop、hbase、zookeeper节点

    简介: Apache Ambari是一种基于Web的工具,支持Apache Hadoop集群的供应.管理和监控.Ambari已支持大多数Hadoop组件,包括HDFS.MapReduce.Hive.P ...

  2. HDP 3.1.0 集成 Sqoop2 踩坑问题记录

    HDP 3.1.0 集成 Sqoop2 踩坑问题记录 本文原始地址:https://sitoi.cn/posts/65261.html 问题一 $ sqoop:000> start job -n ...

  3. Linux下安装Nexus-3.15私服

    1.切换到root用户 创建nexus用户:useradd nexus 设置nexus用户密码:passwd nexus 2.创建文件夹并进入该目录 linux中,软件包一般放在opt目录下,安装时, ...

  4. React源码 memo Fragment StrictMode cloneElement createFactory

    1.memo react 16.6 推出的 api ,他的用意是给 function component 也有 PureComponent 这样一个类似的功能,因为我们知道 PureComponent ...

  5. 201871010115——马北《面向对象程序设计JAVA》第二周学习总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...

  6. DCI学习链接及文章

    https://www.jianshu.com/u/c1b1137d5886 李永顺 https://www.jianshu.com/users/7386692d5489/timeline 袁英杰 小 ...

  7. iptables 自定义链

    当默认链中的规则非常多时,不方便我们管理. 想象一下,如果INPUT链中存放了200条规则,这200条规则有针对httpd服务的,有针对sshd服务的,有针对私网IP的,有针对公网IP的,假如,我们突 ...

  8. 基于web公交查询系统---站点信息管理

    界面设计: 界面设计代码获取: 搭建好框架获取信息: 核心代码: var users = [ ];//获取到的bus所有站点信息 var rowIndex = -1; $.ajax({ url: &q ...

  9. failed to execute /bin/bash: Resource temporarily unavailable的问题处理

    [admin@localhost ~]$ sudo su - scloanLast login: Tue Jun 12 14:06:31 CST 2018 on pts/3su: failed to ...

  10. caffe解析

    Caffe支持CUDA,Caffe和TensorFlow没有给出分布式的版本, 可以使用多gpu,Caffe通过直接在执行指令后面加上-gpu 0,1