MyBatis【源码探究 01】mapper.xml文件内<if test>标签判断参数值不等于null和空(当参数值为0)时筛选条件失效原因分析

简介: MyBatis【源码探究 01】mapper.xml文件内<if test>标签判断参数值不等于null和空(当参数值为0)时筛选条件失效原因分析

这个问题有不少小伙伴遇到过,也给出了解决方案,但是没有探究原因,这次读一下源码,看看原因在哪里。

1. 条件失效情况复现

  • Mapper.xml内的动态SQL如下【伪代码】
<select id="getInfoList" parameterType="java.util.Map" resultType="java.util.Map">
        SELECT
        *
        ${schemaName}${tableName}
        <where>
      <if test="viewId != null and viewId != ''">
                AND viewid = #{viewId}
            </if>
        </where>
  </select>
  • 调用动态SQL的方法如下【伪代码主要是显示一下传递的参数值】
Map<String, Object> mapParam = new HashMap<>(4);
mapParam.put("schemaName", "public");
mapParam.put("tableName", "info_table");
mapParam.put("viewId", 0);
queryInterface.getInfoList(mapParam);

查看查询结果会发现对 viewId 没有进行筛选。

2. 解决方法

去掉判断条件 and viewId != '' 即可。

<select id="getInfoList" parameterType="java.util.Map" resultType="java.util.Map">
        SELECT
        *
        ${schemaName}${tableName}
        <where>
            <if test="viewId != null">
                AND viewid = #{viewId}
            </if>
        </where>
  </select>

3. 源码解析

到底是为什么呢?我们找到 Mybatis 的 IfSqlNode 对象:

下边是打断点进行的参数追踪:

evaluator.evaluateBoolean(test, context.getBindings()) 为 true 时当前节点才会被应用。

进入 evaluateBoolean(test, context.getBindings()) 方法。

进入 OgnlCache.getValue(expression, parameterObject) 方法。

关键方法出现了:Ognl.getValue(parseExpression(expression), context, root);

我们找到 Ognl.getValue(parseExpression(expression), context, root)方法。

中间省略了部分方法,省略的方法主要是查找参数名称和参数值,不重要故未贴出。还有判断节点类型的过程,例子中用的的都是不等于类型的节点。下边的方法真正开始对表达式两侧的数值进行比较了。前半段的 viewId != null 不再贴出,只截图有问题的后半段:

进入最核心的方法比较方法 compareWithConversion(Object v1, Object v2)

看一下转换的过程:

问题的核心代码:

public static double doubleValue(Object value) throws NumberFormatException {
        if (value == null) {
            return 0.0D;
        } else {
            Class c = value.getClass();
            if (c.getSuperclass() == Number.class) {
                return ((Number)value).doubleValue();
            } else if (c == Boolean.class) {
                return (Boolean)value ? 1.0D : 0.0D;
            } else if (c == Character.class) {
                return (double)(Character)value;
            } else {
                String s = stringValue(value, true);
                return s.length() == 0 ? 0.0D : Double.parseDouble(s);
            }
        }
    }

由于 "".length() = 0,传递的参数 viewId 值是 0️⃣ 时 viewId != '' 就变成 0.0 != 0.0 这个自然是 false 此时,筛选条件不起作用就不足为奇了。

为什么会出现这种情况?是框架问题吗? 感觉不是的,我们在编程的时候,对数值类型值的判断本身就不应该使用 =='' 或者 !=''这样的条件。

目录
相关文章
|
6天前
|
XML Java 数据库连接
微服务——SpringBoot使用归纳——Spring Boot集成MyBatis——基于 xml 的整合
本教程介绍了基于XML的MyBatis整合方式。首先在`application.yml`中配置XML路径,如`classpath:mapper/*.xml`,然后创建`UserMapper.xml`文件定义SQL映射,包括`resultMap`和查询语句。通过设置`namespace`关联Mapper接口,实现如`getUserByName`的方法。Controller层调用Service完成测试,访问`/getUserByName/{name}`即可返回用户信息。为简化Mapper扫描,推荐在Spring Boot启动类用`@MapperScan`注解指定包路径避免逐个添加`@Mapper`
26 0
|
17天前
|
XML Java 数据库连接
二、搭建MyBatis采用xml方式,验证CRUD(增删改查操作)
二、搭建MyBatis采用xml方式,验证CRUD(增删改查操作)
73 21
|
5月前
|
XML 前端开发 Java
讲解SSM的xml文件
本文详细介绍了SSM框架中的xml配置文件,包括springMVC.xml和applicationContext.xml,涉及组件扫描、数据源配置、事务管理、MyBatis集成以及Spring MVC的视图解析器配置。
133 1
|
6月前
|
SQL XML Java
mybatis-源码深入分析(一)
mybatis-源码深入分析(一)
|
4月前
|
XML Android开发 数据格式
Eclipse 创建 XML 文件
Eclipse 创建 XML 文件
78 2
|
4月前
|
Java Maven
maven项目的pom.xml文件常用标签使用介绍
第四届人文,智慧教育与服务管理国际学术会议(HWESM 2025) 2025 4th International Conference on Humanities, Wisdom Education and Service Management
450 8
|
4月前
|
SQL 缓存 Java
MyBatis如何关闭一级缓存(分注解和xml两种方式)
MyBatis如何关闭一级缓存(分注解和xml两种方式)
166 5
|
6月前
|
SQL XML Java
mybatis复习03,动态SQL,if,choose,where,set,trim标签及foreach标签的用法
文章介绍了MyBatis中动态SQL的用法,包括if、choose、where、set和trim标签,以及foreach标签的详细使用。通过实际代码示例,展示了如何根据条件动态构建查询、更新和批量插入操作的SQL语句。
mybatis复习03,动态SQL,if,choose,where,set,trim标签及foreach标签的用法
|
6月前
|
SQL XML Java
mybatis复习04高级查询 一对多,多对一的映射处理,collection和association标签的使用
文章介绍了MyBatis中高级查询的一对多和多对一映射处理,包括创建数据库表、抽象对应的实体类、使用resultMap中的association和collection标签进行映射处理,以及如何实现级联查询和分步查询。此外,还补充了延迟加载的设置和用法。
mybatis复习04高级查询 一对多,多对一的映射处理,collection和association标签的使用
|
5月前
|
XML JavaScript Java
java与XML文件的读写
java与XML文件的读写
58 3

热门文章

最新文章