動態SQL之、條件判斷
阿新 • • 發佈:2019-02-16
錯誤方式一:
在mybatis的動態sql語句中使用<if>
標籤可以判斷sql中的條件是否成立。
<select id="getPerson" resultType="com.lzj.bean.Employee">
select * from tbl_employee
where
<if test="id!=null">
id=#{id}
</if>
<if test="lastName!=null and lastName!=''" >
and last_name like #{lastName}
</if>
<if test="email!=null and email.trim()!=''">
and email=#{email}
</if>
<if test="gender==0 or gender==1">
and gender=#{gender}
</if >
</select>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
在上面的動態sql語句中存在一個問題,當第一條sql判斷語句
<if test="id!=null">
id=#{id}
</if>
- 1
- 2
- 3
失敗時,即id值為null,而lastName、email和gender判斷成功後,最後sql語句就會變為: select * from tbl_employee where and last_name like #{lastName} and email=#{email} and gender=#{gender}
where後面多一個and,執行sql時會失敗。
改正方式一:
在where條件後面加了一條判斷1=1,然後在id的判斷後加上and關鍵字,這樣當下面if條件中的任何一個判斷失敗後,都不會影響整個sql語句。
<select id="getPerson" resultType="com.lzj.bean.Employee">
select * from tbl_employee
where 1=1
<if test="id!=null">
and id=#{id}
</if>
<if test="lastName!=null and lastName!=''">
and last_name like #{lastName}
</if>
<if test="email!=null and email.trim()!=''">
and email=#{email}
</if>
<if test="gender==0 or gender==1">
and gender=#{gender}
</if>
</select>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
錯誤方式二:
有些人習慣在每個if判斷中的資料庫欄位的後面加and關鍵字,例如
<select id="getPerson" resultType="com.lzj.bean.Employee">
select * from tbl_employee
where
<if test="id!=null">
id=#{id} and
</if>
<if test="lastName!=null and lastName!=''">
last_name like #{lastName} and
</if>
<if test="email!=null and email.trim()!=''">
email=#{email} and
</if>
<if test="gender==0 or gender==1">
gender=#{gender}
</if>
</select>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
但是上述情況存在一個弊端,當最後一個if判斷gender失敗時,sql語句就變成了: select * from tbl_employee where id=#{id} and last_name like #{lastName} and email=#{email} and
where條件的最後多一個and,sql語句執行的時候也會失敗。
改正方式二:
在最後一個if語句中庫表字段後加and關鍵字,然後在最後加1=1判斷
<select id="getPerson" resultType="com.lzj.bean.Employee">
select * from tbl_employee
where
<if test="id!=null">
id=#{id} and
</if>
<if test="lastName!=null and lastName!=''">
last_name like #{lastName} and
</if>
<if test="email!=null and email.trim()!=''">
email=#{email} and
</if>
<if test="gender==0 or gender==1">
gender=#{gender} and
</if>
1=1
</select>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
建議方式:
用<where>
和<if>
進行組合,當條件不成立時,if條件後的內容包括and也不會存在,因此不會對整個sql語句產生影響。注意and關鍵字要放在每個<if>
語句中的庫表字段賦值的前面。因為,一旦判斷不成功,<where>
會把對應的and關鍵字去掉(還有or關鍵字)。
<select id="getPerson" resultType="com.lzj.bean.Employee">
select * from tbl_employee
<where>
<!-- test:判斷表示式(OGNL)
遇見特殊符號應該去寫轉義字元:&&、''等字元
-->
<if test="id!=null">
id=#{id}
</if>
<if test="lastName!=null and lastName!=''">
and last_name like #{lastName}
</if>
<if test="email!=null and email.trim()!=''">
and email=#{email}
</if>
<!-- ognl會進行字串與數字的轉換判斷 "0"==0 -->
<if test="gender==0 or gender==1">
and gender=#{gender}
</if>
</where>
</select>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
上述很多特殊字元可以寫成轉義的形式,例如
- 1
<select id="getEmpsByConditionIf" resultType="com.atguigu.mybatis.bean.Employee">
select * from tbl_employee
<!-- where -->
<where>
<if test="id!=null">
id=#{id}
</if>
<if test="lastName!=null && lastName!=""">
and last_name like #{lastName}
</if>
<if test="email!=null and email.trim()!=""">
and email=#{email}
</if>
<if test="gender==0 or gender==1">
and gender=#{gender}
</if>
</where>
</select>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
注意,`<if>`失敗後, `<where>` 關鍵字只會去掉庫表字段賦值前面的and,不會去掉後面的and關鍵字,即注意,`<where>` 只會去掉`<if>` 語句中的最開始的and關鍵字。所以下面的形式是不可取的
- 1
- 2
<select id="getPerson" resultType="com.lzj.bean.Employee">
select * from tbl_employee
<where>
<if test="id!=null">
id=#{id} and
</if>
<if test="lastName!=null and lastName!=''">
last_name like #{lastName} and
</if>
<if test="email!=null and email.trim()!=''">
email=#{email} and
</if>
<if test="gender==0 or gender==1">
gender=#{gender}
</if>
</where>
</select>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
``
因為,失敗後,
`不會自動去掉後面的and關鍵字,這種形式與錯誤方式二種原理相同。