自己挖的坑自己填--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加一标识符做个判断,传一个只有我会使用的参数,然后动态 ...
随机推荐
- Kubernets二进制安装(13)之部署Flannel
Flannel简介 Flannel是CoreDNS团队针对Kubernetes设计的一个网络规划服务,简单来说,它的功能是让集群中的不同节点主机创建的Docker容器都具有全集群唯一的虚拟IP地址 ...
- windows cmd 查看远程连接端口
查看远程端口号 Cmd tasklist /svc 在输出的内容中查找svchost.exe进程下termservice服务对应的PID,在此查看的PID为:276 然后输入命令:netstat ...
- codeforces 1016C - Vasya And The Mushrooms 【构造 + 思维】
题目链接:戳这里 题意:从(1,1)出发,一遍把格子走完,每个格子只能走一次.问怎么走总和最大. 解题思路:画图可知,总共就3种走法的混合. dw: 样例1的走法 up: 样例1反过来的走法 lp: ...
- 智能社讲解js基础
一,Javascript的组成ECMAScript:翻译,核心,解释器,DOM:文档对象模型,Document Object Model 操作HTML的能力,document对象BOM:浏览器对象模型 ...
- Leetcode(32)-最长有效括号
给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度. 示例 1: 输入: "(()" 输出: 2 解释: 最长有效括号子串为 "()&quo ...
- 手工数据结构系列-C语言模拟队列 hdu1276
#include <stdio.h> #include <stdlib.h> #define init_size 1000 typedef struct { int head, ...
- 『数据结构与算法』二叉查找树(BST)
微信搜索:码农StayUp 主页地址:https://gozhuyinglong.github.io 源码分享:https://github.com/gozhuyinglong/blog-demos ...
- Python对excel的基本操作
Python对excel的基本操作 目录 1. 前言 2. 实验环境 3. 基本操作 3.1 安装openpyxl第三方库 3.2 新建工作簿 3.2.1 新创建工作簿 3.2.2 缺省工作表 3.2 ...
- C++ Primer笔记
C++ Primer笔记 ch2 变量和基本类型 声明 extern int i; extern int i = 3.14;//定义 左值引用(绑定零一变量初始值,别名) 不能定义引用的引用:引用必须 ...
- CSS 检测 IE 浏览器
CSS 检测 IE 浏览器 <!--[if IE]> <link href="ie.css" rel="stylesheet"> < ...