写在前面

《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. 常用DOM API

    Node Node是一个接口,中文叫节点,很多类型的DOM元素都是继承于它,都共享着相同的基本属性和方法.常见的Node有 element,text,attribute,comment,documen ...

  2. 关于 asp.net 点击确定按钮 获取不到新值问题

    点击事件内,可以使用request.form[" kk"] 获取到值,但是this.txt.Text 确实旧值, 尼玛,居然没加isPostBack重新加载了数据 ,request ...

  3. IBM新合作伙伴计划助力企业转型升级

        IBM作为老牌企业,一直在引领者技术方面的变革.当IBM再一次从自我革新开始,期望能够更快的将认知计算和云推广给自己的合作伙伴和用户们,以帮助他们在新的转型期内,能够快人一步.         ...

  4. Tomcat7的热部署

    所谓热部署就是在tomcat不停机的情况下,将新的war包放上去,达到服务不中断,用户无察觉的目的,实现的原理很简单,这里做下记录,以便后期查看. 1.1 安装tomcat7 略 1.2 在tomca ...

  5. 远程调用其它站点并设置cookie

    远程调用其它站点并设置cookie: 参考js var domainArray = [ {site:'g.com',action:'/b.do?c' } ,{site:'www.baidu.com', ...

  6. MySQL加密和解密案例

    define("ENCRYPT",'2998a15c0cd853edad7');//密钥key 被存储的数据库的字段设置成blob格式(二进制) //AES_ENCRYPT 加密 ...

  7. json字符串转成数组

    $hour_23 json_decode($hour_23,true);//(第二个参数为true的时候)

  8. 微信支付之统一下单--JAVA版

    都说微信支付有些坑,都抱怨微信支付的文档太烂,一会APPId,一会商户id,还有appsecret,支付API秘钥让你傻傻分不清楚,还有这里大写那里小写,几种标准,让你眼花缭乱.没错,这就是很多技术团 ...

  9. CNN中的卷积核及TensorFlow中卷积的各种实现

    声明: 1. 我和每一个应该看这篇博文的人一样,都是初学者,都是小菜鸟,我发布博文只是希望加深学习印象并与大家讨论. 2. 我不确定的地方用了"应该"二字 首先,通俗说一下,CNN ...

  10. php如何上传txt文件,并且读取txt文件

    1.创建目录如下