引入

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

最新文章

  1. Tomcat去除项目名称和端口号,直接使用ip地址访问项目的方法
  2. mac终端命令大全介绍(转)
  3. ORACLE RAISE
  4. 《从零开始做一个MEAN全栈项目》(1)
  5. iOS button 里边的 字体的 摆放
  6. 学习面试题Day06
  7. PHPCMS如何实现后台访问限制?
  8. 导航栏 &amp; 状态栏覆盖
  9. linux 打补丁
  10. pygame 精灵的行走及二段跳实现方法
  11. Heroku 如何上重置 PostgreSQL 数据库
  12. Mac下Charles Contents乱码解决办法
  13. window安装mysql5.7解压版(解决乱码问题)
  14. HTML和CSS查缺补漏
  15. JAVA日常之二
  16. maven开发项目中遇到的问题
  17. 洛谷 CF55D Beautiful numbers 解题报告
  18. Netty+MUI从零打造一个仿微信的高性能聊天项目,兼容iPhone/iPad/安卓
  19. APP的案例分析
  20. jQuery中的观察者模式(Observer Pattern)

热门文章

  1. Linux从入门到放弃、零基础入门Linux(第四篇):在虚拟机vmware中安装centos7.7
  2. mysql数据库之事务和隔离级别
  3. AXIOS 的请求
  4. 使用log4Net输出调试信息
  5. Ql004(母牛的故事)
  6. Codeforces Round #135 (Div. 2) D - Choosing Capital for Treeland(两种树形DP)
  7. C语言实现Socket简单通信
  8. 趣谈Linux操作系统学习笔记:第二十七讲
  9. Spring 事物隔离级别,事物传播行为
  10. Unity开发:5.0+版本标准资源包无内置问题