mybatis获取运行时最终执行SQL

    xiaoxiao2021-12-15  69

    废话不多说上代码,我的版本是mybatis-3.2.8

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

    测试代码

    public String getMyBatisSql(String id, Map<String,Object> parameterMap) { SqlSessionFactory sqlSessionFactory = sqlSessionTemplate.getSqlSessionFactory(); MyBatisSql sql = MyBatisSqlUtils.getMyBatisSql(id, parameterMap, sqlSessionFactory); return sql.toString(); }
    转载请注明原文地址: https://ju.6miu.com/read-999995.html

    最新回复(0)