我们在日常开发中,一般会在表里面增加创建人(create_by)、创建时间(create_time)、修改人(update_by)、修改时间(update_time)四个字段。
创建人:新增时,通过上下文获取用户信息。
创建时间:新增时,获取系统当前时间。
修改人:修改时,通过上下文获取用户信息。
修改时间:修改时,获取系统当前时间。
对于这种公共的字段,如果每次都在Sql
中进行处理,那是相当繁琐也是没必要的。如果你用的是MyBatis-Plus
那么一切就变的简单了。
继承mybatis
的Interceptor
拦截器
/**
* Description: mybatis拦截器,自动注入创建人、创建时间、修改人、修改时间
*
* @author : laughing
* DateTime: 2021-05-06 17:13
*/
@Intercepts({@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})})
@Slf4j
@SuppressWarnings("all")
public class MybatisSqlInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
String sqlId = mappedStatement.getId();
SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
Object parameter = invocation.getArgs()[1];
if (parameter == null) {
return invocation.proceed();
}
if(SysOperateLog.class.isAssignableFrom(parameter.getClass()) || SysLoginInfo.class.isAssignableFrom(parameter.getClass())){
return invocation.proceed();
}
if (SqlCommandType.INSERT == sqlCommandType) {
Field[] fields = ConvertUtils.getAllFields(parameter);
Long userId = SecurityUtils.getUserId();
for (Field field : fields) {
try {
if ("createBy".equals(field.getName())) {
field.setAccessible(true);
Object local_createBy = field.get(parameter);
field.setAccessible(false);
if (local_createBy == null || local_createBy.equals("")) {
// 登录人账号
field.setAccessible(true);
field.set(parameter, userId);
field.setAccessible(false);
}
}
// 注入创建时间
if ("createTime".equals(field.getName())) {
field.setAccessible(true);
Object local_createDate = field.get(parameter);
field.setAccessible(false);
if (local_createDate == null || local_createDate.equals("")) {
field.setAccessible(true);
field.set(parameter, new Date());
field.setAccessible(false);
}
}
} catch (Exception e) {
}
}
}
if (SqlCommandType.UPDATE == sqlCommandType) {
Long userId = SecurityUtils.getUserId();
Field[] fields = null;
if (parameter instanceof MapperMethod.ParamMap) {
MapperMethod.ParamMap<?> p = (MapperMethod.ParamMap<?>) parameter;
if (p.containsKey("et")) {
parameter = p.get("et");
} else {
parameter = p.get("param1");
}
if (parameter == null) {
return invocation.proceed();
}
fields = ConvertUtils.getAllFields(parameter);
} else {
fields = ConvertUtils.getAllFields(parameter);
}
for (Field field : fields) {
try {
if ("updateBy".equals(field.getName())) {
//获取登录用户信息
// 登录账号
field.setAccessible(true);
field.set(parameter, userId);
field.setAccessible(false);
}
if ("updateTime".equals(field.getName())) {
field.setAccessible(true);
field.set(parameter, new Date());
field.setAccessible(false);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
return invocation.proceed();
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
// TODO Auto-generated method stub
}
}
通过SqlSessionFactory
加载插件
/**
* Mybatis-Plus配置
*
* @author leeframe
*/
@Configuration
@EnableTransactionManagement
public class MyBatisPlusConfig {
@javax.annotation.Resource
private Environment env;
static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";
private final Logger logger = LoggerFactory.getLogger(MyBatisPlusConfig.class);
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 如果用了分页插件注意先 add TenantLineInnerInterceptor 再 add PaginationInnerInterceptor
// 用了分页插件必须设置 MybatisConfiguration#useDeprecatedExecutor = false
// interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(
new TenantLineHandler() {
// manager_id = 1088248166370832385
// 获取租户 ID 值表达式,只支持单个 ID 值
@Override
public Expression getTenantId() {
return new StringValue(SecurityUtils.getOrgCode());
}
// 这是 default 方法,默认返回 false 表示所有表都需要拼多租户条件,
// 这里设置 role表不需要该条件
@Override
public boolean ignoreTable(String tableName) {
return StringUtils.isEmpty(SecurityUtils.getOrgCode()) || LeeFrameConfig.getFilterTableList().stream().anyMatch(e -> e.equalsIgnoreCase(tableName));
}
@Override
public String getTenantIdColumn() {
return "org_code";
}
}));
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
@Bean
public ConfigurationCustomizer configurationCustomizer() {
return configuration -> configuration.setUseDeprecatedExecutor(false);
}
public static String setTypeAliasesPackage(String typeAliasesPackage) {
ResourcePatternResolver resolver = (ResourcePatternResolver) new PathMatchingResourcePatternResolver();
MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resolver);
List<String> allResult = new ArrayList<String>();
try {
for (String aliasesPackage : typeAliasesPackage.split(",")) {
List<String> result = new ArrayList<String>();
aliasesPackage = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
+ ClassUtils.convertClassNameToResourcePath(aliasesPackage.trim()) + "/" + DEFAULT_RESOURCE_PATTERN;
Resource[] resources = resolver.getResources(aliasesPackage);
if (resources != null && resources.length > 0) {
MetadataReader metadataReader = null;
for (Resource resource : resources) {
if (resource.isReadable()) {
metadataReader = metadataReaderFactory.getMetadataReader(resource);
try {
result.add(Class.forName(metadataReader.getClassMetadata().getClassName()).getPackage().getName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}
if (result.size() > 0) {
HashSet<String> hashResult = new HashSet<String>(result);
allResult.addAll(hashResult);
}
}
if (allResult.size() > 0) {
typeAliasesPackage = String.join(",", (String[]) allResult.toArray(new String[0]));
} else {
throw new RuntimeException("mybatis typeAliasesPackage 路径扫描错误,参数typeAliasesPackage:" + typeAliasesPackage + "未找到任何包");
}
} catch (IOException e) {
e.printStackTrace();
}
return typeAliasesPackage;
}
public Resource[] resolveMapperLocations(String[] mapperLocations) {
ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
List<Resource> resources = new ArrayList<Resource>();
if (mapperLocations != null) {
for (String mapperLocation : mapperLocations) {
try {
Resource[] mappers = resourceResolver.getResources(mapperLocation);
resources.addAll(Arrays.asList(mappers));
} catch (IOException e) {
// ignore
}
}
}
return resources.toArray(new Resource[resources.size()]);
}
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
String typeAliasesPackage = env.getProperty("mybatisPlus.typeAliasesPackage");
String mapperLocations = env.getProperty("mybatisPlus.mapperLocations");
String configLocation = env.getProperty("mybatisPlus.configLocation");
typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage);
VFS.addImplClass(SpringBootVFS.class);
final MybatisSqlSessionFactoryBean sessionFactory = new MybatisSqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ",")));
sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));
sessionFactory.setPlugins(mybatisSqlInterceptor());
return sessionFactory.getObject();
}
@Bean
public MybatisSqlInterceptor mybatisSqlInterceptor() {
MybatisSqlInterceptor mybatisSqlInterceptor = new MybatisSqlInterceptor();
Properties properties = new Properties();
mybatisSqlInterceptor.setProperties(properties);
return mybatisSqlInterceptor;
}
}
好