目錄
- 一、if
- 二、where
- 三、foreach
- 1. 用法一
- 2. 用法二
- 四、sql代碼片段
- 五、總結
- 1. if
- 2. where
- 3. foreach
- 4. sql代碼片段

專案的創建和之前一樣,具體的看之前的文章,整體結構就是這樣
一、if
對于該標簽的執行,當 test 的值為 true 時,會將其包含的 SQL 片斷拼接到其所在的 SQL 陳述句中,
語法:<if test=”條件”> sql 陳述句的部分 </if>
介面方法:StudentDao
// 動態的sql時,使用java物件作為引數
List<Student> selectStudentIf(Student student);
mapper檔案:StudentDao.xml
<!--if的使用
<if test="使用的引數為java物件屬性值作為判斷條件">
語法:屬性=xxx值
-->
<!--
注意,當這樣寫的時候,name不滿足而age滿足的時候會出現問題
正常:select id,name,age,email from student where name = ? or age > ?
不正常: select id,name,age,email from student where or age > ?
這個時候會有語法錯誤
所以寫的是時候要在where后面這樣
where 1=1
這樣寫的話即使name不滿足,后面的也不不會出現語法錯誤
select id,name,age,email from student where 1=1 or age > ?
但這樣也會出現其他的bug,因為是or,并且1=1永遠為true,所以age無論傳入多大都會有資料的
-->
<select id="selectStudentIf" resultType="com.md.domain.Student">
select id,name,age,email from student
where 1=1
<if test="name != null and name != '' ">
name = #{name}
</if>
<if test="age > 0" >
or age > #{age}
</if>
</select>
測驗
@Test
public void testSelectStudentIf(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
Student student = new Student();
student.setAge(20);
List<Student> studentList = dao.selectStudentIf(student);
studentList.forEach(stu-> System.out.println(stu));
sqlSession.close();
}
此時即使資料庫中,無論年紀多大的都會被查出來,所以就有了下面的標簽
二、where
<if/>標簽的中存在一個比較麻煩的地方:需要在 where 后手工添加 1=1 的子句,因為,若 where 后
的所有<if/>條件均為 false,而 where 后若又沒有 1=1 子句,則 SQL 中就會只剩下一個空的 where,SQL
出錯,所以,在 where 后,需要添加永為真子句 1=1,以防止這種情況的發生,但當資料量很大時,會
嚴重影響查詢效率
使用<where/>標簽,在有查詢條件時,可以自動添加上 where 子句;沒有查詢條件時,不會添加where 子句,需要注意的是,第一個<if/>標簽中的 SQL 片斷,可以不包含 and,不過,寫上 and 也不錯,系統會將多出的 and 去掉,但其它<if/>中 SQL 片斷的 and,必須要求寫上,否則 SQL 陳述句將拼接出錯
<where> 用來包含 多個<if>的, 當多個if有一個成立的, <where>會自動增加一個where關鍵字,并去掉 if中多余的 and ,or等
語法:<where> 其他動態 sql </where>
介面方法
// 動態的sql時,使用java物件作為引數
List<Student> selectStudentWhere(Student student);
mapper
<!--where的使用
select id,name,age,email from student WHERE name = ? or age > ?
select id,name,age,email from student WHERE age > ?
這樣就避免了上面的bug
-->
<select id="selectStudentWhere" resultType="com.md.domain.Student">
select id,name,age,email from student
<where>
<if test="name != null and name != '' ">
name = #{name}
</if>
<if test="age > 0" >
or age > #{age}
</if>
</where>
</select>
測驗:
@Test
public void testSelectStudentWhere(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
Student student = new Student();
student.setName("白昊天");
student.setAge(20);
List<Student> studentList = dao.selectStudentWhere(student);
studentList.forEach(stu-> System.out.println(stu));
sqlSession.close();
}
此時就不會出現之前的bug了
三、foreach
<foreach/>標簽用于實作對于陣列與集合的遍歷,對其使用,需要注意:
- collection 表示要遍歷的集合型別, list ,array 等,
- open、close、separator 為對遍歷內容的 SQL 拼接
語法
<foreach collection=" 集合型別" open=" 開始的字符" close=" 結束的字符"
item=" 集合中的成員" separator=" 集合成員之間的分隔符">
#{item 的值}
</foreach>
例子,查詢學號1001、1002、1003學生的資訊
如果是用純java來拼接這個查詢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";
StringBuilder builder = new StringBuilder("");
// 添加開始
builder.append("(");
for (Integer i : list){
builder.append(i).append(",");
}
// 因為最后多添加了一個逗號,所以在這里進行洗掉
builder.deleteCharAt(builder.length()-1);
builder.append(")");
sql = sql + builder.toString();
System.out.println(sql);
// select * from student where id in(1001,1002,1003)
}
1. 用法一
介面
// 傳入的是普通list
List<Student> selectForeachOne(List<Integer> idlist);
mapper
select id,name,age,email from student where id in ( ? , ? , ? )
<select id="selectForeachOne" resultType="com.md.domain.Student">
select id,name,age,email from student where id in
<foreach collection="list" item="myid" open="(" close=")" separator=",">
#{myid}
</foreach>
</select>
測驗:
@Test
public void testSelectForeachOne(){
SqlSession sqlSession = MybatisUtils.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.selectForeachOne(list);
studentList.forEach(stu-> System.out.println(stu));
sqlSession.close();
}
2. 用法二
介面
// foreach 用法二 , 傳入的是物件集合
List<Student> selectForeachTwo(List<Student> stulist);
mapper檔案
由于傳入的是物件,所以要用物件.屬性
<select id="selectForeachTwo" resultType="com.md.domain.Student">
select id,name,age,email from student where id in
<foreach collection="list" item="stu" open="(" close=")" separator=",">
#{stu.id}
</foreach>
</select>
測驗方法
@Test
public void testSelectForeachTwo(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
List<Student> students = new ArrayList<>();
Student stu1 = new Student();
stu1.setId(1003);
students.add(stu1);
List<Student> studentList = dao.selectForeachTwo(students);
studentList.forEach(stu-> System.out.println(stu));
// select id,name,age,email from student where id in ( ? )
// Student{id=1003, name='白昊天', email='[email protected]', age=18}
sqlSession.close();
}
當然了,對于mapper檔案的sql陳述句還可以這樣寫
<!-- 直接在外面寫小括號,只有能湊成完成的sql陳述句就行-->
<select id="selectForeachTwo" resultType="com.md.domain.Student">
select id,name,age,email from student where id in (
<foreach collection="list" item="stu" separator=",">
#{stu.id}
</foreach>
)
</select>
效果和上面的是一樣的,能完成的拼湊出sql陳述句即可
四、sql代碼片段
<sql/>標簽用于定義 SQL 片斷,以便其它 SQL 標簽復用,
而其它標簽使用該 SQL 片斷,需要使用<include/>子標簽,該<sql/>標簽可以定義 SQL 陳述句中的任何部分,所以<include/>子標簽可以放在動態 SQL的任何位置
介面方法:
List<Student> selectStudentSqlFragment(List<Student> stuList);
mapper檔案
<!-- 創建 sql 片段 id: 片段的自定義名稱 -->
<sql id="studentSql">
select id,name,email,age from student
</sql>
<select id="selectStudentSqlFragment" resultType="com.md.domain.Student">
<!-- 參考 sql 片段 -->
<include refid="studentSql"/>
<if test="list !=null and list.size > 0 ">
where id in
<foreach collection="list" open="(" close=")"
item="stuobject" separator=",">
#{stuobject.id}
</foreach>
< /if>
</select>
測驗方法
@Test
public void testSelectSqlFragment() {
List<Student> list = new ArrayList<>();
Student s1 = new Student();
s1.setId(1002);
list.add(s1);
s1 = new Student();
s1.setId(1005);
list.add(s1);
List<Student> studentList = studentDao.selectStudentSqlFragment(list);
studentList.forEach( stu -> System.out.println(stu));
}
五、總結
根據條件能夠使用不同的sql陳述句,使用mybatis標簽
1. if
判斷條件,條件為true,就會把if之前的sql加入到主sql陳述句之后
2. where
<where> 標簽里面多個if標簽,如果有一個if判斷為true,就會在sql的后面加入where關鍵字,而還會自動的去掉無用的and、or等字符
3. foreach
回圈陣列,list集合,主要看語法格式
4. sql代碼片段
復用常用的sql陳述句
- 先定義<sql id="自定義名唯一" > sql陳述句 </sql>
- 再使用 <include refid = "id的值">
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/95090.html
標籤:Java
上一篇:封裝MyBatis輸出結果
