当前位置: 代码迷 >> SQL >> 运作期获取MyBatis执行的SQL及参数
  详细解决方案

运作期获取MyBatis执行的SQL及参数

热度:74   发布时间:2016-05-05 14:00:14.0
运行期获取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;      }      	@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");	}

以上贴的是实现代码,下面贴一段代码演示一下如何使用:

一、Mapper 文件
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;}


二、Mapper 的xml文件此处就不写了,select 的ID 为 queryAlarmData

三、在service层调用 queryAlarmData方法
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);		}	}


四、其实还可以用log4j来实现,将在下一篇博客贴出具体的实现代码(利用Spring的Aop以及自定义注解,实现系统日志功能)

五、欢迎各位指出本文的不妥之处,欢迎拍砖

1 楼 wufabeishang 2012-06-04  
请问log4j怎么实现的啊?也能拦截到SQL执行的参数吗?
2 楼 cfqlove 2012-06-05  
wufabeishang 写道
请问log4j怎么实现的啊?也能拦截到SQL执行的参数吗?

log4j.debug=truelog4j.rootLogger=INFO, stdout, alarmFile# Console output...log4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%5p %d %C: %m%nlog4j.logger.org.junit=DEBUGlog4j.logger.junit=DEBUG# ehcache logger configlog4j.logger.net.sf.ehcache=DEBUG# ibatis logger configlog4j.logger.org.apache.mybatis=DEBUGlog4j.logger.java.sql.ResultSet=INFOlog4j.logger.java.sql=DEBUG# alarm logger configlog4j.logger.com.boco.monitor.*=INFO, alarmFilelog4j.appender.alarmFile=org.apache.log4j.DailyRollingFileAppenderlog4j.appender.alarmFile.File=${catalina.home}/alarm_logs/alarm_log.loglog4j.appender.alarmFile.layout=org.apache.log4j.PatternLayoutlog4j.appender.alarmFile.layout.ConversionPattern=%5p %d %C: %m%n# flex client logger configlog4j.logger.com.boco.monitor.flex.action.ClientLogger=DEBUG, clientLoglog4j.appender.clientLog=org.apache.log4j.DailyRollingFileAppenderlog4j.appender.clientLog.File=${catalina.home}/client_logs/client_log.loglog4j.appender.clientLog.layout=org.apache.log4j.PatternLayoutlog4j.appender.clientLog.layout.ConversionPattern=%5p %d %C: %m%n

这是我项目的log4j配置,你可以参考下。
  相关解决方案