mybatis - 基于拦截器修改执行语句中的ResultMap映射关系
拦截器介绍
mybatis提供了@Intercepts注解允许开发者对mybatis的执行器Executor进行拦截。
Executor接口方法主要有update、query、commit、rollback等等。
主要思路为:
- 进入拦截器方法中
- 获取拦截器方法参数
- 获取解析参数及MappedStatement
- 从MappedStatement声明类中获取resultMap
- 获取resultMappings并且进行自定义
- 重新组装新的ResultMap
- 利用反射将新的ResultMap设置进入MappedStatement中
拦截器代码
import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ResultMap;
import org.apache.ibatis.mapping.ResultMapping;
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.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Field;
import java.util.*;
@Component
@Intercepts({@org.apache.ibatis.plugin.Signature(type = Executor.class, method = "query",
args = {
MappedStatement.class,
Object.class,
RowBounds.class,
ResultHandler.class,
CacheKey.class,
BoundSql.class})})
public class MybatisInterceptorConfig implements Interceptor {
/*重置ResultMapping*/
private List<ResultMapping> resetResultMap(List<ResultMapping> resultMaps){
//ResultMaps.add
return resultMaps;
}
@Override
public Object intercept(Invocation invocation) throws Throwable {
resetResultMap(invocation);
return invocation.proceed();
}
@Override
public Object plugin(Object o) {
return Plugin.wrap(o, this);
}
@Override
public void setProperties(Properties properties) {
}
private void resetResultMap(Invocation invocation) {
final Object[] args = invocation.getArgs();
MappedStatement mappedStatement = (MappedStatement) args[5];
ResultMap resultMap = mappedStatement.getResultMaps().iterator().next();
if (resultMap != null) {
List<ResultMapping> resultMappings = resultMap.getResultMappings();
if (resultMappings != null && !(resultMappings instanceof AdjustedList)) {
List<ResultMapping> newResultMappings = this.resetResultMap(new AdjustedList(resultMappings));
ResultMap newResultMap = new ResultMap.Builder(mappedStatement.getConfiguration(), resultMap.getId(), resultMap.getType(), newResultMappings).build();
Field field = ReflectionUtils.findField(MappedStatement.class, "resultMaps");
ReflectionUtils.makeAccessible(field);
ReflectionUtils.setField(field, mappedStatement, Collections.singletonList(newResultMap));
}
}
}
private class AdjustedList<E> extends ArrayList<E> {
public AdjustedList(Collection<? extends E> c) {
super(c);
}
}
}
mybatis - 基于拦截器修改执行语句中的ResultMap映射关系的更多相关文章
- mybatis - 基于拦截器修改执行中的SQL语句
拦截器介绍 mybatis提供了@Intercepts注解允许开发者对mybatis的执行器Executor进行拦截. Executor接口方法主要有update.query.commit.rollb ...
- Struts2拦截器的执行过程浅析
在学习Struts2的过程中对拦截器和动作类的执行过程一度陷入误区,特别读了一下Struts2的源码,将自己的收获分享给正在困惑的童鞋... 开始先上图: 从Struts2的图可以看出当浏览器发出请求 ...
- Mybatis自定义拦截器与插件开发
在Spring中我们经常会使用到拦截器,在登录验证.日志记录.性能监控等场景中,通过使用拦截器允许我们在不改动业务代码的情况下,执行拦截器的方法来增强现有的逻辑.在mybatis中,同样也有这样的业务 ...
- mybatis Interceptor拦截器代码详解
mybatis官方定义:MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis ...
- Mybatis之拦截器原理(jdk动态代理优化版本)
在介绍Mybatis拦截器代码之前,我们先研究下jdk自带的动态代理及优化 其实动态代理也是一种设计模式...优于静态代理,同时动态代理我知道的有两种,一种是面向接口的jdk的代理,第二种是基于第三方 ...
- MyBatis实现拦截器分页功能
1.原理 在mybatis使用拦截器(interceptor),截获所执行方法的sql语句与参数. (1)修改sql的查询结果:将原sql改为查询count(*) 也就是条数 (2)将语句sql进行拼 ...
- Mybatis Interceptor 拦截器原理 源码分析
Mybatis采用责任链模式,通过动态代理组织多个拦截器(插件),通过这些拦截器可以改变Mybatis的默认行为(诸如SQL重写之类的),由于插件会深入到Mybatis的核心,因此在编写自己的插件前最 ...
- Struts2第七篇【介绍拦截器、自定义拦截器、执行流程、应用】
什么是拦截器 拦截器Interceptor-..拦截器是Struts的概念,它与过滤器是类似的-可以近似于看作是过滤器 为什么我们要使用拦截器 前面在介绍Struts的时候已经讲解过了,Struts为 ...
- mybatis定义拦截器
applicationContext.xml <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlS ...
随机推荐
- if-else连用时的陷阱
近日,在实现<The C Programing Language>上的一个练习题时,写出了下面一段代码 ; i<=right; i++) { ) ) swap(v, i, ++la ...
- pikachu-反序列化漏洞
1.序列化的概念(摘自pikachu平台的介绍) (1)序列化serialize() 序列化说通俗点就是把一个对象变成可以传输的字符串,比如下面是一个对象: class S{ public $te ...
- imx6ull+debian10 构建静态qt交叉编译环境
# PC:Ubuntu18.04# GCC: arm-linux-gnueabihf- 7.4.0# 开发板:# imx6ull+debian10(文件系统为野火提供的) # 此处需要编译的是带gst ...
- LaTex安装介绍
写在前面 很多的会议.期刊要求投稿使用LaTex编辑,而不是Word,使用好LaTex后,论文的排版任务确实会变得轻松. 1.下载软件 LaTex有很多衍生版,常用的推荐是Tex live,安装方式选 ...
- QingTing.Fm-WPF是调用蜻蜓FMAPI 查询API内容展示,进行播放
QingTing.Fm 是调用蜻蜓FM API 查询界面内容,进行在线播放. Release地址下载 环境 Visual Studio 2019,dotNet Framework 4.6.1 SD ...
- C#设计模式学习笔记:(3)抽象工厂模式
本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/7596897.html,记录一下学习过程以备后续查用. 一.引言 接上一篇C#设计模式学习笔记:简单工厂模式( ...
- .net core 开发 Windows Forms 程序
我是一名 ASP.NET 程序员,专注于 B/S 项目开发.累计文章阅读量超过一千万,我的博客主页地址:https://www.itsvse.com/blog_xzz.html 引言 .net cor ...
- js函数的使用+封装+代码复用
javascript 函数 return 后面没有返回值 代表提早退出语句,return后面的语句都不再执行 此时返回值为undefined <!DOCTYPE html> <htm ...
- Angular修改Port文件一览
\protractor.conf.js\README.md\node_modules\angular-cli\README.md\node_modules\angular-cli\blueprints ...
- P1478 陶陶摘苹果(升级版)(sort(),时间优化,priority_queue)
题目描述 又是一年秋季时,陶陶家的苹果树结了 n 个果子.陶陶又跑去摘苹果,这次他有一个 a 公分的椅子.当他手够不着时,他会站到椅子上再试试. 这次与 NOIp2005 普及组第一题不同的是:陶陶之 ...