基于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 ...
随机推荐
- swagger页面详细讲解
- JavaScript正则表达式进阶指南
摘要:正则表达式是程序员的必备技能,想不想多学几招呢? 本文用JavaScript的exec方法来测试正则表达式. 例如,正则表达式**/F.*g/会匹配"以F开头,以g结尾的字符串&quo ...
- java List一次性添加多个元素
(1)使用addAll方法 ArrayListExample.java public class ArrayListExample { public static void main(String[] ...
- OEL7.6源码安装MYSQL5.7
首先官网下载安装包https://dev.mysql.com/downloads/mysql/5.7.html#downloads 然后上传解压至/usr/local目录 [root@localhos ...
- 微信小程序+php 授权登陆,完整代码
先上图 实现流程: 1.授权登陆按钮和正文信息放到了同一个页面,未授权的时候显示登陆按钮,已授权的时候隐藏登陆按钮,显示正文信息,当然也可以授权和正文分开成两个页面,在授权页面的onlo ...
- Memcache内存缓存框架
转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/10923221.html 一:Memcache是什么,为什么要用它 MemCache是一个高性能.“分布式”的 ...
- rhel7学习第五天
管道命令符的功能的确强大!
- 用 Splashtop Wired XDisplay HD 让 ipad做电脑扩展屏幕__亲测有效
参考: [1]https://blog.csdn.net/Tang_Chuanlin/article/details/86433152
- PAC、KNN和GridSearchCV
PCA PCA主要是用来数据降维,将高纬度的特征映射到低维度,具体可学习线性代数. 这里,我们使用sklearn中的PCA. from sklearn.decomposition import PCA ...
- python基础之一:input、if、while