zoukankan      html  css  js  c++  java
  • 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;
    
    

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

  • 相关阅读:
    静态成员在类中的初始化
    博客中尖括号不显示的问题
    声明vector对象保存函数指针
    返回数组指针的函数
    C++ 指针与引用的差别
    Configure Eclipse “Content Assist”
    How to install Eclipse-Color-Theme
    国内 git 托管平台
    SHA1 对文件求信息摘要的实现
    SHA1 对字符串求摘要的实现
  • 原文地址:https://www.cnblogs.com/bkmemory/p/13777305.html
Copyright © 2011-2022 走看看