All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy