写在前面

《Docker+SpringBoot+Mybatis+thymeleaf的Java博客系统开源啦》

由于开源了项目的缘故,很多使用了My Blog项目的朋友遇到问题也都会联系我去解决,有的是把问题留在项目的issue里提出,有的是在我的私人博客里留言,还有的则是直接添加我的qq来找我讲自己遇到的问题,有些问题比较简单直接就解决了,有些问题的解决记录也留在issue记录里,有些则是网上有相关教程,而剩下问题的解决方案,如果时间允许我都会单独的做一篇博客来解答。

问题描述

当时的聊天记录:

截图中提到的代码(节选):

ContentVoMapper.xml:

 <sql id="Example_Where_Clause">
<where>
<foreach collection="oredCriteria" item="criteria" separator="or">
<if test="criteria.valid">
<trim prefix="(" prefixOverrides="and" suffix=")">
<foreach collection="criteria.criteria" item="criterion">
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
CommentVoExample:

    protected abstract static class GeneratedCriteria {
protected List<Criterion> criteria; protected GeneratedCriteria() {
super();
criteria = new ArrayList<Criterion>();
} public boolean isValid() {
return criteria.size() > 0;
} public List<Criterion> getAllCriteria() {
return criteria;
} public List<Criterion> getCriteria() {
return criteria;
}
...

问题整理:在GeneratedCriteria类中并没有valid这一属性,仅仅只有一个isValid()方法,但是在Mapper文件中mybatis的<if test>语法中,却有criteria.valid的表达式,而且程序可以正常运行,这是怎么回事呢?

思路整理

首先,我刚看到这个问题的时候也是有点懵,因为这个代码其实不是我写的,Mapper文件是我通过Mybatis-Generator自动生成的,所以这段代码我也是有点陌生的,哈哈哈哈。

但是看了一遍代码之后,我觉得应该是mybatis根据valid属性自动找到了isValid()方法,然后执行了逻辑判断,当然,这都是个人感觉,没什么依据,隐隐约约觉得应该是这么个道理。但是呢,毕竟这位朋友是来问问题的,我不能就简简单单的回复这么一句话,而且是连我自己都不确定的答案。

疑惑的问题有:

  • 并不知道mybatis是不是这个执行流程;
  • 即使是如上的流程,那么为什么根本没有的属性会被mybatis正常解析;
  • 为什么mybatis会去执行isValid()方法而不去执行其他的方法。

解决过程

带着以上的问题和心中的不确定,我唯一能做的就是去查看这部分过程的源码了,最终也如愿得到了答案,通过IDEA的debug功能得到了代码的执行过程,可以自行执行查看一下整个过程:

  • IfSqlNode类中,获取了if test标签中表达式的值:criteria.valid;

  • 接着是在ObjectPropertyAccessor类中解析到了需要操作的属性值Criteria类中的valid;

  • 然后是在OgnlRuntime类中得到了表达式对应执行的MethodisValid()方法。

接下来就是执行方法并获取返回值了,就不再截图了。

上面的前两个问题就有了答案:

  • <if test="criteria.valid">到执行isValid()方法的执行流程找到了,虽然过程较多但是几个重要的节点就是以上三点,获取Mapper表达式中的类名和属性值,然后获取需要执行的方法,最终实现整个功能。
  • mybatis并没有去关注是否存在这个属性,而是根据属性去找到对应的方法并执行。

至于第三个问题,我也做了一下扩展,如果其他带有valid字符串的方法会不会也被执行到,结果是肯定回答,如图:

isValid()改为getValid()

OgnlRuntime类中得到了对应执行的MethodgetValid()方法

当两个方法都存在时,会执行isValid()方法,因为if test需要的是一个boolean返回值,当只存在getValid()方法时,则会执行getValid()

结语

首发于我的个人博客

如果有问题或者有一些好的创意,欢迎给我留言,也感谢向我指出项目中存在问题的朋友,关于这篇文章,特别感谢一下@libinghui

代码和这次的问题都是My Blog项目中的,如果你想继续了解该项目可以查看整个系列文章Java开源博客My-Blog(SpringBoot+Docker)系列文章,也可以到我的GitHub仓库或者开源中国代码仓库中查看源码及详细的部署过程和使用文档。

Mybatis-Generator生成Mapper文件中<if test="criteria.valid">的问题解答的更多相关文章

  1. Mybatis逆向生成Mapper文件

    本文参考博客 http://blog.csdn.net/for_my_life/article/details/51228098 1. 在resources根目录下添加generator.proper ...

  2. Mybatis 自动生成mapper文件

    在pom.xml下的<build>内加入: <build> <plugins> <plugin> <groupId>org.mybatis. ...

  3. Maven下用MyBatis Generator生成文件

    使用Maven命令用MyBatis Generator生成MyBatis的文件步骤如下: 1.在mop文件内添加plugin <build> <finalName>KenShr ...

  4. MyBatis mapper文件中的变量引用方式#{}与${}的差别

    MyBatis mapper文件中的变量引用方式#{}与${}的差别 #{},和 ${}传参的区别如下:使用#传入参数是,sql语句解析是会加上"",当成字符串来解析,这样相比于$ ...

  5. ][mybatis]MyBatis mapper文件中的变量引用方式#{}与${}的差别

    转自https://blog.csdn.net/szwangdf/article/details/26714603 MyBatis mapper文件中的变量引用方式#{}与${}的差别 默认情况下,使 ...

  6. MyBatis mapper文件中使用常量

    MyBatis mapper文件中使用常量 Java 开发中会经常写一些静态常量和静态方法,但是我们在写sql语句的时候会经常用到判断是否等于 //静态类 public class CommonCod ...

  7. mybatis Generator生成代码及使用方式

    本文原创,转载请注明:http://www.cnblogs.com/fengzheng/p/5889312.html 为什么要有mybatis mybatis 是一个 Java 的 ORM 框架,OR ...

  8. mybatis逆向工程生成mapper报错

    Result Maps collection already contains value for xxxMapper.BaseResultMap错误解决办法一.问题描述今天在做项目时,遇到一个错误: ...

  9. 使用mybatis-generator插件结合tk.mybatis自动生成mapper二三事

    本篇文章将介绍使用spring boot框架,引入mybatis-generator插件,结合tk.mybatis自动生成Mapper和Entity的一整套流程,其中包括最重要的踩坑与填坑.     ...

