com.github.mybatis.helper.dolog.DoLogSqlInterceptor Maven / Gradle / Ivy
The newest version!
package com.github.mybatis.helper.dolog;
import com.alibaba.fastjson.JSONObject;
import com.github.mybatis.helper.core.ReflectUtil;
import com.github.mybatis.helper.core.sql.ExecuteHelper;
import com.github.mybatis.helper.core.sql.SqlInterceptor;
import com.github.mybatis.helper.dolog.annotation.DoLogSettings;
import com.github.mybatis.helper.dolog.dialect.DialectHandler;
import com.github.mybatis.helper.dolog.dialect.helper.Dialect;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.JdbcParameter;
import net.sf.jsqlparser.expression.LongValue;
import net.sf.jsqlparser.expression.StringValue;
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.delete.Delete;
import net.sf.jsqlparser.statement.insert.Insert;
import net.sf.jsqlparser.statement.select.*;
import net.sf.jsqlparser.statement.update.Update;
import org.apache.ibatis.binding.MapperMethod;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.RowBounds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* 创建或更新时自动插入日志表
* @author will
*/
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
@DoLogSettings(logTableNamePostfix="_LOG")
public class DoLogSqlInterceptor extends SqlInterceptor {
private Logger logger = LoggerFactory.getLogger(this.getClass());
private Dialect dialect;
public DoLogSqlInterceptor() {
super();
paramName="userId";
}
private static final SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Override
public String doSqlFilter(String originalSql, Object filterParam, MappedStatement mappedStatement, RowBounds rowBounds, BoundSql boundSql, ExecuteHelper executeHelper) {
try{
if(dialect==null){
dialect = DialectHandler.getDialect(super.dbType);
}
DoLogSettings activeSettings=getSetting(mappedStatement.getId());
Object parameter=boundSql.getParameterObject();
if(parameter instanceof MapperMethod.ParamMap){
throw new Exception("目前只支持单个入参!");
}
List parameterMappingList=boundSql.getParameterMappings();
Insert insert=new Insert();
List columnList=new ArrayList<>();
List expressions=new ArrayList<>();
if(activeSettings.logTypeColumn()!=null&&activeSettings.logTypeColumn().length()!=0){
columnList.add(new Column(activeSettings.logTypeColumn()));
expressions.add(new StringValue(mappedStatement.getSqlCommandType().name()));
}
if(activeSettings.logPersonColumn()!=null&&activeSettings.logPersonColumn().length()!=0){
columnList.add(new Column(activeSettings.logPersonColumn()));
if(filterParam instanceof String){
expressions.add(new StringValue(filterParam.toString()));
}else{
expressions.add(new LongValue(filterParam.toString()));
}
}
if(activeSettings.logDateColumn()!=null&&activeSettings.logDateColumn().length()!=0){
columnList.add(new Column(activeSettings.logDateColumn()));
expressions.add(dialect.buildNowExpression());
}
if(mappedStatement.getSqlCommandType()==SqlCommandType.INSERT){
//插入
Insert statement=(Insert) CCJSqlParserUtil.parse(originalSql);
String recordTableName=statement.getTable().getName();
String logTableName=generateTableName(activeSettings, recordTableName);
insert.setTable(new Table(logTableName));
if(activeSettings.logPrimaryKeyColumn()!=null&&activeSettings.logPrimaryKeyColumn().length()!=0){
columnList.add(new Column(activeSettings.logPrimaryKeyColumn()));
expressions.add(dialect.buildUUIDExpression());
}
if(activeSettings.logRecordTableNameColumn()!=null&&activeSettings.logRecordTableNameColumn().length()!=0){
columnList.add(new Column(activeSettings.logRecordTableNameColumn()));
expressions.add(new StringValue(recordTableName));
}
if(activeSettings.logRecordPrimaryKeyColumn()!=null&&activeSettings.logRecordPrimaryKeyColumn().length()!=0){
int index=0;
for(int i=0;i jsonMap=new HashMap<>();
int index=0;
for(int i=0;i jsonMap=new HashMap<>();
int index=0;
for(int i=0;i selectColumnList=new ArrayList<>();
for(int i=0;i jsonMap=executeHelper.exeQuery(new ExecuteHelper.Action() {
@Override
public Map doAction(ResultSet resultSet) throws SQLException {
Map jsonMap=new HashMap<>();
if(resultSet.next()) {
for(Column column:statement.getColumns()){
jsonMap.put(column.toString(),resultSet.getObject(column.toString()));
}
}
return jsonMap;
}
},select.toString(),false);
expressions.add(new StringValue(JSONObject.toJSONString(jsonMap)));
}
}else{
//删除
Delete statement=(Delete) CCJSqlParserUtil.parse(originalSql);
String recordTableName=statement.getTable().getName();
String logTableName=generateTableName(activeSettings,recordTableName);
insert.setTable(new Table(logTableName));
if(activeSettings.logPrimaryKeyColumn()!=null&&activeSettings.logPrimaryKeyColumn().length()!=0){
columnList.add(new Column(activeSettings.logPrimaryKeyColumn()));
expressions.add(dialect.buildUUIDExpression());
}
if(activeSettings.logRecordTableNameColumn()!=null&&activeSettings.logRecordTableNameColumn().length()!=0){
columnList.add(new Column(activeSettings.logRecordTableNameColumn()));
expressions.add(new StringValue(recordTableName));
}
Expression recordPrimaryKeyExpression=null;
if(activeSettings.logRecordPrimaryKeyColumn()!=null&&activeSettings.logRecordPrimaryKeyColumn().length()!=0){
columnList.add(new Column(activeSettings.logRecordPrimaryKeyColumn()));
if(parameter instanceof String){
recordPrimaryKeyExpression=new StringValue(parameter.toString());
expressions.add(recordPrimaryKeyExpression);
}else{
recordPrimaryKeyExpression=new LongValue(parameter.toString());
expressions.add(recordPrimaryKeyExpression);
}
}
if(activeSettings.logRecordContentColumn()!=null&&activeSettings.logRecordPrimaryKeyColumn()!=null){
columnList.add(new Column(activeSettings.logRecordContentColumn()));
PlainSelect plainSelect=new PlainSelect();
plainSelect.addSelectItems(new AllColumns());
plainSelect.setFromItem(new Table(recordTableName));
EqualsTo equalsTo=new EqualsTo();
equalsTo.setLeftExpression(new Column(activeSettings.recordPrimaryKey()));
equalsTo.setRightExpression(recordPrimaryKeyExpression);
plainSelect.setWhere(equalsTo);
Select select = new Select();
select.setSelectBody(plainSelect);
Map jsonMap=executeHelper.exeQuery(new ExecuteHelper.Action() {
@Override
public Map doAction(ResultSet resultSet) throws SQLException {
Map jsonMap=new HashMap<>();
ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
if(resultSet.next()) {
for (int i = 1; i <= resultSetMetaData.getColumnCount(); i++) {
if(resultSet.getObject(i) instanceof java.sql.Date){
jsonMap.put(resultSetMetaData.getColumnName(i),simpleDateFormat.format(new Date(((java.sql.Timestamp)resultSet.getTimestamp(i)).getTime())));
}else{
jsonMap.put(resultSetMetaData.getColumnName(i),resultSet.getObject(i));
}
}
}
return jsonMap;
}
},select.toString(),false);
expressions.add(new StringValue(JSONObject.toJSONString(jsonMap)));
}
}
insert.setColumns(columnList);
ExpressionList expressionList=new ExpressionList();
expressionList.setExpressions(expressions);
insert.setItemsList(expressionList);
executeHelper.exeUpdate(insert.toString(),false);
}catch (Exception e){
logger.error("无法生成操作日志,sql:{},原因:{}",originalSql,e);
}
return originalSql;
}
private String generateTableName(DoLogSettings settings, String recordTableName) {
if(settings.logTableName()!=null&&settings.logTableName().length()!=0){
return settings.logTableName();
}
StringBuilder tableNameBuilder=new StringBuilder();
if(settings.logTableNamePrefix()!=null&&settings.logTableNamePrefix().length()!=0){
tableNameBuilder.append(settings.logTableNamePrefix());
}
tableNameBuilder.append(recordTableName);
if(settings.logTableNamePostfix()!=null&&settings.logTableNamePostfix().length()!=0){
tableNameBuilder.append(settings.logTableNamePostfix());
}
return tableNameBuilder.toString();
}
@Override
public boolean isContainsSqlCommandType(SqlCommandType sqlCommandType) {
return sqlCommandType==SqlCommandType.DELETE||sqlCommandType==SqlCommandType.UPDATE||sqlCommandType==SqlCommandType.INSERT;
}
}