• 自己挖的坑自己填--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)第二种情况有多种解决办法:

      I.需要将单引号和双引号调换即可。

        <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>

       II.添加toString() 进行类型转换

        <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'.toString()">
                name = #{name,jdbcType=VARCHAR}
            </if>
        </select>

       III.添加转义实体字符串引号

        <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 != &quot;a&quot;">
                name = #{name,jdbcType=VARCHAR}
            </if>
        </select>
    作者:huangrenhui
    欢迎任何形式的转载,但请务必注明出处。
    如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】。
    如果,您希望更容易地发现我的新博客,不妨点击一下左下角的【关注我】。
    如果,您对我的博客所讲述的内容有兴趣,请继续关注我的后续博客,我是【码猿手】。
    限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。
  • 相关阅读:
    连接心跳问题
    超时时间已到
    CSS定位属性-position
    AJAX背景技术介绍
    mysql中length字符长度函数使用方法
    mysql常用函数
    php构造函数的继承方法
    属性选择器(通常用在input)
    input标签常用属性
    PHP程序如何debug?
  • 原文地址:https://www.cnblogs.com/huangrenhui/p/14521248.html
Copyright © 2020-2023  润新知