引入

在实际开发中,总会避免不了操作数据库,而在数据库中每个表都会有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. Shell 编程 正则表达式

    本篇主要写一些shell脚本正则表达式的使用基础. 概述 正则表达式分为基础正则表达式(Regular Expression)与扩展正则表达式(Extended Regular Expression) ...

  2. pytorch报错:ValueError: Expected more than 1 value per channel when training, got input size torch.Size([1,512,1,1])

    1.pytorch报错:ValueError: Expected more than 1 value per channel when training, got input size torch.S ...

  3. passwd修改密码失败,报鉴定令牌操作错误

    出现这个情况,从四个方面来分析: 1./usr/bin/passwd 的权限中没有添加s即SUID特殊权限 即:-rwxr-xr-x. 1 root root 27000 8月  22 2010 /u ...

  4. 《linux就该这么学》课堂笔记16 bind域名解析

    1.DNS域名解析服务 DNS(Domain Name System,域名系统)是一项用于管理和解析域名与IP地址对应关系的技术,就是能够接受用户输入的域名或IP地址,然后自动查找与之匹配(或者说具有 ...

  5. 字符串比较==和equals的区别

    <Stack Overflow 上 370万浏览量的一个问题:如何比较 Java 的字符串?> 比较详细的比较了==和equals方法的区别. 那借此机会,我就来梳理一下 Stack Ov ...

  6. detectron2安装出现Kernel not compiled with GPU support 报错信息

    在安装使用detectron2的时候碰到Kernel not compiled with GPU support 问题,前后拖了好久都没解决,现总结一下以备以后查阅. 不想看心路历程的可以直接跳到最后 ...

  7. 201671030103 实验十四 团队项目评审&课程学习总结

    项目 内容 这个作业属于哪个课程 任课教师首页链接 这个作业的要求在哪里 作业链接地址 课程学习目标 (1)掌握软件项目评审会流程 (2)反思总结课程学习内容 任务一: 团队项目Github仓库中提交 ...

  8. 【大数据】0002---MongoDB集群自动分离创建新集群

    场景:MongoDB集群运行后,自动产生新的集群 解答:可能没有理解问题,理清思路如下 1.日志分析 2.配置文件检查(日期.版本) 3.网络IP变化 4.github 5.stack overflo ...

  9. Python并发编程之进程同步

    """ 问题:当多个进程使用同一份数据资源的时候,就会引发数据安全或顺序混乱的问题 """ ''' 进程同步 ''' #多进程抢占输出资源 ...

  10. Java String语法

    String类代表字符串. Java程序中的所有字符串文字(例如"abc" )都被实现为此类的实例. 字符串不变; 它们的值在创建后不能被更改. 字符串缓冲区支持可变字符串. 因为 ...