自己挖的坑自己填--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加一标识符做个判断,传一个只有我会使用的参数,然后动态 ...
随机推荐
- 如何自己绘制fcitx4输入法皮肤?
先来给大家看看我自己修改后的结果 当然你可以自己设计,自己定义喜欢的颜色和样式 但是注意,这个教程仅仅针对使用fcitx皮肤面板的输入法,例如rime.sunpinyin等. 搜狗输入法.讯飞输入法. ...
- js arrow function return object
js arrow function return object bug filterData: { type: Object, default: () => {}, required: true ...
- MDN & JavaScript 文档翻译状态
MDN & JavaScript 文档翻译状态 https://developer.mozilla.org/zh-CN/docs/MDN/Doc_status/JavaScript refs ...
- SVG & convert polygon/polyline to path
SVG & convert polygon/polyline to path SVG Polygon/Polyline to Path Converter https://codepen.io ...
- js 的 ArrayBuffer 和 dataView
arrayBuffer文档 一个十六进制代表4位,0xF = 1111,0xFF = 1111 1111,八位是1字节,所以通常用两个16进制代表1字节. 假如我申请一个8字节的内存空间,然后初始化为 ...
- Flutter: 设置简单的启动屏
更多代码参考 有短暂的白屏时间 import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter ...
- 同样是NGK官方推出的代币,SPC与BGV有何异同?
近日,币圈又火热了起来,而这次火热是由NGK搅动的.原来,NGK官方空投了200万枚SPC,用于奖励NGK算力持有者.当前,已经有一部分算力持有者获得了SPC奖励,有的算力持有者获得的SPC数量惊人, ...
- 两百万SPC空投来袭,带动市场热情!
NGK投放项目的时间节点总是以牛市为主,像是上一次的BGV项目投放就在2020年末的数字加密货币牛市,其结果想必各位生态建设者们都已经见到了,在登陆交易所首日便高收于近889美金,创下惊人的近一千七百 ...
- mysql一张表到底能存多少数据?
前言 程序员平时和mysql打交道一定不少,可以说每天都有接触到,但是mysql一张表到底能存多少数据呢?计算根据是什么呢?接下来咱们逐一探讨 知识准备 数据页 在操作系统中,我们知道为了跟磁盘交互, ...
- MVVM中的vm双向监听和mvc的缺点
`MVVM`模型: - 即Model,模型,包括数据和一些基本操作 - 即View,视图,页面渲染结果- 即View-Model,模型与视图间的双向操作(无需开发人员干涉) `MVVM`中的`VM`要 ...