• springboot使用mybatis插件动态修改sql


    一、关于mybatis的定位


    mybatis很大的一个功能就是解析mapper.xml文件,按照规则解析sql,并交由数据库驱动最终执行sql,然后对结果集进行处理

    二、先说一下我们要做的事情:在sql执行前对sql进行动态修改,接收到结果后,对结果再次进行修改


    于是有了如上图设计
    那拦截器到底要如何设计才能做到修改sql呢,就要说到sqlSession的四大对象executor, statementHandler, parameterHandler,resultHandler。对于这四大对象有很多文章解析,这里我们只用到statementHandler和resultSetHandler

    三、准备

    实体类

    四、自定义拦截


    注解里声明了要拦截的对象,分别是statementHandler和resultSetHandler

    在sql执行前拦截到statementHandle

    public Object process(Invocation invocation) throws Throwable {
     
    	StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
    	BaseStatementHandler delegate = (BaseStatementHandler) ReflectUtil.getFieldValue(statementHandler, "delegate");
    	MappedStatement mappedStatement = (MappedStatement) ReflectUtil.getFieldValue(delegate, "mappedStatement");
    	Object parameterObject = boundSql.getParameterObject();
    	
    	MetaObject metaMappedStatement = MetaObject.forObject(mappedStatement
    			, new DefaultObjectFactory(), new DefaultObjectWrapperFactory(), new DefaultReflectorFactory());
    	SqlNode sqlNode = (SqlNode) metaMappedStatement.getValue("sqlSource.rootSqlNode");
    	//动态生成sql
    	DynamicContext context = new DynamicContext(mappedStatement.getConfiguration(), boundSql.getParameterObject());
    	sqlNode.apply(context);
    	String contextSql = context.getSql();
    	// 将实体类中的方法加载到
    	Map<String, Method> methodMap = getMethodMap(parameterObject);
     
    	modifySql(contextSql, parameterObject, key, methodMap);
    	for (Map.Entry<String, Object> entry : context.getBindings().entrySet()) {
    		boundSql.setAdditionalParameter(entry.getKey(), entry.getValue());
    	}
     
    	return invocation.proceed();
    }
    
    

    在sql返回结果后拦截resultSetHandler

    
    public Object process(Invocation invocation) throws Throwable {
     
    	Object result = invocation.proceed();
     
    	//如果结果集是一个List
    	if (result instanceof ArrayList) {
    		ArrayList resultList = (ArrayList) result;
    		for (int i = 0; i < resultList.size(); i++) {
    			//依次获取其中的对象
    			Object object = resultList.get(i);
    				//利用反射对结果集中的每个对象进行处理,
    				handleObject(object);
    				System.out.println(object);
    			}
    			resultList.set(i,object);
    		}
    		return resultList;
    	}
     
    	return result;
    
    

    这样,就可以对结果集进行处理

  • 相关阅读:
    C的xml编程文章链接
    《Android内核剖析》读书笔记 第13章 View工作原理【View树遍历】
    在MyEclipse中编写Web Project,编码设置全集合
    “克强经济学”绝非是通缩经济学
    VS2008--无法找到“XXX.exe”的调试信息,或者调试信息不匹配
    Dubbo架构设计详解--转载
    Beyond MySQL --Branching the popular database--转载
    eclipse中不能找到dubbo.xsd解决方法
    Java + MongoDB Hello World Example--转载
    Dubbo入门实例--转载
  • 原文地址:https://www.cnblogs.com/bkmemory/p/13777305.html
Copyright © 2020-2023  润新知