如下是 MyBatis 的映射文件合冀。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zm.dao.CourseMapper">
<!--
多條件課程列表查詢
-->
<select id="findCourseByCondition" parameterType="courseVo" resultType="course">
select * from course
<where>
<if test="courseName != null and courseName != ''">
and course_name like concat('%', #{courseName}, '%')
</if>
<if test="`status` != null and `status` != ''">
and `status` = #{status}
</if>
<if test="true">
and is_del != 1
</if>
</where>
</select>
</mapper>
啟動了 Tomcat 服務(wù)器赖条,使用 Postman 進(jìn)行測試底哗,使用了 log4j 輸出 MyBatis 相關(guān)的 log。
當(dāng) status 為 1 時隧枫,無論有沒有為 status 加反單引號喉磁,輸出結(jié)果都是正確的:
02:02:18,119 DEBUG SpringManagedTransaction:87 - JDBC Connection [com.mysql.jdbc.JDBC4Connection@5fd1a13d] will not be managed by Spring
02:02:18,131 DEBUG findCourseByCondition:143 - ==> Preparing: select * from course WHERE course_name like concat('%', ?, '%') and `status` = ? and is_del != 1
02:02:18,176 DEBUG findCourseByCondition:143 - ==> Parameters: Vue.js 3.0 核心源碼解析(String), 1(Integer)
02:02:18,233 DEBUG findCourseByCondition:143 - <== Total: 2
當(dāng) status 為 0 時,如果 <if test> 的 status 沒有加反單引號官脓,即便里面的 status 加了反單引號协怒,輸出結(jié)果是錯誤的:
<if test="status != null and status != ''">
and `status` = #{status}
</if>
02:06:47,190 DEBUG SpringManagedTransaction:87 - JDBC Connection [com.mysql.jdbc.JDBC4Connection@7d4a78] will not be managed by Spring
02:06:47,202 DEBUG findCourseByCondition:143 - ==> Preparing: select * from course WHERE course_name like concat('%', ?, '%') and is_del != 1
02:06:47,246 DEBUG findCourseByCondition:143 - ==> Parameters: Vue.js 3.0 核心源碼解析(String)
02:06:47,282 DEBUG findCourseByCondition:143 - <== Total: 2
可以看到這時候的 <if test> 執(zhí)行并沒有通過,導(dǎo)致少追加了 status 的判斷卑笨。
只有在 <if test> 的 status 加上反單引號孕暇,執(zhí)行結(jié)果才是正確的:
<if test="`status` != null and `status` != ''">
and `status` = #{status}
</if>
02:11:24,352 DEBUG SpringManagedTransaction:87 - JDBC Connection [com.mysql.jdbc.JDBC4Connection@713af06d] will not be managed by Spring
02:11:24,365 DEBUG findCourseByCondition:143 - ==> Preparing: select * from course WHERE course_name like concat('%', ?, '%') and `status` = ? and is_del != 1
02:11:24,408 DEBUG findCourseByCondition:143 - ==> Parameters: Vue.js 3.0 核心源碼解析(String), 0(Integer)
02:11:24,435 DEBUG findCourseByCondition:143 - <== Total: 0
整數(shù)類型的 isFree 也會出現(xiàn)這個問題,加上反單引號:
<if test="`isFree` != null and `isFree` != ''">
is_free = #{isFree},
</if>
由此可以推測出:整數(shù)類型轉(zhuǎn)字符串類型后湾趾,0 代表空字符串的意思芭商,加上反單引號可以把整數(shù)類型的 0 直接轉(zhuǎn)為 字符 0派草。
同樣道理搀缠,status 是整數(shù)類型,當(dāng)它為 0 時近迁,進(jìn)行字符串轉(zhuǎn)型會把它轉(zhuǎn)為 null艺普;加上反單引號就不會出錯了。
但是加上反單引號卻有另外一個問題鉴竭,就是當(dāng) status 為 Integer 類型時歧譬, status 可以為 null,這時候使用反單引號進(jìn)行整數(shù)類型轉(zhuǎn)字符串類型會把 null 本身轉(zhuǎn)為字符串 "null"搏存,從而導(dǎo)致判斷出錯瑰步。
所以,當(dāng) status 為 Integer 且可能為 null 時璧眠,最好是用以下方式解決:
<if test="status != null and status != '' or status == 0">
and `status` = #{status}
</if>