自己挖的坑自己填--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加一标识符做个判断,传一个只有我会使用的参数,然后动态 ...
随机推荐
- Django用户注册、登录
一.用户注册 1 ''' 2 注册的表单模型 3 forms.py 的例子 4 ''' 5 6 from django import forms #表单功能 7 from django.contrib ...
- linux多线程模拟银行家算法
题外话: 这应该是最近有点难度的作业了,起码比之前的理发师,读写,哲学家问题要难. 但是做好程序的结构,自顶向下,就还是不难的. 银行家算法简介: 代码: init() ...
- codeforces - 978D【思维】
D. Almost Arithmetic Progression time limit per test 1 second memory limit per test 256 megabytes in ...
- redis运维与开发笔记
- CSS 解决Float后塌陷问题
当父级元素没有设定高度时候,而子集元素设定float类型时候,此时父级元素不能靠子集元素撑起来,所以就形成了塌陷: 示例分析 **1.Float之前的效果** <!DOCTYPE html> ...
- js screen size check
js screen size check js 屏幕尺寸检测 window.screen API screen; window.screen.width; window.screen.height; ...
- CSS Grid & Flex poster PDF 海报定制
CSS Grid & Flex poster PDF 海报定制 CSS 手工实现 导出 SVG / PNG 导出 PDF 打印,定制海报 refs https://css-tricks.com ...
- Web 前端如何优雅的处理海量数据
Web 前端如何优雅的处理海量数据 Q: 如何在 Web 页面上处理上亿条后端返回的数据,并且保证 UI 展示的流畅性 A: 思路: 时间分片, 批处理,Buffer 缓存,虚拟滚动,Web Work ...
- JavaScript 注释规范
JavaScript 注释规范 总原则 As short as possible(如无必要,勿增注释).尽量提高代码本身的清晰性.可读性. As long as necessary(如有必要,尽量详尽 ...
- iPhone 12 Pro 屏幕时间设置的密码锁出现弹窗 UI 错位重大 Bug
iPhone 12 Pro 屏幕时间设置的密码锁出现弹窗 UI 错位重大 Bug iOS 14.1 Bug 弹窗 UI 非常丑 弹窗屏占太高了 屏幕使用时间 https://support.apple ...