mybatis中的動態SQL

在實際開發中,數據庫的查詢很難一蹴而就,咱們每每要根據各類不一樣的場景拼接出不一樣的SQL語句,這無疑是一項複雜的工做,咱們在使用mybatis時,mybatis給咱們提供了動態SQL,可讓咱們根據具體的業務邏輯來拼接不一樣的SQL語句。OK,那麼咱們今天就來看看如何使用mybatis中的動態SQL。
mybatis中的動態SQL主要包含以下幾種元素:if、choose、when、otherwise、trim、where、set以及foreach幾種,咱們下面分別來看看這幾種。git

if

if是mybatis動態SQL中的判斷元素,這個有點相似於Java中的if語句,不一樣的是這裏的if通常經常和test配合使用。咱們來看一個簡單的例子:github

<select id="getUser" resultMap="u" parameterType="String">
        select * from user2
        <if test="address!=null and address !=''">
            WHERE address LIKE concat('%',#{address},'%')
        </if>
    </select>

當用戶傳入的address不爲null或者空字符串的時候,我就加上一個where條件,不然就什麼條件都不加入。而後咱們再來看看咱們在UserMapper這個接口中定義的相關方法:sql

public List<User> getUser(@Param("address") String address);

咱們在調用這個方法的時候,若是傳入了address參數,那麼查詢條件中就有address,不然就沒有。來看看測試代碼:數據庫

SqlSession sqlSession = null;
        try {
            sqlSession = DBUtils.openSqlSession();
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            List<User> list = mapper.getUser("西安");
            for (User user : list) {
                System.out.println(user);
            }
            sqlSession.commit();
        } catch (Exception e) {
            System.err.println(e.getMessage());
            sqlSession.rollback();
        } finally {
            if (sqlSession != null) {
                sqlSession.close();
            }
        }

查詢結果:
這裏寫圖片描述
若是我將查詢條件設爲空字符串,以下:markdown

SqlSession sqlSession = null;
        try {
            sqlSession = DBUtils.openSqlSession();
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            List<User> list = mapper.getUser("");
            for (User user : list) {
                System.out.println(user);
            }
            sqlSession.commit();
        } catch (Exception e) {
            System.err.println(e.getMessage());
            sqlSession.rollback();
        } finally {
            if (sqlSession != null) {
                sqlSession.close();
            }
        }

這裏寫圖片描述

小夥伴們注意兩個查詢結果截圖中打印出來的SQL語句的差別。mybatis

choose

choose有點相似於Java中的switch,經常配合when和otherwise一塊兒來使用。咱們來看一個簡單的例子:app

<select id="getUser2" resultMap="u">
        SELECT * FROM user2 WHERE 1=1
        <choose>
            <when test="id!=null">
                AND id=#{id}
            </when>
            <when test="address!=null">
                AND address=#{address}
            </when>
            <when test="username!=null">
                AND user_name LIKE concat(#{username},'%')
            </when>
            <otherwise>
                AND 10>id
            </otherwise>
        </choose>
    </select>

在查詢條件中,若是用戶傳來了id,那麼我就查詢該id的數據,若是用戶傳來了address,那麼我就咱們添加address的查詢條件,若是用戶傳來了username,那麼我就添加username的查詢條件,最後若是用戶任何一個查詢條件都沒有添加進來,那麼默認查詢條件就是查詢id小於10的全部數據。ide

where

在上面的案例中小夥伴們可能都發現了一個問題,就是咱們在添加查詢條件的時候,在查詢條件以前都先添加了where 1=1,而後後面直接在這以後再追加and什麼什麼的,那麼每次這樣來寫顯然有點麻煩,有沒有簡單一點的方案呢?固然有,咱們能夠經過where元素,以下:測試

<select id="getUser3" resultMap="u">
        SELECT * FROM user2
        <where>
            <choose>
                <when test="id!=null">
                    AND id=#{id}
                </when>
                <when test="address!=null">
                    AND address=#{address}
                </when>
                <when test="username!=null">
                    AND user_name LIKE concat(#{username},'%')
                </when>
                <otherwise>
                    AND 10>id
                </otherwise>
            </choose>
        </where>
    </select>

這樣,只有where元素中有條件成立,纔會將where關鍵字組裝到SQL中,這樣就比前一種方式簡單許多。ui

trim

trim有點元素替換的意思,仍是上面的案例,咱們能夠將and替換爲where,以下:

<select id="getUser4" resultMap="u">
        SELECT * FROM user2
        <trim prefix="where" prefixOverrides="and">
            AND id=1
        </trim>
    </select>

這個最終執行的sql是SELECT * FROM user2 where id=1

set

set是咱們在更新表的時候使用的元素,經過set元素,咱們能夠逐字段的修改一條數據,以下:

<update id="update">
        UPDATE user2
        <set>
            <if test="username!=null">
                user_name=#{username},
            </if>
            <if test="password!=null">
                password=#{password}
            </if>
        </set>
        WHERE id=#{id}
    </update>

在set元素中,若是遇到了逗號,系統會自動將之去除。

foreach

foreach元素用來遍歷集合,好比我想查詢多個城市的人,個人sql語句多是這樣SELECT * FROM user2
WHERE address IN('西安','北京')
,我在查詢的時候可能只是傳入了一個list集合,該集合中有西安和北京兩個查詢條件,那我如何將這個集合組裝成一個sql語句呢?很簡單,以下:

<select id="getUserInCities" resultMap="u">
        SELECT * FROM user2
        WHERE address IN
        <foreach collection="cities" index="city" open="(" separator="," close=")" item="city">
            #{city}
        </foreach>
    </select>

collection表示傳入的參數中集合的名稱,index表示是當前元素在集合中的下標,open和close則表示如何將集合中的數據包裝起來,separator表示分隔符,item則表示循環時的當前元素。這樣一段配置最終組合成的sql就是SELECT * FROM user2
WHERE address IN('西安','北京')

bind

使用bind元素咱們能夠預先定義一些變量,而後在查詢語句中使用,以下:

<select id="getUserByName" resultMap="u">
        <bind name="un" value="username+'%'"></bind>
            SELECT* FROM user2 WHERE user_name LIKE #{un}

    </select>

這個貌似沒什麼難度,再也不贅述。

以上。

本文案例下載:
本文案例GitHub地址https://github.com/lenve/JavaEETest/tree/master/Test27-mybatis9

以上。

參考資料: 《深刻淺出MyBatis 技術原理與實戰》第五章

相關文章
相關標籤/搜索