Mybatis: sql中if 判断的坑

简介: “原创精选,转载注明出处,三克油”前言Mbatis 的script标签可以支持很多动态SQL查询、在使用if test判断的时候、会有一些意向不到的坑正文我们一般在Mbatis中做update更新时、都会加上使用if test判断、防...

“原创精选,转载注明出处,三克油”

前言

  • Mbatis 的script标签可以支持很多动态SQL查询、在使用if test判断的时候、会有一些意向不到的坑

正文

  • 我们一般在Mbatis中做update更新时、都会加上使用if test判断、防止更新空值、一般正常都是像name这种既判断NULL又判断''
  • 但是对于int类型的sex字段、如果加上 sex != ''条件时、当sex值为0时、此sql不会被拼加上、也不会被执行更新
<if test="name !=null and name !='' ">
    name = #{name},
</if>
<if test="sex !=null">
    sex = #{sex},
</if>
  • 以上是问题以及现象、现在让我们来看一下Mbatis源码、为什么会出现这种情况
  1. 首先在mbatis中找到啊以上包路径、此路径为解析script标签时用到的类
org.apache.ibatis.scripting
  1. 过程不在细说、对于mbatis来说、script标签的动态SQL、都是遍历条件做SQL拼接而成的
  2. 我们直接看org.apache.ibatis.scripting.xmltags.IfSqlNode这个类、此类是script标签中if标签的判断方式、其中evaluateBoolean返回true时、if标签下的SQL拼接生效
public boolean apply(DynamicContext context) {
    if (evaluator.evaluateBoolean(test, context.getBindings())) {
        contents.apply(context);
        return true;
    }
    return false;
}
  1. 再具体看org.apache.ibatis.scripting.xmltags.ExpressionEvaluator :evaluateBoolean 这个方法、我们看到了如果是number类型、会与0做判断比较
public boolean evaluateBoolean(String expression, Object parameterObject) {
    Object value = OgnlCache.getValue(expression, parameterObject);
    if (value instanceof Boolean) return (Boolean) value;
    if (value instanceof Number) return !new BigDecimal(String.valueOf(value)).equals(BigDecimal.ZERO);
    return value != null;
}
  1. 由此可以发现、当动态sql参数是int类型、并且传入0时、是使用OgnlCache获取的value、而OgnlCache是对OGNL的封装
  2. OGNL的官网上面可以看到如下解释
Any object can be used where a boolean is required. OGNL interprets objects as booleans like this:
· If the object is a Boolean, its value is extracted and returned;
· If the object is a Number, its double-precision floating-point value is compared with zero; non-zero is treated as true, zero as false;
· If the object is a Character, its boolean value is true if and only if its char value is non-zero;
Otherwise, its boolean value is true if and only if it is non-null.

结尾

For Future.

相关文章
|
20天前
|
SQL XML Java
mybatis实现动态sql
MyBatis的动态SQL功能为开发人员提供了强大的工具来应对复杂的查询需求。通过使用 `<if>`、`<choose>`、`<foreach>`等标签,可以根据不同的条件动态生成SQL语句,从而提高代码的灵活性和可维护性。本文详细介绍了动态SQL的基本用法和实际应用示例,希望对您在实际项目中使用MyBatis有所帮助。
47 11
|
2月前
|
SQL 缓存 Java
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
本文详细介绍了MyBatis的各种常见用法MyBatis多级缓存、逆向工程、分页插件 包括获取参数值和结果的各种情况、自定义映射resultMap、动态SQL
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
|
2月前
|
SQL Java 数据库连接
canal-starter 监听解析 storeValue 不一样,同样的sql 一个在mybatis执行 一个在数据库操作,导致解析不出正确对象
canal-starter 监听解析 storeValue 不一样,同样的sql 一个在mybatis执行 一个在数据库操作,导致解析不出正确对象
|
3月前
|
SQL Java 数据库连接
mybatis使用四:dao接口参数与mapper 接口中SQL的对应和对应方式的总结,MyBatis的parameterType传入参数类型
这篇文章是关于MyBatis中DAO接口参数与Mapper接口中SQL的对应关系,以及如何使用parameterType传入参数类型的详细总结。
62 10
|
4月前
|
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标签的用法
|
5月前
|
SQL Java 数据库连接
Mybatis系列之 Error parsing SQL Mapper Configuration. Could not find resource com/zyz/mybatis/mapper/
文章讲述了在使用Mybatis时遇到的资源文件找不到的问题,并提供了通过修改Maven配置来解决资源文件编译到target目录下的方法。
Mybatis系列之 Error parsing SQL Mapper Configuration. Could not find resource com/zyz/mybatis/mapper/
|
4月前
|
SQL XML Java
mybatis :sqlmapconfig.xml配置 ++++Mapper XML 文件(sql/insert/delete/update/select)(增删改查)用法
当然,这些仅是MyBatis功能的初步介绍。MyBatis还提供了高级特性,如动态SQL、类型处理器、插件等,可以进一步提供对数据库交互的强大支持和灵活性。希望上述内容对您理解MyBatis的基本操作有所帮助。在实际使用中,您可能还需要根据具体的业务要求调整和优化SQL语句和配置。
76 1
|
5月前
|
SQL Java 数据库连接
Mybatis系列之 动态SQL
文章详细介绍了Mybatis中的动态SQL用法,包括`<if>`、`<choose>`、`<when>`、`<otherwise>`、`<trim>`和`<foreach>`等元素的应用,并通过实际代码示例展示了如何根据不同条件动态生成SQL语句。
|
5月前
|
SQL Java 关系型数据库
SpringBoot 系列之 MyBatis输出SQL日志
这篇文章介绍了如何在SpringBoot项目中通过MyBatis配置输出SQL日志,具体方法是在`application.yml`或`application.properties`中设置MyBatis的日志实现为`org.apache.ibatis.logging.stdout.StdOutImpl`来直接在控制台打印SQL日志。
SpringBoot 系列之 MyBatis输出SQL日志
|
3月前
|
Java 数据库连接 Maven
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和MyBatis Generator,使用逆向工程来自动生成Java代码,包括实体类、Mapper文件和Example文件,以提高开发效率。
165 2
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。