以學生表student
爲例:java
id | name | age | score |
---|---|---|---|
1 | zhangsan | 11 | 60 |
2 | lisi | 22 | 60 |
3 | wangwu | 33 | 90 |
4 | zhaoliu | 14 | 59 |
<?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.lusifer.mybatis.dao.DynamicStudentDao"> <!-- if --> <select id="selectByIf" resultType="com.lusifer.mybatis.entity.Student"> SELECT id, name, age, score FROM student WHERE 1 = 1 <if test="name != null and name != ''"> AND name LIKE concat('%', #{name}, '%') </if> <if test="age != null and age > 0"> AND age > #{age} </if> </select> </mapper>
說明:sql
爲了解決兩個條件均未作設定的狀況,在 where
後添加了一個「1=1」
的條件。這樣就不至於兩個條件均未設定而出現只剩下一個 where,而沒有任何可拼接的條件的不完整 SQL 語句。數組
<!-- where--> <select id="selectByWhere" resultType="com.lusifer.mybatis.entity.Student"> SELECT id, name, age, score FROM student <where> <if test="name != null and name != ''"> AND name LIKE concat('%', #{name}, '%') </if> <if test="age != null and age > 0"> AND age > #{age} </if> </where> </select>
說明:mybatis
<if/>
標籤的中存在一個比較麻煩的地方:須要在 where
後手工添加 1=1
的子句。由於,若 where
後的全部 <if/>
條件均爲 false,而where
後若又沒有 1=1
子句,則 SQL 中就會只剩下一個空的 where
,SQL 出錯。因此,在 where
後,須要添加永爲真子句1=1
,以防止這種狀況的發生。但當數據量很大時,會嚴重影響查詢效率。可是<where>
語句則避免這一麻煩的發生。app
<!-- choose --> <select id="selectByChoose" resultType="com.lusifer.mybatis.entity.Student"> SELECT id, name, age, score FROM student <where> <choose> <when test="name != null and name != ''"> AND name LIKE concat('%', #{name}, '%') </when> <when test="age != null and age > 0"> AND age > #{age} </when> <otherwise> AND 1 != 1 </otherwise> </choose> </where> </select>
說明:spa
該標籤中只能夠包含 <when/>
<otherwise/>
,能夠包含多個 <when/>
與一個 <otherwise/>
。它們聯合使用,完成 Java 中的開關語句 switch
..case
功能。3d
本例要完成的需求是,若姓名不空,則按照姓名查詢;若姓名爲空,則按照年齡查詢;若沒有查詢條件,則沒有查詢結果。code
注意:動態 SQL 的判斷中使用的都是 OGNL 表達式。OGNL 表達式中的數組使用 array
表示,數組長度使用 array.length
表示。xml
<!-- foreach --> <select id="selectByForeach" resultType="com.lusifer.mybatis.entity.Student"> <!-- select * from student where id in (2, 4) --> SELECT id, name, age, score FROM student <if test="array != null and array.length > 0"> WHERE id IN <foreach collection="array" open="(" close=")" item="id" separator=","> #{id} </foreach> </if> </select>
說明:blog
<foreach/>
標籤用於實現對於數組與集合的遍歷。對其使用,須要注意:
collection 表示要遍歷的集合類型,這裏是數組,即 array。
open、close、separator 爲對遍歷內容的 SQL 拼接。
本例實現的需求是,查詢出 id 爲 2 與 4 的學生信息。
注:遍歷集合的方式與遍歷數組的方式相同,只不過是將 array 替換成了 list
定義接口
/** * 使用 foreach 標籤以 list 基本類型的形式查詢 * @param ids * @return */ public List<Student> selectByForeachWithListBase(List<Long> ids);
SQL
<!-- foreach --> <select id="selectByForeachWithListBase" resultType="com.lusifer.mybatis.entity.Student"> <!-- select * from student where id in (2, 4) --> SELECT id, name, age, score FROM student <if test="list != null and list.size > 0"> WHERE id IN <foreach collection="list" open="(" close=")" item="id" separator=","> #{id} </foreach> </if> </select>
定義接口
/** * 使用 foreach 標籤以 list 自定義類型的形式查詢 * @param students * @return */ public List<Student> selectByForeachWithListCustom(List<Student> students);
SQL
<!-- foreach --> <select id="selectByForeachWithListCustom" resultType="com.lusifer.mybatis.entity.Student"> <!-- select * from student where id in (2, 4) --> SELECT id, name, age, score FROM student <if test="list != null and list.size > 0"> WHERE id IN <foreach collection="list" open="(" close=")" item="student" separator=","> #{student.id} </foreach> </if> </select>
<sql/>
標籤用於定義 SQL 片段,以便其它 SQL 標籤複用。而其它標籤使用該 SQL 片段, 須要使用 <include/>
子標籤。該 <sql/> 標籤能夠定義 SQL 語句中的任何部分,因此 <include/>
子標籤能夠放在動態 SQL 的任何位置。
<sql id="select"> SELECT id, name, age, score FROM student </sql>
<!-- foreach --> <select id="selectByForeachWithListCustom" resultType="com.lusifer.mybatis.entity.Student"> <!-- select * from student where id in (2, 4) --> <include refid="select" /> <if test="list != null and list.size > 0"> WHERE id IN <foreach collection="list" open="(" close=")" item="student" separator=","> #{student.id} </foreach> </if> </select>