运行期获取MyBatis执行的SQL及参数
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); 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).getValue(propertyName.substring(prop.getName().length())); } } else { value = metaObject == null ? null : metaObject.getValue(propertyName); } parameterArray[i] = value; } } ibatisSql.setParameters(parameterArray); } return ibatisSql; }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; } @Overridepublic 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 interface AlarmMapper {public List<Alarm> queryAlarmData(@Param(value = "filter") Filter filter,@Param(value = "alarmStatus") AlarmStatus alarmStatus,@Param(value = "startDate") Date startDate,@Param(value = "endDate") Date endDate,@Param(value = "regionId") String regionId,@Param(value = "paramter") Map<String, Object> paramter,@Param(value = "startRow") int startRow,@Param(value = "endRow") int endRow) throws SQLException;}public List<Alarm> queryAlarmData(Filter filter, AlarmStatus alarmStatus,Date start, Date end, String regionId, Map<String, Object> paramter,int startRow, int endRow) {try {List<Alarm> alarms = mapper.queryAlarmData(filter,alarmStatus, start, end, regionId,paramter, startRow, endRow);Map<String,Object> parameterMap = new HashMap<String,Object>(); //存储参数// key 要与Mapper中的参数名一致parameterMap.put("filter", filter);parameterMap.put("alarmStatus", alarmStatus);parameterMap.put("startDate", start);parameterMap.put("endDate", end);parameterMap.put("regionId", regionId);parameterMap.put("paramter", paramter);parameterMap.put("startRow", startRow);parameterMap.put("endRow", endRow);logger.info(MyBatisSqlUtils.getMyBatisSql("queryAlarmData", parameterMap, sqlSessionFactory).toString());return alarms;} catch (Exception e) {e.printStackTrace();throw new RuntimeException(e);}}