mybatis中之后台调出sql语句

本文介绍了一种在MyBatis中记录执行的SQL语句及其参数的方法。通过AOP技术,可以在运行时捕获到实际执行的SQL语句,并将其与对应的参数一起保存。这种方法对于调试和日志记录非常有用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数据库中如果想保存sql语句可以这样处理,进行aop处理;

此方式是在网上找了很多资料,拿过来大约整合调试出来的,并非原创;

1,先创建类
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;
	}

	public String toString() {
		if (parameters == null || sql == null) {
			return "";
		}
		try {
			List parametersArray = Arrays.asList(parameters);
			List list = new ArrayList(parametersArray);
			if(!list.toString().equals("[null]")){
				while (sql.indexOf("?") != -1 && list.size() > 0 && parameters.length > 0) {
					if(null!=list.get(0)){
						sql = sql.replaceFirst("\\?", list.get(0).toString());
						list.remove(0);
					}else{ //走添加保存方法list无法获取get(0)选项的情况
						String ls = list.toString();
						ls=ls.replace("[", "");
						ls=ls.replace("]", "");
						System.out.println(ls);
						String[] strs = ls.split(",");
						for(String s :strs){
							sql = sql.replaceFirst("\\?", s);
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return sql.replaceAll("(\r?\n(\\s*\r?\n)+)", "\r\n");
	}
}
2,获取sql
/**
 * mybatis获取sql语句
 * @author HGJ
 *
 */
public class MyBatisSqlUtils {

	/**
	 * 运行期获取MyBatis执行的SQL及参数
	 * @param id             Mapper xml 文件里的select Id
	 * @param parameterMap   参数
	 * @param sqlSessionFactory 
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public static MyBatisSql getMyBatisSql(String id, Map parameterMap,SqlSessionFactory sqlSessionFactory) {
		MyBatisSql ibatisSql = new MyBatisSql();
	    MappedStatement ms = sqlSessionFactory.getConfiguration().getMappedStatement(id);
	    BoundSql boundSql = ms.getBoundSql(parameterMap);
	    ibatisSql.setSql(boundSql.getSql());
	    List 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, null, null);  
	             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, null, null).getValue(propertyName.substring(prop.getName().length()));  
	              } 
	            }else{  
	              value = metaObject == null ? null : metaObject.getValue(propertyName);  
	            }
	            parameterArray[i] = value;  
	          }  
	        }  
	        ibatisSql.setParameters(parameterArray);
	    }  
        return ibatisSql;
	}
	
}
3,调用方式
    @Autowired
	private SqlSessionFactory sqlSessionFactory;
	
	Map mapParam = new HashMap();
	try {
		mapParam = writeLogHasValueInfo(paramNames, joinPoint);
		sql = MyBatisSqlUtils.getMyBatisSql(joinPoint.getSignature()
				.getName(), mapParam, sqlSessionFactory)
				+ "";
	} catch(Exception exception){
		logger.error(exception.toString());
	}
	//注意:getMyBatisSql(第一个参数是mybatis中接口的名称,第二个是捕获后封装的map参数,sqlSessionFactory);
3,关于writeLogHasValueInfo方法
    /**
	 * 排除null
	 * 
	 * @param paramNames
	 * @param joinPoint
	 * @return
	 */
	private static Map writeLogHasValueInfo(
		String[] paramNames, JoinPoint joinPoint) {
		Map map = new HashMap();
		Map map2 = new HashMap();
		Object[] args = joinPoint.getArgs();
		boolean clazzFlag = true;
		for (int k = 0; k < args.length; k++) {
			Object arg = args[k];
			// 获取对象类型
			String typeName = arg.getClass().getName();
			for (String t : types) {
				if (t.equals(typeName)) {
					map.put(paramNames[k], arg);
				}
			}
			if (clazzFlag) {
				map2 = getFieldsHasValue(arg);
			}
		}
		map.putAll(map2);
		return map;
	}
	
	/**
	 * 得到的列有参数和值(排除null)
	 * 
	 * @param obj
	 */
	public static Map getFieldsHasValue(Object obj) {
		Map map = new HashMap();
		Field[] fields = obj.getClass().getDeclaredFields();
		String typeName = obj.getClass().getName();
		for (String t : types) {
			if (t.equals(typeName)) {
				// return "";
			}
		}
		for (Field f : fields) {
			f.setAccessible(true);
			try {
				for (String str : types) {
					if (f.getType().getName().equals(str)) {
						if (null != f.get(obj)) {
							map.put(f.getName(), f.get(obj));
						}
					}
				}
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		return map;
	}
	
	

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值