随机推荐

  1. R语言重要数据集分析研究——  数据集本身的分析技巧

    数据集本身的分析技巧           作者:王立敏           文章来源:网络 1.数据集 数据集,又称为资料集.数据集合或资料集合,是一种由数据所组成的集合. Data set(或dat ...

  2. 针对Oracle数据库表中的数据的常见操作

    1.查询表中所有数据 select * from 表名; 例:select * from stu; 2.查询的同时修改表中数据 select * from 表名  for update; 例:sele ...

  3. java执行程序的内存分析系列专栏

    近段时间研究了java的程序执行过程中的内存分配,收获颇多,解决了我最近时间学习java的很多困惑点.写java内存分析系列的目的主要有两个,一来是希望给像我一样的java初学者一定的启发,希望也能解 ...

  4. mysql数据库和mongodb数据库的相关操作以及两个数据库的区别

    在docs命令中执行数据操作 MySQL数据库 先启动MySQL服务器  net start mysql 进入MySQL服务器MySQL -uroot -p(这里写你的数据库密码) (-P是从哪个端口 ...

  5. [leetcode-504-Base 7]

    Given an integer, return its base 7 string representation. Example 1: Input: 100 Output: "202&q ...

  6. 关于DOM中的model(将元素转成对象进行操作)

    DOM document (html, xml) object 将文档中的HTML元素转成js的对象 通过ID找到文档的元素转成js对象 var obj = document.getElementBy ...

  7. python迭代器生成器(二)

    其他内置类型迭代器 除了文件以及列表这样的实际的序列外,其他类型也有适合的迭代器. 遍历字典的经典方法是明确的获取其键的列表. 在最近的python版本中,字典有一个迭代器,在迭代环境中,会自动一次返 ...

  8. CentOS6.4虚拟机设置固定IP、安装JDK、Tomcat、Redis并部署web项目

    一.CentOS设置固定IP 1.直接修改配置文件的方式,原文地址:http://www.cnblogs.com/zhja/p/3964159.html (1)首先获取你的GATEWAY 方便后面在c ...

  9. dashDB - Creating a table with CLOB column type

    In order to create a table with clob column type, the table has to be created with "ORGANIZE BY ...

  10. 【ALB学习笔记】基于.NET环境的高频RFID卡读写设备的基本操作案例

    基于.NET环境的高频RFID卡读写设备的基本操作案例 广东职业技术学院  欧浩源 1.引言 RFID高频卡在我们的日常生活中随处可见,是物联网应用中不可或缺的一个重要部分,也是全国职业院校技能大赛& ...