开发过程中,会经常执行insert、update语句。大部分数据库表结构都有类似create_time这样的时间列,用于记录创建时间。
很多朋友通常会为这个列设置一个默认值、或者通过代码setTime()去设置。这样做是没有问题的。
这里主要提供注解的方式去达到这个目的。有利于提高开发效率。
1、先添加两个自定义注解类:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 时间注解,在实体类对应字段添加注解,插入数据库时会自动添加时间
*
* @author gogym
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD })
public @interface CreateTime {
String value() default "";
}
//----------------------------这里是两个类,你可以分开创建--------------------------------
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 时间注解,在实体类对应字段添加注解,更新操作时会自动添加时间
*
* @author gogym
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD })
public @interface UpdateTime {
String value() default "";
}
2、添加mybaits时间注解拦截器,通过拦截器给带注解的实体类属性设置时间:
import java.lang.reflect.Field;
import java.util.Date;
import java.util.Properties;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
/**
* 添加时间注解拦截器,通过拦截sql,自动给带注解的属性添加时间
*
* @author gogym
*/
@Intercepts({@Signature(type = Executor.class, method = "update", args = {MappedStatement.class,
Object.class})})
public class DateTimeInterceptor implements Interceptor
{
@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();
for (Field field : declaredFields)
{
if (field.getAnnotation(CreateTime.class) != null)
{
if (SqlCommandType.INSERT.equals(sqlCommandType))
{
// insert语句插入createTime
field.setAccessible(true);
// 这里设置时间,当然时间格式可以自定。比如转成String类型
field.set(parameter, new Date());
}
}
else if (field.getAnnotation(UpdateTime.class) != null)
{
if (SqlCommandType.INSERT.equals(sqlCommandType)
|| SqlCommandType.UPDATE.equals(sqlCommandType))
{
// insert 或update语句插入updateTime
field.setAccessible(true);
field.set(parameter, new Date());
}
}
}
return invocation.proceed();
}
@Override
public Object plugin(Object target)
{
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties)
{}
}
3、配置mybatis拦截器:
你可以通过mybatis的xml文件注册:
<plugins>
<!--这里配置拦截器-->
<plugin interceptor="...DateTimeInterceptor"/>
</plugins>
当然如果你用的是spring boot,通过java类注册也可以
import java.util.Properties;
import org.apache.ibatis.session.AutoMappingBehavior;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ExecutorType;
import org.springframework.context.annotation.Bean;
import tk.mybatis.mapper.autoconfigure.ConfigurationCustomizer;
import com.rbl.common.plugin.mybatis.interceptor.DateTimeInterceptor;
@org.springframework.context.annotation.Configuration
public class MyBatisConfig {
@Bean
public ConfigurationCustomizer configurationCustomizer() {
return new ConfigurationCustomizer() {
@Override
public void customize(Configuration configuration) {
// 全局映射器启用缓存
configuration.setCacheEnabled(false);
// 查询时,关闭关联对象即时加载以提高性能
configuration.setLazyLoadingEnabled(false);
// 对于未知的SQL查询,允许返回不同的结果集以达到通用的效果
configuration.setMultipleResultSetsEnabled(true);
// 允许使用列标签代替列名
configuration.setUseColumnLabel(true);
// 给予被嵌套的resultMap以字段-属性的映射支持 FULL,PARTIAL
configuration
.setAutoMappingBehavior(AutoMappingBehavior.PARTIAL);
// 对于批量更新操作缓存SQL以提高性能 BATCH,SIMPLE
configuration.setDefaultExecutorType(ExecutorType.BATCH);
// 允许在嵌套语句上使用行边界。如果允许,设置false。
configuration.setSafeRowBoundsEnabled(false);
// 设置关联对象加载的形态,此处为按需加载字段(加载字段由SQL指 定),不会加载关联表的所有字段,以提高性能
configuration.setAggressiveLazyLoading(false);
// 数据库超过30秒仍未响应则超时
configuration.setDefaultStatementTimeout(30);
// 注册时间注解拦截器到mybatis
configuration.addInterceptor(dateTimeInterceptor());
}
};
}
/**
*这里配置拦截器
/*
@Bean
public DateTimeInterceptor dateTimeInterceptor() {
return new DateTimeInterceptor();
}
}
4、使用注解:
使用非常简单,只需要在你需要添加时间的实体类,也就是model里的对应属性添加注解即可,这样当你只需insert或update语句时,就会自动帮你添加上当前系统时间。
@CreateTime
private Date createTime;
完