基于Mybatis-Plus实现自动化操作创建时间和修改时间
引入
在实际开发中,总会避免不了操作数据库,而在数据库中每个表都会有create_time和update_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>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.1.1</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.mybatis.spring.boot</groupId>-->
<!-- <artifactId>mybatis-spring-boot-starter</artifactId>-->
<!-- <version>2.0.1</version>-->
<!-- </dependency>-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
注意
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 && parameter.getClass().getDeclaredFields()[0].getName().equals("serialVersionUID");
//兼容mybatis plus
if (plus) {
Map<String, Object> updateParam = (Map<String, Object>) parameter;
Class<?> 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<String, Object> updateParam = (Map<String, Object>) 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_TIME 和UPDATE_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<Field> fieldTarget = Stream.of(target).collect(Collectors.toList());
if (source != null) {
List<Field> 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实现自动化操作创建时间和修改时间的更多相关文章
- VC++ 获取文件属性创建时间、修改时间和访问时间
转载:http://blog.sina.com.cn/s/blog_66bf8d8301014ikd.html WIN32_FIND_DATA结构 关于文件的全部属性信息,总计有以下以下9 种:文件的 ...
- 如何修改文件的 “创建时间” 和 “修改时间”(Windows Linux macOS)
请访问原文链接:https://sysin.org/blog/how-to-change-file-date,查看最新版.原创作品,转载请保留出处. 作者:gc(at)sysin.org,主页:www ...
- Oracle和SQL server查询数据库中表的创建和最后修改时间
有时候我们需要查看下数据数据库中表的创建时间和最后修改时间,可以通过以下语句实现: Oracle数据库 -- 查看当前用户下的表 SELECT * FROM USER_TABLES -- 查看数据库中 ...
- python 修改文件的创建时间、修改时间、访问时间
目录 python 修改文件创建.修改.访问时间 方案一 方案二(无法修改文件创建时间) python 修改文件创建.修改.访问时间 突如其来想知道一下 python 如何修改文件的属性(创建.修改. ...
- 【转载】在Linux下,一个文件也有三种时间,分别是:访问时间、修改时间、状态改动时间
在windows下,一个文件有:创建时间.修改时间.访问时间.而在Linux下,一个文件也有三种时间,分别是:访问时间.修改时间.状态改动时间. 两者有此不同,在Linux下没有创建时间的概念,也就是 ...
- 在Linux中,没有文件创建时间的概念。只有文件的访问时间、修改时间、状态改变时间
在Linux中,没有文件创建时间的概念.只有文件的访问时间.修改时间.状态改变时间.也就是说不能知道文件的创建时间.但如果文件创建后就没有修改过,修改时间=创建时间:如果文件创建后,状态就没有改变过, ...
- Linux下文件的三种时间标记:访问时间、修改时间、状态改动时间 (转载)
在windows下,一个文件有:创建时间.修改时间.访问时间. 而在Linux下,一个文件也有三种时间,分别是:访问时间.修改时间.状态改动时间. 两者有此不同,在Linux下没有创建时间的概念,也就 ...
- 黄聪:WordPress 多站点建站教程(四):获取子站点相关信息(站点的注册时间,修改时间,总文章数,URL等)
1.获取子站点blogs表里面的内容信息 $blog_details = get_blog_details(1); echo 'Blog '.$blog_details->blog_id.' i ...
- linux 查看系统当前时间,修改时间
linux 查看系统当前时间,修改时间1. 查看时间和日期命令 : "date"2.设置时间和日期例如:将系统日期设定成2018年6月8日的命令命令 : "date -s ...
- 基于facebook-wda的iOS自动化操作实践记录
[本文出自天外归云的博客园] 原理 对于iOS自动化操作,主要靠WebDriverAgent来完成.在Mac电脑上连接真机iPhone,运行WebDriverAgentRunner会在Mac端启动WD ...
随机推荐
- httpclient解析
1.HttpClient简介 HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性,它不仅使客户端发送Http请求变得容易,而且也方便开发人员测试接口(基于Http ...
- Java IO全面
转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/10857412.html 一:IO流梳理——字符流.字节流.输入流.输出流 见另一篇博文:https://ww ...
- Python3和HTMLTestRunner生成html测试报告
1.测试环境: Python3.5+unittest+HTMLTestRunner 2.下载HTMLTestRunner.py文件 下载地址 http://tungwaiyip.info/softwa ...
- php静态化介绍
1.动态URL地址设置成静态形式http://state.com/index.php?c=play&a=index&id=16267 ------>http://state.co ...
- 常用dos命令(1)
[ 文件夹管理 ] cd 显示当前目录名或改变当前目录. md 创建目录. rd 删除一个目录. dir 显示目录中的文件和子目录列表. tree 以图形显示驱动器或路径的文件夹结构. path 为可 ...
- 【oracle】处理锁表
查询锁表 select object_name,machine,s.sid,s.serial# from v$locked_object l,dba_objects o ,v$session swhe ...
- Native Clojure with GraalVM
转自:https://www.innoq.com/en/blog/native-clojure-and-graalvm/ GraalVM is a fascinating piece of techn ...
- Python实现电子词典
代码一览: dictionary/├── code│ ├── client.py│ ├── func.py│ ├── server.py│ └── settings.py├── dat ...
- [PHP] Layui + jquery 实现 实用的文章自定义标签
先看实现效果: html 代码如下: <!doctype html> <html> <head> <meta charset="utf-8" ...
- GCD(洛谷 2568)
题目描述 给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对. 输入格式 一个整数N 输出格式 答案 输入输出样例 输入 #1 4 输出 #1 4 说明/提示 ...