Mybatis之旅第五篇-動態SQL

1、引言

在以前的CRUD例子中,都是一些很簡單的SQL,然而實際的業務開發中會有一些複雜的SQL,咱們常常須要拼接SQL,拼接的時候要確保不能忘了必要的空格,還要注意省掉列名列表最後的逗號。Mybatis個一個強大特性--動態SQL,這一特性能夠完全擺脫這種痛苦。html

2、if標籤

如今有以下查詢:spring

<!-- 根據條件查詢用戶 -->
    <select id="queryUserByWhere" parameterType="user" resultType="user"> SELECT id, username, birthday, sex, address FROM `user` WHERE sex = #{sex} AND username LIKE '%${username}%' </select>

當咱們帶入兩個參數時,返回結果不會有問題,但是當咱們只帶入姓名,不帶入性別時,結果就不合理,由於sex帶入的null,做爲查詢條件就過濾告終果,這個時候咱們須要if標籤。sql

改造sql:數組

<!-- 根據條件查詢用戶 -->
<select id="queryUserByWhere" parameterType="user" resultType="user"> SELECT id, username, birthday, sex, address FROM `user` WHERE 1=1 <if test="sex!=null and sex !=''"> AND sex = #{sex} </if>
   <if test="username!=null and username!=''"> AND username like '%${username}%' </if>
</select>

將接口和方法都加入其中mybatis

@Test public void testQueryUserByWhere() { // mybatis和spring整合,整合以後,交給spring管理
    SqlSession sqlSession = this.sqlSessionFactory.openSession(); // 建立Mapper接口的動態代理對象,整合以後,交給spring管理
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class); // 使用userMapper執行根據條件查詢用戶
    User user = new User(); //user.setSex("1");
    user.setUsername("張"); List<User>list = userMapper.queryUserByWhere(user); for (User u : list) { System.out.println(u); } // mybatis和spring整合,整合以後,交給spring管理
 sqlSession.close(); }

結果:app

3、where 標籤

where標籤會把第一個and忽略,固然若是是or開頭的,MyBatis也會把它忽略,此外,在where元素中你不須要考慮空格的問題,MyBatis會智能的幫你加上。ide

<select id="queryUserByWhere1" parameterType="user" resultType="user"> SELECT id, username, birthday, sex, address FROM `user` <!-- where標籤能夠自動添加where,同時處理sql語句中第一個and或者or關鍵字 -->
    <where>
        <if test="sex!=null"> AND sex = #{sex} </if>
        <if test="username!=null and username!=''"> AND username like '%${username}%' </if>
    </where>
</select>

4、set 標籤

在更新的時候咱們也須要像where同樣可以進行動態判斷,這個時候就使用set標籤,set會使最後的逗號忽略,咱們就能夠動態的更新那些修改了的字段。測試

以下:this

<update id="dynamicSetTest" parameterType="user"> update `user` <set>
        <if test="sex != null"> sex = #{sex}, </if>
        <if test="username!=null and username!=''"> username = #{username}, </if>
    </set> where id = #{id} </update>

測試:spa

@Test public void dynamicSetTest() { SqlSession sqlSession = this.sqlSessionFactory.openSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = new User(); //user.setSex("1");
    user.setUsername("袁大大"); user.setId(26); userMapper.dynamicSetTest(user); sqlSession.commit(); sqlSession.close(); }

5、choose(when,otherwise) 標籤

choose的做用相似Java語言中的switch,能夠解決咱們只想選擇一個查詢條件的狀況。

以下:

<select id="selectUserByChoose" resultType="user" parameterType="user"> select id, username, birthday, sex, address FROM `user` <where>
            <choose>
                <when test="id !='' and id != null"> id=#{id} </when>
                <when test="username !='' and username != null"> and username like #{username} </when>
                <otherwise> and sex=#{sex} </otherwise>
            </choose>
        </where>
    </select>

這個寫法很容易理解,與switch相同,匹配成功後就會跳出。

6、trim 標籤

trim標記是一個格式化的標記,能夠完成set或者是where標記的功能,怎麼用呢:

增長prefix前綴,去掉第一個prefixoverride中內容。

增長suffix後綴,去掉最後一個suffixoverride中內容。

經過trim能夠解決where 與set 問題

<select id="selectUserByUsernameAndSex" resultType="user" parameterType="user"> select * from user <!-- <where> <if test="username != null"> username=#{username} </if> <if test="username != null"> and sex=#{sex} </if> </where> -->
    <trim prefix="where" prefixOverrides="and | or">
        <if test="username != null"> and username=#{username} </if>
        <if test="sex != null"> and sex=#{sex} </if>
    </trim>
</select>

先增長where,並去掉第一個and 或者or ,替換了where if 寫法。

<!-- 根據 id 更新 user 表的數據 -->
    <update id="updateUserById" parameterType="com.ys.po.User"> update user u <!-- <set> <if test="username != null and username != ''"> u.username = #{username}, </if> <if test="sex != null and sex != ''"> u.sex = #{sex} </if> </set> -->
            <trim prefix="set" suffixOverrides=",">
                <if test="username != null and username != ''"> u.username = #{username}, </if>
                <if test="sex != null and sex != ''"> u.sex = #{sex}, </if>
            </trim> where id=#{id} </update>

增長set,並去掉最後一個逗號,替換了set if寫法。

7、SQL片斷

寫sql時常常會出現一些重複片斷,咱們能夠進行提取,這樣能夠作到重用。

先使用sql進行聲明:

<!-- 聲明sql片斷 -->
<sql id="userFields"> id, username, birthday, sex, address </sql>

使用include refid

<select id="queryUserBySqlWhere" parameterType="user" resultType="user">
<!-- SELECT id, username, birthday, sex, address FROM `user` -->
<!-- 使用include標籤加載sql片斷;refid是sql片斷id --> SELECT <include refid ="userFields"/> FROM `user` <!-- where標籤能夠自動添加where關鍵字,同時處理sql語句中第一個and關鍵字 -->
<where>
    <if test="sex != null"> AND sex = #{sex} </if>
<if test="username != null and username != ''"> AND username LIKE '%${username}%' </if>
    </where>
</select>

8、foreach標籤

當咱們向sql傳遞數組或List,mybatis使用foreach解析。

  • foreach標籤,進行遍歷

  • collection:遍歷的集合,這裏是QueryVo的ids屬性

  • item:遍歷的項目,能夠隨便寫,,可是和後面的#{}裏面要一致

  • open:在前面添加的sql片斷

  • close:在結尾處添加的sql片斷

  • separator:指定遍歷的元素之間使用的分隔符

    <select id="queryUserByIds" parameterType="com.yuanqinnan.pojo.QueryVo" resultType="user"> SELECT * FROM `user` <where>
        <foreach collection="ids" item="item" open="id IN (" close=")" separator=","> #{item} </foreach>

    改造QueryVo:

    @Data public class QueryVo { private User user; private List<Integer> ids; }

    測試方法:

    @Test public void queryUserByIds(){ SqlSession sqlSession = this.sqlSessionFactory.openSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); QueryVo user = new QueryVo(); List<Integer>ids = new ArrayList<>(); ids.add(1); ids.add(10); ids.add(24); user.setIds(ids); List<User> list = userMapper.queryUserByIds(user); for (User u : list) { System.out.println(u); } sqlSession.close(); }

    結果

  • 動態sql實際上是一個拼接過程,咱們掌握上面這些標籤,就能完成mybatis的動態sql

原文出處:https://www.cnblogs.com/yuanqinnan/p/10712679.html

相關文章
相關標籤/搜索