mybatis获取运行时最终执行SQL

废话很少说上代码,个人版本是mybatis-3.2.8java

package com.jujin.util;

import java.util.List;
import java.util.Map;

import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.ParameterMode;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.apache.ibatis.reflection.property.PropertyTokenizer;
import org.apache.ibatis.scripting.xmltags.ForEachSqlNode;
import org.apache.ibatis.session.SqlSessionFactory;

public class MyBatisSqlUtils {
    /** * 运行期获取MyBatis执行的SQL及参数 * @param id Mapper xml 文件里的select Id * @param parameterMap 参数 * @param sqlSessionFactory * @return */
    public static MyBatisSql getMyBatisSql(String id, Map<String,Object> parameterMap,SqlSessionFactory sqlSessionFactory) {  
        MyBatisSql ibatisSql = new MyBatisSql(); 
        MappedStatement ms = sqlSessionFactory.getConfiguration().getMappedStatement(id); 
        BoundSql boundSql = ms.getBoundSql(parameterMap); 
        ibatisSql.setSql(boundSql.getSql()); 
        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings(); 
        if (parameterMappings != null)
        {  
            Object[] parameterArray = new Object[parameterMappings.size()];
            ParameterMapping parameterMapping = null;
            Object value = null; 
            Object parameterObject = null;
            MetaObject metaObject = null;
            PropertyTokenizer prop = null;
            String propertyName = null;
            String[] names = null;
            for (int i = 0; i < parameterMappings.size(); i++) 
            {  
              parameterMapping = parameterMappings.get(i); 
              if (parameterMapping.getMode() != ParameterMode.OUT) 
              {  
                propertyName = parameterMapping.getProperty(); 
                names = propertyName.split("\\.");
                if(propertyName.indexOf(".") != -1 && names.length == 2)
                {
                    parameterObject = parameterMap.get(names[0]);
                    propertyName = names[1];
                }
                else if(propertyName.indexOf(".") != -1 && names.length == 3)
                {
                    parameterObject = parameterMap.get(names[0]); // map
                    if(parameterObject instanceof Map)
                    {
                        parameterObject = ((Map)parameterObject).get(names[1]);
                    }
                    propertyName = names[2];
                }
                else
                {
                    parameterObject = parameterMap.get(propertyName);
                }
                metaObject = parameterMap == null ? null : MetaObject.forObject(parameterObject, SystemMetaObject.DEFAULT_OBJECT_FACTORY, SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY); 
                prop = new PropertyTokenizer(propertyName); 
                if (parameterObject == null) 
                {  
                  value = null; 
                } 
                else if (ms.getConfiguration().getTypeHandlerRegistry().hasTypeHandler(parameterObject.getClass())) 
                {  
                  value = parameterObject; 
                } 
                else if (boundSql.hasAdditionalParameter(propertyName)) 
                {  
                  value = boundSql.getAdditionalParameter(propertyName); 
                } 
                else if (propertyName.startsWith(ForEachSqlNode.ITEM_PREFIX) && boundSql.hasAdditionalParameter(prop.getName())) 
                {  
                  value = boundSql.getAdditionalParameter(prop.getName()); 
                  if (value != null) 
                  {  
                    value = MetaObject.forObject(value,SystemMetaObject.DEFAULT_OBJECT_FACTORY, SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY).getValue(propertyName.substring(prop.getName().length())); 
                  }  
                } 
                else 
                {  
                  value = metaObject == null ? null : metaObject.getValue(propertyName); 
                }  
                parameterArray[i] = value; 
              }  
            }  
            ibatisSql.setParameters(parameterArray); 
        }  
        return ibatisSql; 
    }
}
package com.jujin.util;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class MyBatisSql {

    /** * 运行期 sql */
    private String sql;

    /** * 参数 数组 */
    private Object[] parameters;

    public void setSql(String sql) {  
        this.sql = sql;  
    }  

    public String getSql() {  
        return sql;  
    }  

    public void setParameters(Object[] parameters) {  
        this.parameters = parameters;  
    }  

    public Object[] getParameters() {  
        return parameters;  
    }  

    @Override
    public String toString() {
        if(parameters == null || sql == null)
        {
            return "";
        }
        List<Object> parametersArray = Arrays.asList(parameters);
        List<Object> list = new ArrayList<Object>(parametersArray);
        while(sql.indexOf("?") != -1 && list.size() > 0 && parameters.length > 0)
        {
            sql = sql.replaceFirst("\\?", list.get(0).toString());
            list.remove(0);
        }
        return sql.replaceAll("(\r?\n(\\s*\r?\n)+)", "\r\n");
    }
}

测试代码web

public String getMyBatisSql(String id, Map<String,Object> parameterMap) {  
        SqlSessionFactory sqlSessionFactory = sqlSessionTemplate.getSqlSessionFactory();
        MyBatisSql sql = MyBatisSqlUtils.getMyBatisSql(id, parameterMap, sqlSessionFactory); 
        return sql.toString();
    }