一、動態SQL
動態SQL,主要用於解決查詢條件不確定的情況:在程序運行期間,根據提交的查詢條件進行查詢。
動態SQL,即通過MyBatis提供的各種標簽對條件作出判斷以實現動態拼接SQL語句。
二、使用動態SQL原因
提供的查詢條件不同,執行的SQL語句不同。若將每種可能的情況均逐一列出,就將出現大量的SQL語句。
三、<if/>標簽
注意事項:
(1)

1 @Test 2 public void test08() { 3 Student stu = new Student("明", 20, 0); 4 List<Student> students = dao.selectStudentsByCondition(stu); 5 for (Student student : students) { 6 System.out.println(student); 7 } 8 9 }

1 public interface IStudentDao { 2 // 根據條件查詢問題 3 List<Student> selectStudentsByCondition(Student student); 4 }

1 <mapper namespace="com.jmu.dao.IStudentDao"> 2 <select id="selectStudentsByCondition" resultType="Student"> 3 select id,name,age,score 4 from student 5 where 6 <if test="name !=null and name !=''"> 7 name like '%' #{name} '%' 8 </if> 9 <if test="age>0"> 10 and age >#{age} 11 </if> 12 </select> 13 </mapper>
輸出:

0 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByCondition - ==> Preparing: select id,name,age,score from student where name like '%' ? '%' and age >? 48 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByCondition - ==> Parameters: 明(String), 20(Integer) 96 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByCondition - <== Total: 15 Student [id=159, name=明明, score=87.9, age=23] Student [id=173, name=小明明, score=99.5, age=23] Student [id=175, name=明明, score=99.5, age=23] Student [id=177, name=明明, score=99.5, age=23] Student [id=179, name=明明, score=99.5, age=23] Student [id=181, name=明明, score=99.5, age=23] Student [id=183, name=明明, score=99.5, age=23] Student [id=185, name=明明, score=99.5, age=23] Student [id=187, name=明明, score=99.5, age=23] Student [id=189, name=明明, score=99.5, age=23] Student [id=191, name=明明, score=99.5, age=23] Student [id=193, name=明明, score=99.5, age=23] Student [id=195, name=明明, score=99.5, age=23] Student [id=198, name=明明, score=99.5, age=23] Student [id=200, name=明明, score=99.5, age=23]
(2) 針對第一個值為空,sql語句“where and”出錯的情況
// Student stu = new Student("明", 20, 0); Student stu = new Student("", 20, 0);
解決:
四、<where/>標簽
當數據量特別大,做“where 1= 1”的判斷,就降低了整個系統的執行效率

1 @Test 2 public void test02() { 3 // Student stu = new Student("明", 20, 0); 4 Student stu = new Student("", 20, 0); 5 List<Student> students = dao.selectStudentsByWhere(stu); 6 for (Student student : students) { 7 System.out.println(student); 8 } 9 10 }

import java.util.List; import java.util.Map; import com.jmu.bean.Student; public interface IStudentDao { // 根據條件查詢問題 List<Student> selectStudentsByIf(Student student); List<Student> selectStudentsByWhere(Student student); }

1 <select id="selectStudentsByWhere" resultType="Student"> 2 select id,name,age,score 3 from student 4 <where> 5 <if test="name !=null and name !=''"> 6 and name like '%' #{name} '%' 7 </if> 8 <if test="age>0"> 9 and age >#{age} 10 </if> 11 </where> 12 </select>
輸出:

0 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByIf - ==> Preparing: select id,name,age,score from student where 1=1 and age >? 48 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByIf - ==> Parameters: 20(Integer) 86 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByIf - <== Total: 2 Student [id=198, name=明明, score=99.5, age=23] Student [id=200, name=明明, score=99.5, age=23] 111 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByWhere - ==> Preparing: select id,name,age,score from student WHERE age >? 111 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByWhere - ==> Preparing: select id,name,age,score from student WHERE age >? 111 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByWhere - ==> Parameters: 20(Integer) 111 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByWhere - ==> Parameters: 20(Integer) 115 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByWhere - <== Total: 2 115 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByWhere - <== Total: 2 Student [id=198, name=明明, score=99.5, age=23] Student [id=200, name=明明, score=99.5, age=23]
五、<choose/>標簽
該標簽可以包含多個<when/>和一個<otherwise/>,它們聯合使用來完成JAVA的開關語句switch...case功能。

1 <select id="selectStudentsByChoose" resultType="Student"> 2 select id,name,age,score 3 from student 4 <where> 5 <choose> 6 <when test="name !=null and name !=''"> 7 and name like '%' #{name} '%' 8 </when> 9 <when test="age>0"> 10 and age>#{age} 11 </when> 12 <otherwise> 13 1=2 <!-- false,使得查詢不到結果 --> 14 </otherwise> 15 </choose> 16 </where> 17 </select>

1 import java.util.List; 2 import java.util.Map; 3 4 import com.jmu.bean.Student; 5 6 public interface IStudentDao { 7 // 根據條件查詢問題 8 List<Student> selectStudentsByIf(Student student); 9 List<Student> selectStudentsByWhere(Student student); 10 List<Student> selectStudentsByChoose(Student student); 11 12 }

1 } 2 @Test 3 public void test03() { 4 // Student stu = new Student("明", 20, 0); 5 Student stu = new Student("", 20, 0); 6 // Student stu = new Student("", 0, 0); 7 List<Student> students = dao.selectStudentsByChoose(stu); 8 for (Student student : students) { 9 System.out.println(student); 10 } 11 12 }
輸出:

0 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByIf - ==> Preparing: select id,name,age,score from student where 1=1 and age >? 50 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByIf - ==> Parameters: 20(Integer) 86 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByIf - <== Total: 2 Student [id=198, name=明明, score=99.5, age=23] Student [id=200, name=明明, score=99.5, age=23] 104 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByWhere - ==> Preparing: select id,name,age,score from student WHERE age >? 104 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByWhere - ==> Preparing: select id,name,age,score from student WHERE age >? 105 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByWhere - ==> Parameters: 20(Integer) 105 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByWhere - ==> Parameters: 20(Integer) 109 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByWhere - <== Total: 2 109 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByWhere - <== Total: 2 Student [id=198, name=明明, score=99.5, age=23] Student [id=200, name=明明, score=99.5, age=23] 121 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByChoose - ==> Preparing: select id,name,age,score from student WHERE age>? 121 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByChoose - ==> Preparing: select id,name,age,score from student WHERE age>? 121 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByChoose - ==> Preparing: select id,name,age,score from student WHERE age>? 122 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByChoose - ==> Parameters: 20(Integer) 122 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByChoose - ==> Parameters: 20(Integer) 122 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByChoose - ==> Parameters: 20(Integer) 124 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByChoose - <== Total: 2 124 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByChoose - <== Total: 2 124 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByChoose - <== Total: 2 Student [id=198, name=明明, score=99.5, age=23] Student [id=200, name=明明, score=99.5, age=23]
當查詢的條件均不滿足時:
Student stu = new Student("", 0, 0);
輸出:
六、<foreach/>標簽--遍歷數組
該標簽用於實現對數組與集合的遍歷,對其使用需要注意:
- collection表示要遍歷的集合類型,這里是數組,即array。
- open、close、separate為遍歷內容的SQL拼接。

1 List<Student> selectStudentsByForeach(int[] ids);

1 @Test 2 public void test04() { 3 int[] ids={197,198,199}; 4 List<Student> students = dao.selectStudentsByForeach(ids); 5 for (Student student : students) { 6 System.out.println(student); 7 } 8 9 }

1 <select id="selectStudentsByForeach" resultType="Student"> 2 <!-- select id,name,age,score from student where id in (1,3,5) --> 3 select id,name,age,score 4 from student 5 <if test="array.length>0"> 6 where id in 7 <foreach collection="array" item="myid" open="(" close=")" 8 separator=","> 9 #{myid} 10 </foreach> 11 </if> 12 </select>
輸出:

176 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - ==> Preparing: select id,name,age,score from student where id in ( ? , ? , ? ) 176 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - ==> Preparing: select id,name,age,score from student where id in ( ? , ? , ? ) 176 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - ==> Preparing: select id,name,age,score from student where id in ( ? , ? , ? ) 176 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - ==> Preparing: select id,name,age,score from student where id in ( ? , ? , ? ) 177 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - ==> Parameters: 197(Integer), 198(Integer), 199(Integer) 177 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - ==> Parameters: 197(Integer), 198(Integer), 199(Integer) 177 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - ==> Parameters: 197(Integer), 198(Integer), 199(Integer) 177 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - ==> Parameters: 197(Integer), 198(Integer), 199(Integer) 179 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - <== Total: 3 179 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - <== Total: 3 179 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - <== Total: 3 179 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach - <== Total: 3 Student [id=197, name=明明, score=87.9, age=19] Student [id=198, name=明明, score=99.5, age=23] Student [id=199, name=明明, score=87.9, age=19]
七、<foreach/>標簽--遍歷泛型為基本類型的List

1 @Test 2 public void test05() { 3 List<Integer> ids =new ArrayList<>(); 4 ids.add(198); 5 ids.add(199); 6 List<Student> students = dao.selectStudentsByForeach2(ids); 7 for (Student student : students) { 8 System.out.println(student); 9 } 10 11 }

1 import java.util.List; 2 import com.jmu.bean.Student; 3 4 public interface IStudentDao { 5 // 根據條件查詢問題 6 List<Student> selectStudentsByIf(Student student); 7 List<Student> selectStudentsByWhere(Student student); 8 List<Student> selectStudentsByChoose(Student student); 9 List<Student> selectStudentsByForeach(int[] ids); 10 List<Student> selectStudentsByForeach2(List<Integer> ids); 11 }

1 <select id="selectStudentsByForeach2" resultType="Student"> 2 <!-- select id,name,age,score from student where id in (1,3,5) --> 3 select id,name,age,score 4 from student 5 <if test="list.size>0"> 6 where id in 7 <foreach collection="list" item="myid" open="(" close=")" 8 separator=","> 9 #{myid} 10 </foreach> 11 </if> 12 </select>
輸出:

0 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach2 - ==> Preparing: select id,name,age,score from student where id in ( ? , ? ) 48 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach2 - ==> Parameters: 198(Integer), 199(Integer) 78 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach2 - <== Total: 2 Student [id=198, name=明明, score=99.5, age=23] Student [id=199, name=明明, score=87.9, age=19]
八、<foreach/>標簽--遍歷泛型為自定義類型的List

1 import java.util.List; 2 import com.jmu.bean.Student; 3 4 public interface IStudentDao { 5 // 根據條件查詢問題 6 List<Student> selectStudentsByIf(Student student); 7 List<Student> selectStudentsByWhere(Student student); 8 List<Student> selectStudentsByChoose(Student student); 9 List<Student> selectStudentsByForeach(int[] ids); 10 List<Student> selectStudentsByForeach2(List<Integer> ids); 11 List<Student> selectStudentsByForeach3(List<Student> ids); 12 }

1 @Test 2 public void test06() { 3 Student stu1 = new Student(); 4 stu1.setId(198); 5 Student stu2 = new Student(); 6 stu2.setId(199); 7 List<Student> stus =new ArrayList<>(); 8 stus.add(stu1); 9 stus.add(stu2); 10 List<Student> students = dao.selectStudentsByForeach3(stus); 11 for (Student student : students) { 12 System.out.println(student); 13 } 14 15 }

1 <select id="selectStudentsByForeach3" resultType="Student"> 2 select id,name,age,score 3 from student 4 <if test="list.size>0"> 5 where id in 6 <foreach collection="list" item="stu" open="(" close=")" 7 separator=","> 8 #{stu.id} 9 </foreach> 10 </if> 11 </select>
輸出:

1 0 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach3 - ==> Preparing: select id,name,age,score from student where id in ( ? , ? ) 2 49 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach3 - ==> Parameters: 198(Integer), 199(Integer) 3 90 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentsByForeach3 - <== Total: 2 4 Student [id=198, name=明明, score=99.5, age=23] 5 Student [id=199, name=明明, score=87.9, age=19]
九、SQL片段