package test;


import org.apache.ibatis.executor.statement.RoutingStatementHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.ParameterMode;
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.apache.ibatis.session.SqlSession;
import org.apache.ibatis.type.TypeHandlerRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.plugin2.main.server.ResultHandler;

import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author sjt
 * @Description 测试mybatis打印SQL日志
 * @date 2019/12/31
 **/
@Intercepts({@Signature(type = StatementHandler.class, method = "query", args = {Statement.class, ResultHandler.class})})
public class MyBatisLog implements Interceptor {

    public static final Logger log = LoggerFactory.getLogger(MyBatisLog.class);

    public Object intercept(Invocation invocation) throws Throwable {
        if(invocation.getTarget() instanceof RoutingStatementHandler){
            RoutingStatementHandler statementHandler = (RoutingStatementHandler)invocation.getTarget();
            StatementHandler delegate = (StatementHandler) ReflectHelper.getValueByFieldName(statementHandler, "delegate");
            //获取SQL
            BoundSql boundSql = delegate.getBoundSql();
            //获取参数
            Object parameterObject = boundSql.getParameterObject();
            List<Object> params = new ArrayList<Object>();
            TypeHandlerRegistry typeHandlerRegistry = (TypeHandlerRegistry) ReflectHelper.getValueByFieldName(delegate, "configuration");

            List<ParameterMapping> parameterMappingList = boundSql.getParameterMappings();
            if(parameterMappingList != null){
                for (ParameterMapping parameterMapping: parameterMappingList){
                    if(parameterMapping.getMode() != ParameterMode.OUT){
                        Object value;
                        String propertyName = parameterMapping.getProperty();
                        if(boundSql.hasAdditionalParameter(propertyName)){
                            value = boundSql.getAdditionalParameter(propertyName);
                        } else if (parameterObject == null){
                            value = null;
                        } else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())){
                            value = parameterObject;
                        } else {
                            value = null;
                        }
                        params.add(value);
                    }

                    String sql = boundSql.getSql();
                    for (Object param : params){
                        String paramStr;
                        Pattern pattern = Pattern.compile("^-?[0-9]+");
                        Matcher isNum = pattern.matcher(param+"");
                        if( !isNum.matches() ){
                            paramStr = "'"+param+"'";
                        } else {
                            paramStr = param+"";
                        }
                        sql = sql.replaceFirst("[?]", paramStr);
                    }
                    log.info("log打印："+sql);
                }
            }
        }
        return null;
    }

    public Object plugin(Object o) {
        return null;
    }

    public void setProperties(Properties properties) {

    }

}
