自己挖的坑自己填--Mybatis mapper文件if标签中number类型及String类型的坑
1.现象描述
(1)使用 Mybatis 在进行数据更新时,大部分时候update语句都需要通过动态SQL进行拼接。在其中,if标签中经常会有 xxx !='' 这种判断,若 number 类型的字段上传递的值为 0, 执行更新时会发现数据库中的数据并没有被更新成 0,这种异常现象不会报错,所以容易被忽视。
<update id="update" parameterType="com.hrh.mybatis.bean.Person">
update tab_person
<set>
<if test="id != null">
id = #{id,jdbcType=BIGINT},
</if>
<if test="name != null">
name= #{name,jdbcType=VARCHAR},
</if>
<if test="age != null and age !=''" >
age= #{age,jdbcType=BIGINT}
</if>
</set>
where id = #{id,jdbcType=BIGINT}
</update>
(2)在 if 标签中有时会用到加条件的判断,如 xxx != ‘x’,如果筛选条件中只有单个字符时,这样拼接执行会报错
### Error querying database. Cause: java.lang.NumberFormatException: For input string: "张三"
### Cause: java.lang.NumberFormatException: For input string: "张三"
<select id="selectByCondition" resultType="com.hrh.mybatis.bean.Person" parameterType="java.lang.String">
select
<include refid="Base_Column_List"/>
from tab_person
where
<if test="name != null and name !='a'">
name = #{name,jdbcType=VARCHAR}
</if>
</select>
2.原因探究
(1)Mybatis的表达式使用 OGNL 处理的,若对象是一个 number 类型,值为0时将被解析为 false,否则为 true,浮点型 0.00也是如此。所以问题1中的 <if test="age != null and age !=''" >当age为0时导致表达式的值为false,不进行SQL拼接,执行更新后数据库中的数据不会被更新成0。
所以对于insert语句拼接也是一样的,<if test="age != null and age !=''" >当age为0时导致表达式的值为false,不进行SQL拼接,导致参数和值传递不一致报错
### Error updating database. Cause: java.sql.SQLException: Column count doesn't match value count at row 1
### The error may involve com.hrh.mybatis.mapper.PersonMapper.insertSelective-Inline
### The error occurred while setting parameters
### SQL: insert into tab_person ( id, name, age ) values ( ?, ? )
### Cause: java.sql.SQLException: Column count doesn't match value count at row 1
bad SQL grammar []; nested exception is java.sql.SQLException: Column count doesn't match value count at row 1
<insert id="insertSelective" parameterType="com.hrh.mybatis.bean.Person">
insert into tab_person
<trim prefix="(" suffix=")" suffixOverrides="," >
<if test="id != null">
id,
</if>
<if
test="name != null">
name,
</if>
<if test="age != null">
age
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides="," >
<if test="id != null">#{id,jdbcType=BIGINT},
</if>
<if test="name != null">
#{name,jdbcType=VARCHAR},
</if>
<if test="age != null and age !=''">
#{age,jdbcType=BIGINT}
</if>
</trim>
</insert>
(2)单引号 '' 内如果为单个字符时,OGNL 将会识别为Java的char 类型,String类型与char 类型做运算时会报错。
3.解决办法
(1)number 类型的字段在进行拼接时只需要判断 xxx!=null即可。
<update id="update" parameterType="com.hrh.mybatis.bean.Person">
update tab_person
<set>
<if test="id != null">
id = #{id,jdbcType=BIGINT},
</if>
<if test="name != null">
name= #{name,jdbcType=VARCHAR},
</if>
<if test="age != null" >
age= #{age,jdbcType=BIGINT}
</if>
</set>
where id = #{id,jdbcType=BIGINT}
</update>
(2)第二种情况只需要将单引号和双引号调换即可。
<select id="selectByCondition" resultType="com.hrh.mybatis.bean.Person" parameterType="java.lang.String">
select
<include refid="Base_Column_List"/>
from tab_person
where
<if test='name != null and name !="a"'>
name = #{name,jdbcType=VARCHAR}
</if>
</select>
自己挖的坑自己填--Mybatis mapper文件if标签中number类型及String类型的坑的更多相关文章
- MyBatis mapper文件中的变量引用方式#{}与${}的差别
MyBatis mapper文件中的变量引用方式#{}与${}的差别 #{},和 ${}传参的区别如下:使用#传入参数是,sql语句解析是会加上"",当成字符串来解析,这样相比于$ ...
- [DB][mybatis]MyBatis mapper文件引用变量#{}与${}差异
MyBatis mapper文件引用变量#{}与${}差异 默认,使用#{}语法,MyBatis会产生PreparedStatement中.而且安全的设置PreparedStatement參数,这个过 ...
- intellij idea 插件开发--快速定位到mybatis mapper文件中的sql
intellij idea 提供了openApi,通过openApi我们可以自己开发插件,提高工作效率.这边直接贴个链接,可以搭个入门的demo:http://www.jianshu.com/p/24 ...
- mybatis mapper文件sql语句传入hashmap参数
1.怎样在mybatis mapper文件sql语句传入hashmap参数? 答:直接这样写map就可以 <select id="selectTeacher" paramet ...
- ][mybatis]MyBatis mapper文件中的变量引用方式#{}与${}的差别
转自https://blog.csdn.net/szwangdf/article/details/26714603 MyBatis mapper文件中的变量引用方式#{}与${}的差别 默认情况下,使 ...
- MyBatis mapper文件中使用常量
MyBatis mapper文件中使用常量 Java 开发中会经常写一些静态常量和静态方法,但是我们在写sql语句的时候会经常用到判断是否等于 //静态类 public class CommonCod ...
- Mybatis mapper文件占位符设置默认值
如果要设置占位符默认值的话:需要进行 设置 org.apache.ibatis.parsing.PropertyParser.enable-default-value 属性为true启用占位符默认值处 ...
- [转载]MyBatis mapper文件中的变量引用方式#{}与${}的差别
转载自:http://blog.csdn.net/szwangdf/article/details/26714603 默认情况下,使用#{}语法,MyBatis会产生PreparedStatement ...
- Mybatis Mapper文件中的一小坑
前几天来一需求,实现过程中需要修改一个底层的查询接口,具体修改就是在where中添加一个条件,由于这个底层SQL使用的地方太多,所以就想着是用if加一标识符做个判断,传一个只有我会使用的参数,然后动态 ...
随机推荐
- Codeforces 11D A Simple Task 统计简单无向图中环的个数(非原创)
太难了,学不会.看了两天都会背了,但是感觉题目稍微变下就不会了.dp还是摸不到路子. 附ac代码: 1 #include<iostream> 2 #include<cstdio> ...
- java有序数组的有序交集
public static void main(String[] args) throws ParseException { int[] a = {4,5,-1,-1}; int[] b = {-1, ...
- TypeScript Version 23 Design Patterns
TypeScript Version 23 Design Patterns TypeScript 设计模式 https://refactoring.guru/design-patterns/types ...
- React Query & SWR
React Query & SWR HTTP request all in one solution React Query Hooks for fetching, caching and u ...
- ES6 arrow function vs ES5 function
ES6 arrow function vs ES5 function ES6 arrow function 与 ES5 function 区别 this refs xgqfrms 2012-2020 ...
- React Hooks 内部实现原理
React Hooks 内部实现原理 源码分析 // 链表 React Hooks 原理剖析 refs https://reactjs.org/docs/hooks-intro.html https: ...
- Web 网站安全测试 & 渗透测试
Web 网站安全测试 & 渗透测试 Penetration Testing learning path 建一个测试环境来进行渗透测试 安装 Kali Linux -渗透测试操作系统 在虚拟机中 ...
- Node.js Learning Paths
Node.js Learning Paths Node.js in Action Node.js Expert situations / scenario Restful API OAuth 2.0 ...
- js online playground & web editor
js online playground & web editor -javascript playgrounds 2019 https://scotch.io/tutorials/7-jav ...
- Flutter: provider 使用小部件的小部件构建的依赖注入系统
文档 dependencies: provider: import 'package:dart_printf/dart_printf.dart'; import 'package:flutter/ma ...