@Data
public class BaseEntity {
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
private Long createBy;
@JsonFormat( pattern = "yyyy年MM月dd日 HH时mm分ss秒")
private LocalDateTime createTime;
private Long updateBy;
@JsonFormat( pattern = "yyyy年MM月dd日 HH时mm分ss秒")
private LocalDateTime updateTime;
private Integer delFlag;
}
package org.yangmy.tide.common.core.config;
import org.apache.ibatis.binding.MapperMethod;
import org.apache.ibatis.builder.StaticSqlSource;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.springframework.stereotype.Component;
import org.yangmy.tide.common.core.utils.BaseEntity;
import org.yangmy.tide.common.security.SecurityUtils;
import java.lang.reflect.Field;
import java.time.LocalDateTime;
import java.util.*;
@Component
@Intercepts({@Signature(method = "update", type = Executor.class, args = {MappedStatement.class, Object.class})})
public class IbatisAuditDataInterceptor implements Interceptor {
private final Set<String> cache=new HashSet<>();
@Override
public Object intercept(Invocation invocation) throws Throwable {
Object[] args = invocation.getArgs();
MappedStatement ms = (MappedStatement) args[0];
Object params=args[1];
SqlSource newSqlSource=null;
if (ms.getSqlCommandType()==SqlCommandType.INSERT) {
String sql=ms.getSqlSource().getBoundSql(null).getSql();
String newSql = insertAudit(sql);
List<ParameterMapping> newParameterMappings=new ArrayList<>();
ParameterMapping createByMapping=new ParameterMapping.Builder(ms.getConfiguration(),"createBy",Object.class).build();
ParameterMapping createTimeMapping=new ParameterMapping.Builder(ms.getConfiguration(),"createTime",Object.class).build();
ParameterMapping updateByMapping=new ParameterMapping.Builder(ms.getConfiguration(),"updateBy",Object.class).build();
ParameterMapping updateTimeMapping=new ParameterMapping.Builder(ms.getConfiguration(),"updateTime",Object.class).build();
ParameterMapping delFlagMapping=new ParameterMapping.Builder(ms.getConfiguration(),"delFlag",Object.class).build();
newParameterMappings.add(createByMapping);
newParameterMappings.add(createTimeMapping);
newParameterMappings.add(updateByMapping);
newParameterMappings.add(updateTimeMapping);
newParameterMappings.add(delFlagMapping);
newParameterMappings.addAll(ms.getSqlSource().getBoundSql(null).getParameterMappings());
newSqlSource=new StaticSqlSource(ms.getConfiguration(),newSql,newParameterMappings);
if(params instanceof BaseEntity){
BaseEntity baseEntity=(BaseEntity) params;
baseEntity.setCreateBy(Long.valueOf(Objects.requireNonNull(SecurityUtils.getUserId())));
baseEntity.setCreateTime(LocalDateTime.now());
baseEntity.setUpdateBy(Long.valueOf(Objects.requireNonNull(SecurityUtils.getUserId())));
baseEntity.setUpdateTime(LocalDateTime.now());
baseEntity.setDelFlag(0);
}else if(params instanceof MapperMethod.ParamMap){
MapperMethod.ParamMap<Object> map= (MapperMethod.ParamMap) params;
map.put("createBy",SecurityUtils.getUserId());
map.put("createTime",LocalDateTime.now());
map.put("updateBy",SecurityUtils.getUserId());
map.put("updateTime",LocalDateTime.now());
map.put("delFlag",0);
}
if(!cache.contains(ms.getId())){
Field msField = invocation.getArgs()[0].getClass().getDeclaredField("sqlSource");
msField.setAccessible(true);
msField.set(invocation.getArgs()[0],newSqlSource);
cache.add(ms.getId());
}
}
if (ms.getSqlCommandType()==SqlCommandType.UPDATE) {
String source=ms.getSqlSource().getBoundSql(null).getSql();
String newSql=updateAudit(source);
List<ParameterMapping> newParameterMappings=new ArrayList<>();
ParameterMapping updateByMapping=new ParameterMapping.Builder(ms.getConfiguration(),"updateBy",Object.class).build();
ParameterMapping updateTimeMapping=new ParameterMapping.Builder(ms.getConfiguration(),"updateTime",Object.class).build();
newParameterMappings.add(updateByMapping);
newParameterMappings.add(updateTimeMapping);
newParameterMappings.addAll(ms.getSqlSource().getBoundSql(null).getParameterMappings());
newSqlSource=new StaticSqlSource(ms.getConfiguration(),newSql,newParameterMappings);
if(params instanceof BaseEntity){
BaseEntity baseEntity=(BaseEntity) params;
baseEntity.setUpdateBy(Long.valueOf(Objects.requireNonNull(SecurityUtils.getUserId())));
baseEntity.setUpdateTime(LocalDateTime.now());
}else{
MapperMethod.ParamMap<Object> map= (MapperMethod.ParamMap) params;
map.put("updateBy",SecurityUtils.getUserId());
map.put("updateTime",LocalDateTime.now());
}
if(!cache.contains(ms.getId())){
Field msField = invocation.getArgs()[0].getClass().getDeclaredField("sqlSource");
msField.setAccessible(true);
msField.set(invocation.getArgs()[0],newSqlSource);
cache.add(ms.getId());
}
}
invocation.getArgs()[1]=params;
return invocation.proceed();
}
public String insertAudit(String source){
char[] chars = source.toCharArray();
StringBuilder newSql=new StringBuilder();
boolean afterFormalParam=false;
for (char c : chars) {
String cStr=String.valueOf(c);
newSql.append(cStr);
if (cStr.equals("(")){
if(afterFormalParam){
newSql.append("?,?,?,?,?,");
}else {
newSql.append("create_by,create_time,update_by,update_time,del_flag,");
}
}
if(cStr.equals(")")){
afterFormalParam=true;
}
}
return newSql.toString();
}
public String updateAudit(String source){
String[] strArray = source.split("\\s+");
StringBuilder newSql=new StringBuilder();
boolean afterSet=false;
for (String s : strArray) {
if(afterSet){
s="update_by=?,update_time=?,"+s;
afterSet=false;
}
if(s.equals("set")||s.equals("SET")){
afterSet=true;
}
newSql.append(s).append(" ");
}
return newSql.toString();
}
}