`
zhouchaofei2010
  • 浏览: 1085859 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

mybatis出现sql异常时的日志优化-打印sql参数

阅读更多
 
(请参考版本2 ,因为该版本有bug,必须要配置mybatis的日志logimp,否则会报错.
方法:通过插件拦截StatementHandler的parameterize方法,在StatementHandler对象调用parameterize方法设置参数后,就可以获取完整的sql参数

 

package com.glsys.mybatis3.interceptor;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Statement;
import java.util.Properties;

import org.apache.ibatis.executor.ErrorContext;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.logging.jdbc.PreparedStatementLogger;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


@Intercepts({ 
	@Signature(type = StatementHandler.class, method = "parameterize", args = {Statement.class}) })
public class SQLErrorContextInterceptor implements Interceptor {
	private final Logger logger = LoggerFactory.getLogger(this.getClass());
	@Override
	public Object intercept(Invocation invocation) throws Throwable {
		Object obj=invocation.getArgs()[0];
		System.out.println("Before StatementHandler. parameterize()...");
		 System.out.println("Before sql:"+obj.toString());
		  invocation.proceed();
		 System.out.println("Aflter StatementHandler .parameterize()...");
		 System.out.println("Aflter sql:"+obj.toString());
		
		 System.out.println("sql:"+obj.toString());
		 //方式1:直接使用statment对象的 toString方法
		// ErrorContext.instance().sql(obj.toString());
		 //方式2 : 反射获取PreparedStatementLogger父类的PreparedStatementLogger方法
		 StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
	     BoundSql boundSql = statementHandler.getBoundSql();
		 Object handler=Proxy.getInvocationHandler(obj);
		 PreparedStatementLogger pstLogger=(PreparedStatementLogger)handler;
		 Class clz=pstLogger.getClass().getSuperclass();
		 Method m=clz.getDeclaredMethod("getParameterValueString");
		 m.setAccessible(true); 
		 String logStr=(String) m.invoke(pstLogger);
		 System.out.println(logStr);
		 ErrorContext.instance().sql( boundSql.getSql()+" parameters:"+logStr);
		 return null;
	}

	@Override
	public Object plugin(Object target) {
		 return Plugin.wrap(target, this);
	}

	@Override
	public void setProperties(Properties properties) {
		  String dialect = properties.getProperty("dialect");
	        logger.info("mybatis intercept dialect:{}", dialect);
		
	}

}
 
 
1
0
分享到:
评论
2 楼 zhouchaofei2010 2017-10-16  
Saro 写道
在log4j配置里把mapper所在包设为debug就行了,参数什么的都有
<logger name="com.a.b.mapper" level="debug">


开发的时候是可以这样设置的,但是系统上线了日志就不能设置debug了
1 楼 Saro 2017-10-16  
在log4j配置里把mapper所在包设为debug就行了,参数什么的都有
<logger name="com.a.b.mapper" level="debug">

相关推荐

Global site tag (gtag.js) - Google Analytics