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 ...
随机推荐
- docker 部署jenkins
1.拉取镜像 docker pull jenkins/jenkins 2.运行jenkins镜像作为容器 运行命令如下: docker run -d -p 9086:8080 -p 50000:500 ...
- Reflux之Store
Reflux中的Store既是一个listener(既有对action的监听,又有对store的监听)同时又是一个publisher. 一.监听单个action const Reflux = requ ...
- java中字符串截取
1.使用StringUtils,需要导包 String strs = "abcdef1003535197"; System.out.println("=====2==== ...
- Python的概述
官网:https://www.python.org/ 诞生:1989年底诞生,1990年V1发布,2000年V2发布,2008年V3发布(不兼容V2),2017年随着AI的崛起而流行 特点:简单.跨平 ...
- BZOJ 1084DP
1084: [SCOI2005]最大子矩阵 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2796 Solved: 1391[Submit][Sta ...
- JavaScript计时
JavaScript计时分两种 setTimeout:程序在隔几秒后执行 语法: setTimeout(function(){要执行的程序},xxxx) setInterval:程序每隔几秒执行 语法 ...
- Python面向对象的特征跟私有属性
面向对象的三大特征 继成.封装.多态: 继承:一个类可以继承一个或多个类,被继承的类叫做父类,继承的类叫做子类 封装:将数据和方法放在了一个类中就构成了封装 多态:指的一类事物有多重形态,一个抽象类 ...
- 前端自动化构建之webpack
前言 学了gulp后马上就开始学了一下webpack,所以马上来谈一下感受,感觉webpack有人说是一个模块化工具,用来和browserify来做比较,我感觉webpack牛逼多了,不但可以把复杂的 ...
- 化学元素周期表的英文全称 Periodic Table of the Elements
化学元素周期表的英文全称 Periodic Table of the Elements 缩写 PTE 拉丁文 英文 1 H 氢 Hydrogenium Hydrogen 2 He 氦 Helium ...
- CPU缓存学习及C6678缓存使用总结(知识归纳)
作者注: 1.本篇博客内容是本人在学习cpu缓存原理时进行的学习总结,参考了多处相关资源(书籍,视频,知乎回答等),参考出处标注在内容最后. 2.由于本篇内容的编辑工作在印象笔记完成,输出的PDF文件 ...