自己挖的坑自己填--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>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章