1. 程式人生 > 其它 >ssm-mybatis進階之動態sql

ssm-mybatis進階之動態sql

ssm-mybatis進階之動態sql

動態 SQL 是 MyBatis 的強大特性之一。如果你使用過 JDBC 或其它類似的框架,你應該能理解根據不同條件拼接 SQL 語句有多痛苦, 例如拼接時要確保不能忘記新增必要的空格,還要注意去掉列表最後一個列名的逗號。利用動態 SQL,可以徹底擺脫這種痛苦。MyBatis 動態 SQL 主要通過在mapper對映檔案中,使用類似於JSTL語言進行編寫。

動態SQL元素

MyBatis 3 之後,元素已經大大精簡,主要有以下幾種:
  • if
  • choose (when, otherwise)
  • trim (where, set)
  • foreach

if

使用動態 SQL 最常見情景是根據條件包含 where 子句的一部分,下面舉例說明:
  1. 編寫dao:
  2. List<Student> getStudents(@Param("sex") String sex, @Param("pageIndex") int pageIndex, @Param("pageSize") int pageSize);
  3. 編寫mapper對映檔案:

  4. 語法:<if test="條件表示式">拼接sql語句</if>
  5. 編寫測試方法驗證:
  6. @Test
    public void getStudents() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        //不篩選性別,也不分頁
        List<Student> students = mapper.getStudents("", 0, 0);
        Object jsonStr = JSON.toJSON(students);
        System.out.println(jsonStr);
        sqlSession.close();
    }
    不篩選性別,也不分頁,結果如下:


    修改測試方法,篩選性比也分頁,驗證如下:
    List<Student> students = mapper.getStudents("男", 0, 2);

choose (when, otherwise)

有時候,我們不想使用所有的條件,而只是想從多個條件中選擇一個使用,Mybatis 又沒提供 else 。 針對這種情況,MyBatis 提供了 choose 元素,它有點像 Java 中的 switch 語句。
  1. 編寫dao:
  2. List<Student> getStudents2(@Param("sex") String sex, @Param("name") String name);
  3. 編寫mapper對映檔案:

  4. 重點:要注意like語句的拼接方式
    語法:
    <choose>
        <when test="條件表示式1">
            拼接SQL1
        </when>
        <when test="條件表示式2">
            拼接SQL2
        </when>
        ...
        <otherwise>
            拼接預設SQL
        </otherwise>
    </choose>
    
  5. 編寫測試方法驗證:
  6. @Test
    public void getStudents2() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        //只執行性別篩選
        List<Student> students = mapper.getStudents2("男", "");
        Object jsonStr = JSON.toJSON(students);
        System.out.println("[1]:" + jsonStr);
        //只執行姓名篩選
        students = mapper.getStudents2("", "張");
        jsonStr = JSON.toJSON(students);
        System.out.println("[2]:" + jsonStr);
        //引數都傳遞,但只會按順尋執行第一個篩選
        students = mapper.getStudents2("女", "張");
        jsonStr = JSON.toJSON(students);
        System.out.println("[3]:" + jsonStr);
        //一個都不傳,預設返回第一個
        students = mapper.getStudents2("", "");
        jsonStr = JSON.toJSON(students);
        System.out.println("[4]:" + jsonStr);
        sqlSession.close();
    }

trim (where, set)

trim主要為了解決多條語句拼接時,冗餘關鍵字、符號問題,MyBatis 已經提取了常用的去冗元素:<where>,<set>。 其中<where>標籤主要解決拼接篩選過程中去除多餘的AND和OR,<set>則解決賦值過程中多餘的逗號問題。 下面就用<where>來舉例說明(<set>類似)
  1. 編寫dao:
  2. List<Student> getStudents3(@Param("sex") String sex, @Param("name") String name);
  3. 編寫mapper對映檔案:

  4. 編寫測試方法驗證:
  5. @Test
    public void getStudents3() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        //只執行性別篩選
        List<Student> students = mapper.getStudents3("男", "");
        Object jsonStr = JSON.toJSON(students);
        System.out.println("[1]:" + jsonStr);
        //只執行姓名篩選
        students = mapper.getStudents3("", "張");
        jsonStr = JSON.toJSON(students);
        System.out.println("[2]:" + jsonStr);
        //引數都傳遞,都會篩選
        students = mapper.getStudents3("女", "李");
        jsonStr = JSON.toJSON(students);
        System.out.println("[3]:" + jsonStr);
        //一個都不傳,返回所有
        students = mapper.getStudents3("", "");
        jsonStr = JSON.toJSON(students);
        System.out.println("[4]:" + jsonStr);
        sqlSession.close();
    }

foreach

動態 SQL 的另一個常見使用場景是對集合進行遍歷(尤其是在構建 IN 條件語句的時候)。
  1. 編寫dao:
  2. List<Student> getStudentsForeach(@Param("sex") String sex, @Param("ids") int[] ids);
  3. 編寫mapper對映檔案:

  4. collection 可以是 list, set, array, map。map 時 index 為 key , item 為值。
  5. 編寫測試方法驗證:
  6. @Test
    public void getStudentsForeach() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        int[] ids = new int[]{1, 2, 3};
        List<Student> students = mapper.getStudentsForeach("男", ids);
        Object jsonStr = JSON.toJSON(students);
        System.out.println(jsonStr);
        sqlSession.close();
    }