項目的建立和以前同樣,具體的看以前的文章,總體結構就是這樣java
對於該標籤的執行,當 test 的值爲 true 時,會將其包含的 SQL 片段拼接到其所在的 SQL 語句中。
語法:<if test=」條件」> sql 語句的部分 </if>sql
接口方法: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>
測試mybatis
@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(); }
此時即便數據庫中,不管年紀多大的都會被查出來,因此就有了下面的標籤app
<if/>標籤的中存在一個比較麻煩的地方:須要在 where 後手工添加 1=1 的子句。由於,若 where 後
的全部<if/>條件均爲 false,而 where 後若又沒有 1=1 子句,則 SQL 中就會只剩下一個空的 where,SQL
出錯。因此,在 where 後,須要添加永爲真子句 1=1,以防止這種狀況的發生。但當數據量很大時,會
嚴重影響查詢效率dom
使用<where/>標籤,在有查詢條件時,能夠自動添加上 where 子句;沒有查詢條件時,不會添加where 子句。須要注意的是,第一個<if/>標籤中的 SQL 片段,能夠不包含 and。不過,寫上 and 也不錯,系統會將多出的 and 去掉。但其它<if/>中 SQL 片段的 and,必需要求寫上。不然 SQL 語句將拼接出錯測試
<where> 用來包含 多個<if>的, 當多個if有一個成立的, <where>會自動增長一個where關鍵字,並去掉 if中多餘的 and ,or等ui
語法:<where> 其餘動態 sql </where>3d
接口方法
// 動態的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=" 集合類型" open=" 開始的字符" close=" 結束的字符" item=" 集合中的成員" separator=" 集合成員之間的分隔符"> #{item 的值} </foreach>
例子,查詢學號100一、100二、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) }
接口
// 傳入的是普通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(); }
接口
// 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='ht@qq.com', 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 片段,須要使用<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標籤
判斷條件,條件爲true,就會把if以前的sql加入到主sql語句以後
<where> 標籤裏面多個if標籤,若是有一個if判斷爲true,就會在sql的後面加入where關鍵字,而還會自動的去掉無用的and、or等字符
循環數組,list集合,主要看語法格式
複用經常使用的sql語句