MyBatis 動態 SQL(基礎篇)

以學生表student爲例:java

id name age score
1 zhangsan 11 60
2 lisi 22 60
3 wangwu 33 90
4 zhaoliu 14 59

if 標籤

定義映射文件

<?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 標籤

<!-- 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 標籤

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

foreach 標籤-遍歷數組

注意:動態 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 的學生信息。

foreach 標籤-遍歷集合

注:遍歷集合的方式與遍歷數組的方式相同,只不過是將 array 替換成了 list

1. 歷泛型爲基本類型的 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>

2. 遍歷泛型爲自定義類型的 List

定義接口

/**
 * 使用 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 標籤複用。而其它標籤使用該 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>

相關文章
相關標籤/搜索