一、動態SQL陳述句
- 何為動態SQL陳述句:
通過mybatis提供的< if > ,< where >,< foreach >標簽對條件做出判斷以實作動態拼接SQL陳述句,主要用于解決查詢條件不確定的情況,它會根據用戶提交的查詢條件進行查詢,其主要是SQL陳述句where關鍵字后面部分發生變化,
- 注意事項:
在映射檔案中的動態 SQL 中若出現大于號(>)、小于號(<)、大于等于號(>=),小于等于號(<=)等符號,最好將其轉換為物體符號,否則,XML 可能會出現決議出錯問題,
重點:特別是對于小于號(<),在 XML 檔案中是絕不能出現的,否則決議 映射檔案 會出錯,
- 物體符號表:
| < | 小于 | <; |
|---|---|---|
| > | 大于 | >; |
| >= | 大于等于 | >;= |
| <= | 小于等于 | <;= |
- 下面介紹這幾種標簽:
(1)< if >標簽
語法格式:
<if test="判斷java物件的屬性值">
部分sql陳述句
</if>
- 定義介面中的方法
List<Student> selectStudentIf(Student student);
- 映射檔案
<select id="selectStudentIf" resultType="Student">
<include refid="studentSql"/>
where
<if test="name!=null and name!=''">
name=#{name}
</if>
<if test="age>0">
or age>#{age}
</if>
</select>
這里定義了SQL陳述句代碼片段,方便以后呼叫,避免代碼冗余
使用步驟:
1.先定義 < sql id=“自定義名稱唯一”> sql陳述句, 表名,欄位等 < /sql>
2.再使用, < include refid=“id的值” />
<sql id="studentSql" >
select id,name,age,email from student
</sql>
- 定義測驗方法
@Test
public void testSelectStudenIf(){
SqlSession sqlSession = MyBatisUtil.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
Student student = new Student();
student.setName("李四");
student.setAge(20);
List<Student> studentList = dao.selectStudentIf(student);
for (Student student1:studentList){
System.out.println("學生if="+student1);
}
}
這里如把測驗方法中的代碼姓名這段代碼注釋掉:
Student student = new Student();
//student.setName("李四");
student.setAge(20);
List<Student> studentList = dao.selectStudentIf(student);
那么執行的SQL陳述句則會出錯:
SQL:select id,name,age,email from student where or age>?
缺陷:
當后面一個if陳述句不滿足或者都不滿足時,SQL陳述句會拼接成
select id,name,age,email from student where or age>?
select id,name,age,email from student where
這樣的SQL陳述句明顯是錯誤的
小技巧:
可以在where后面加入一個滿足條件(真子句),例如:where id>0
這樣SQL陳述句就變成了可執行陳述句了
select id,name,age,email from student where id>0 or age>?
但當資料量很大時,會嚴重影響查詢效率,
改進后的映射檔案為:
<select id="selectStudentIf" resultType="Student">
<include refid="studentSql"/>
where id>0
<if test="name!=null and name!=''">
and name=#{name}
</if>
<if test="age>0">
or age>#{age}
</if>
</select>
里面where關鍵字后面添加了一個真子句id>0并在name前面加多了and
這樣執行SQL陳述句則變成:
SQL:select id,name,age,email from student where id>0 or age>?
(2)< where >標簽
語法格式:
<where>
其他動態 sql
</where>
< where >:解決< if >標簽帶來的小缺陷
< where > 用來包含 多個< if> 的
1、當多個 if 有一個成立的,< where >會自動增加一個WHERE關鍵字
2、當后面 if 條件有些不成立時,可以去掉 if 中多余的 and ,or等
3、當后面的 if 條件都不滿足時,WHERE關鍵字也會去掉
- 定義介面中的方法
List<Student> selectStudentWhere(Student student);
- 映射檔案
<select id="selectStudentWhere" resultType="Student">
<include refid="studentSql"></include>
<where>
<if test="name!=null and name!=''">
name=#{name}
</if>
<if test="age>0">
or age>#{age}
</if>
</where>
</select>
- 定義測驗方法
@Test
public void testSelectStudenWhere(){
SqlSession sqlSession = MyBatisUtil.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
Student student = new Student();
//student.setName("李四");
student.setAge(20);
List<Student> studentList = dao.selectStudentWhere(student);
for (Student student1:studentList){
System.out.println("學生where="+student1);
}
}
(3)< foreach>標簽
語法格式:
<foreach collection="" open="" close="" item="" separator="">
#{item 的值}
</foreach>
< foreach >標簽用于實作對于陣列與集合的遍歷,主要用在sql陳述句的 in 陳述句中
1、這里先不用標簽把SQL陳述句拼接出來
例如:查詢學生 id 是 1001,1002,1003
select * from student where id in (1001,1002,1003)
這里定義一個測驗方法來拼接上面的SQL陳述句
@Test
public void testfor(){
List<Integer> list=new ArrayList<>();
list.add(1001);
list.add(1002);
list.add(1003);
//String sql = "select * from student where id in(1001,1002,1003);
String sql ="select * from student where id in";
StringBuilder builder = new StringBuilder(sql);
int init=0;
int len=list.size();
//添加開始的(
builder.append("(");
for (Integer i:list){
builder.append(i).append(",");
}
//將最后一個逗號洗掉
builder.deleteCharAt(builder.length()-1);
//回圈結束
builder.append(")");
sql = builder.toString();
System.out.println("sql=="+sql);
}
顯然以上代碼很長很臭,下面進行改進…
2、通過< foreach >標簽把SQL陳述句拼接出來
用法一:遍歷 List<簡單型別>
- 定義介面中的方法
List<Student> selectStudentForeachOne(List<Integer> list);
- 映射檔案
<select id="selectStudentForeachOne" resultType="Student">
<include refid="studentSql"/> where id in
<foreach collection="list" item="myid" open="(" close=")" separator=",">
#{myid}
</foreach>
</select>
決議標簽中的屬性:
1、collection:表示介面中的方法引數的型別,
如果是陣列使用array , 如果是list集合使用list
2、item:自定義的,表示陣列和集合成員的變數,相當于Integer i中的 i 變數
for (Integer i:list){
builder.append(i).append(",");
}
3、open:回圈開始是的字符“(”
4、close:回圈結束時的字符“)”
5、separator:集合成員之間的分隔符“,”
- 定義測驗方法
@Test
public void testSelectStudenForeachOne(){
SqlSession sqlSession = MyBatisUtil.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
List<Integer> list=new ArrayList<>();
list.add(1001);
list.add(1002);
list.add(1003);
List<Student> studentList = dao.selectStudentForeachOne(list);
for (Student student1:studentList){
System.out.println("學生foreachone="+student1);
}
}
用法二:遍歷 List<物件型別>
- 定義介面中的方法
List<Student> selectStudentForeachTwo(List<Student> studentlist);
- 映射檔案
<select id="selectStudentForeachTwo" resultType="Student">
<include refid="studentSql"/> where id in (
<foreach collection="list" item="stu" separator=",">
#{stu.id}
</foreach>
)
</select>
注意:這里 item 的值 stu 只是對應的Java物件
- 定義測驗方法
@Test
public void testSelectStudenForeachTwo(){
SqlSession sqlSession = MyBatisUtil.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
List<Student> stulist=new ArrayList<>();
Student s1 = new Student();
s1.setId(1001);
stulist.add(s1);
Student s2 = new Student();
s2.setId(1002);
stulist.add(s2);
List<Student> studentList = dao.selectStudentForeachTwo(stulist);
for (Student student1:studentList){
System.out.println("學生foreachtwo="+student1);
}
}
二、思維大綱

如有不足之處請大家指正哈!
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/252740.html
標籤:其他
上一篇:資訊收集
