Mybatis反射修改SQL值
Mybatis反射修改SQL值
某一些情况下我们需要动态的改变Mybtis的执行的sql语句,有两种方法:1)使用拦截器,2)使用反射,拦截器的比较简单点,这里使用反射实现一次,有一点小坑,记录一下:
特别说明:环境配置就不列出来了,下面的所有操作是假设spring已经整合好了mybatis的基础上的。具体的代码连接见文章结尾:
重点在于org.apache.ibatis.builder.StaticSqlSource.getBoundSql(Object)
@Override
public BoundSql getBoundSql(Object parameterObject) {
return new BoundSql(configuration, sql, parameterMappings, parameterObject);
}
// 每次获得是一个新的对象,这里使用反射修改是无效的,所以需要直接修改 BoundSql 的 sql 子弹
代码:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:applicationContext2.xml"})
public class MapperTest {
@Autowired
private SqlSessionFactoryBean sqlSessionFactoryBean;
// 动态修改sql
// 1. 使用 mybatis 的插件来完成参考分页插件改变查询的SQL com.bart.plugins.MyBatisPagePlugi
// 2. 使用反射修改MappedStatement的boundSql
@Test
public void testDynamicModifySQL2() throws Exception {
SqlSessionFactory sessionFactory = sqlSessionFactoryBean.getObject();
Configuration configuration = sessionFactory.getConfiguration();
MappedStatement mappedStatement = configuration.getMappedStatement("com.bart.common.mapper.dao.EmployeeMapper.selectAll");
// org.apache.ibatis.scripting.defaults.RawSqlSource
// 该 sqlSource 中还有一个 org.apache.ibatis.builder.StaticSqlSource 实例
// getSqlSource() 实际上是调用的内部的 StaticSqlSource#getSqlSource() 方法
// 而StaticSqlSource#getSqlSource()每次返回的是一个新的BoundSql对象直接修改这个
// 是无效的,所以我们需要使用反射直接修改那个 StaticSqlSource 中的 sql 字符串的值
SqlSource rowSqlSource = mappedStatement.getSqlSource();
System.out.println(String.format("修改前的SQL = %s", rowSqlSource.getBoundSql(null).getSql()));
// 获得 private final SqlSource sqlSource; 对象
Field staticsqlSourceField = rowSqlSource.getClass().getDeclaredField("sqlSource");
staticsqlSourceField.setAccessible(true);
Object staticsqlSourceObject = staticsqlSourceField.get(rowSqlSource);
// 修改 sqlSource 的 sql 字段值
Field sqlField = staticsqlSourceObject.getClass().getDeclaredField("sql");
sqlField.setAccessible(true);
String sqlFieldValue = (String)sqlField.get(staticsqlSourceObject);
sqlField.set(staticsqlSourceObject, sqlFieldValue +" limit 1");
System.out.println(String.format("修改前的SQL = %s", rowSqlSource.getBoundSql(null).getSql()));
System.out.println("============分割线===============");
List<Employee> list = employeeMapper.selectAll();
list.stream().forEach(System.out::println); // 查询出来就是一条了OK
}
Mybatis反射修改SQL值的更多相关文章
- Java反射-修改字段值, 反射修改static final修饰的字段
反射修改字段 咱们从最简单的例子到难, 一步一步深入. 使用反射修改一个private修饰符的变量name 咱们回到主题, 先用反射来实现一个最基础的功能吧. 其中待获取的name如下: public ...
- 如果不空null并且不是空字符串才去修改这个值,但这样写只能针对字符串(String)类型,如果是Integer类型的话就会有问题了。 int i = 0; i!=''。 mybatis中会返回tr
mybatis 参数为Integer型数据并赋值0时,有这样一个问题: mybatis.xml中有if判断条件判断参数不为空时,赋值为0的Integer参数被mybatis判断为空,因此不执行< ...
- Sql Server 增加字段、修改字段、修改类型、修改默认值(转)
转:http://www.cnblogs.com/pangpanghuan/p/6432331.html Sql Server 增加字段.修改字段.修改类型.修改默认值 1.修改字段名: alter ...
- Java 反射修改类的常量值、静态变量值、属性值
前言 有的时候,我们需要修改一个变量的值,但变量也许存在于 Jar 包中或其他位置,导致我们不能从代码层面进行修改,于是我们就用到了下面的场景,通过反射来进行修改变量的值. 定义一个实体类 class ...
- 详解Java的MyBatis框架中SQL语句映射部分的编写
这篇文章主要介绍了Java的MyBatis框架中SQL语句映射部分的编写,文中分为resultMap和增删查改实现两个部分来讲解,需要的朋友可以参考下 1.resultMap SQL 映射XML 文件 ...
- MyBatis的动态SQL详解
MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑,本文详解mybatis的动态sql,需要的朋友可以参考下 MyBatis 的一个强大的特性之一通常是它 ...
- MyBatis框架——动态SQL、缓存机制、逆向工程
MyBatis框架--动态SQL.缓存机制.逆向工程 一.Dynamic SQL 为什么需要动态SQL?有时候需要根据实际传入的参数来动态的拼接SQL语句.最常用的就是:where和if标签 1.参考 ...
- java web(七): mybatis的动态sql和mybatis generator自动生成pojo类和映射文件
前言: MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据 不同条件拼接 SQL 语句的痛苦.例如拼接时要确保不能忘记添加必要的空格,还 ...
- mybatis中的.xml文件总结——mybatis的动态sql
resultMap resultType可以指定pojo将查询结果映射为pojo,但需要pojo的属性名和sql查询的列名一致方可映射成功. 如果sql查询字段名和pojo的属性名不一致,可以通过re ...
随机推荐
- js实现图片幻灯片效果
其效果是点击图片切换到下一张图片 首先准备五张图片 <ul class="imge"> <li><img src="images/1.jpg ...
- 实战!我用 Wireshark 让你“看得见“ TCP
每日一句英语学习,每天进步一点点: 前言 为了让大家更容易「看得见」 TCP,我搭建不少测试环境,并且数据包抓很多次,花费了不少时间,才抓到比较容易分析的数据包. 接下来丢包.乱序.超时重传.快速重传 ...
- promise对象里resolve和reject状态讲解及Promise.all()的使用
首先来说下同步异步与阻塞非阻塞的概念,同步异步与阻塞非阻塞并没有关系.同步异步主要是事情做完以后,如何进行处理.或者说关注的是一种消息通信机制. 同步的情况下,是由处理消息者自己去等待消息是否被触发: ...
- HTML5新特性 websocket(重点)--多对多聊天室
一.html5新特性 websocket(重点)--多对多聊天室 HTTP:超文本传输协议 HTTP作用:传输网页中资源(html;css;js;image;video;..) HTTP是浏览器搬运 ...
- 【python----发轫之始】【基础知识总结】
python基础知识总结 一.自学感受 学完之后,,,感觉脑子里全是乱的,单词这么多,都要分不清什么时候该用什么,他到底属于哪一个数据类型里的函数,,,,,, 所以,我想着把笔记整理一下,方便自己和需 ...
- CukeTest+Puppeteer的Web自动化测试(一)
CukeTest+Puppeteer的Web自动化测试 一.初识BDD.Cucumber(黄瓜).CukeTest 行为驱动开发(Behavior Driven Development,BDD).行为 ...
- 苏浪浪 201771010120 第四周 Java基本程序设计总结
第四章 对象与类 学习目标 掌握类与对象的基础概念,理解类与对象的关系: 掌握对象与对象变量的关系: 掌握预定义类的基本使用方法,熟悉Math类.String类.math类.Scanner类.Lo ...
- Java——线程安全的集合
线程安全的集合 java.util.concurrent包:ConcurrentHashMap,ConcurrentSkipListMap,ConcurrentSkipListSet,Concu ...
- ES[7.6.x]学习笔记(十)聚合查询
聚合查询,它是在搜索的结果上,提供的一些聚合数据信息的方法.比如:求和.最大值.平均数等.聚合查询的类型有很多种,每一种类型都有它自己的目的和输出.在ES中,也有很多种聚合查询,下面我们看看聚合查询的 ...
- rocketmq初识
概念说明 通常一个消息队列需要掌握的知识点有Topic(主体).Producer(生产者).Consumer(消费者).Queue(队列).Delivery Semantics(消息传递范式) 蛋疼的 ...