本文是Mybatis基礎系列的第三篇文章,點擊下面連接能夠查看前面的文章:html
mybatis基礎系列(二)——基礎語法、別名、輸入映射、輸出映射sql
MyBatis 的強大特性之一即是它的動態 SQL。擺脫了JDBC中根據不一樣條件拼接 SQL 語句的痛苦。動態 SQL能夠幫咱們解決複雜需求。mybatis 動態SQL,經過 if, choose, when, otherwise, trim, where, set, foreach等標籤組合成很是靈活的SQL語句。mybatis
根據員工編號或者員工姓名查詢員工信息,輸入的員工編號可能爲空。ide
<select id="queryByEnameOrEempno" parameterType="com.itpsc.request.EmpRequest" resultType="com.itpsc.vo.EmpVo"> SELECT * FROM t_emp WHERE <if test="emp.ename!=null"> ename=#{emp.ename} </if> <if test="emp.empno!=null"> and empno=#{emp.empno} </if> </select>
執行結果:spa
編號爲空 ==> Preparing: SELECT * FROM t_emp WHERE ename=? ==> Parameters: itpsc(String) <== Columns: empno, ename, job, mgr, hiredate, sal, comm, deptno <== Row: 7100, itpsc, developer, 7902, 1980-01-10, null, 1000.00, 20 <== Total: 1 姓名爲空 ==> Preparing: SELECT * FROM t_emp WHERE and empno=? ==> Parameters: 7100(Integer)
從執行結果能夠看出,上面的if語句只能是在員工姓名不能爲空的狀況下執行,若是員工姓名爲空sql語句就出錯了,If+where語句能夠解決這個問題。code
<select id="queryByEnameOrEempno" parameterType="com.itpsc.request.EmpRequest" resultType="com.itpsc.vo.EmpVo"> SELECT * FROM t_emp <where> <if test="emp.ename!=null"> and ename=#{emp.ename} </if> <if test="emp.empno!=null"> and empno=#{emp.empno} </if> </where> </select>
執行結果:htm
姓名爲空 ==> Preparing: SELECT * FROM t_emp WHERE empno=? ==> Parameters: 7100(Integer) <== Columns: empno, ename, job, mgr, hiredate, sal, comm, deptno <== Row: 7100, itpsc, developer, 7902, 1980-01-10, null, 1000.00, 20 <== Total: 1 編號爲空 ==> Preparing: SELECT * FROM t_emp WHERE ename=? ==> Parameters: itpsc(String) <== Columns: empno, ename, job, mgr, hiredate, sal, comm, deptno <== Row: 7100, itpsc, developer, 7902, 1980-01-10, null, 1000.00, 20 <== Total: 1
<where>標籤中包含的標籤中有返回值的話,它就插入一個where關鍵字,而且where 標籤會自動將其後第一個條件的and或者是or給忽略掉。對象
trim語句能夠實現<where>標籤相似的功能:blog
(1)trim標籤能夠在包含的內容前加上前綴,也能夠在其後加上後綴,對應的屬性是prefix和suffix;
(2)trim標籤能夠把包含內容的首部某些內容忽略,也能夠把尾部的某些內容忽略,對應的屬性是prefixOverrides和suffixOverrides。
<select id="queryByEnameOrEempno" parameterType="com.itpsc.request.EmpRequest" resultType="com.itpsc.vo.EmpVo"> SELECT * FROM t_emp <trim prefix="where" prefixOverrides="and | or"> <if test="emp.ename!=null"> and ename=#{emp.ename} </if> <if test="emp.empno!=null"> and empno=#{emp.empno} </if> </trim> </select>
執行結果:
empno爲空 ==> Preparing: SELECT * FROM t_emp where ename=? ==> Parameters: itpsc2(String) <== Columns: empno, ename, job, mgr, hiredate, sal, comm, deptno <== Row: 7101, itpsc2, developer, 7902, 1980-01-10, 2000.00, 1000.00, 20 <== Total: 1 ename爲空 ==> Preparing: SELECT * FROM t_emp where empno=? ==> Parameters: 7100(Integer) <== Columns: empno, ename, job, mgr, hiredate, sal, comm, deptno <== Row: 7100, itpsc1, mannager, 7902, 1980-01-10, null, 1000.00, 20 <== Total: 1 empno、ename都不爲空 ==> Preparing: SELECT * FROM t_emp where ename=? and empno=? ==> Parameters: itpsc2(String), 7100(Integer) <== Total: 0
條件判斷用<where>標籤,同理更新操做用<set>標籤。
<select id="updateEnameOrJob" parameterType="com.itpsc.request.EmpRequest"> UPDATE t_emp <set> <if test="emp.ename!=null"> ename=#{emp.ename} </if> <if test="emp.job!=null"> job=#{emp.job} </if> </set> WHERE empno=#{emp.empno} </select>
運行結果:
job爲空 ==> Preparing: UPDATE t_emp SET ename=? WHERE empno=? ==> Parameters: hello(String), 7100(Integer) ename 爲空 ==> Preparing: UPDATE t_emp SET job=? WHERE empno=? ==> Parameters: itpsc(String), 7100(Integer)
<set>標籤中包含的標籤中有返回值的話,它就插入一個set關鍵字。job和ename都不爲空則sql錯誤,那又如何寫呢,trim標籤能夠幫咱們能實現。
<select id="updateEnameOrJob" parameterType="com.itpsc.request.EmpRequest"> UPDATE t_emp <trim prefix="set" suffixOverrides=","> <if test="emp.ename!=null"> ename=#{emp.ename}, </if> <if test="emp.job!=null"> job=#{emp.job}, </if> </trim> WHERE empno=#{emp.empno} </select>
運行結果:
==> Preparing: UPDATE t_emp set ename=?, job=? WHERE empno=? ==> Parameters: itpsc(String), mannager(String), 7100(Integer)
上的例子中,job和ename都不爲空則是一種條件,job爲空且ename不爲空是一種條件,ename爲空且job不爲空是一種條件。實際上,咱們要只要知足任意一個條件,就能夠執行。choose(when,otherwise) 語句能夠幫咱們解決,相似jstl。
<select id="updateEnameOrJob" parameterType="com.itpsc.request.EmpRequest"> UPDATE t_emp <set> <choose> <when test="emp.ename!=null and emp.job!=null"> ename=#{emp.ename},job=#{emp.job} </when> <otherwise> <if test="emp.ename!=null"> ename=#{emp.ename} </if> <if test="emp.job!=null"> job=#{emp.job} </if> </otherwise> </choose> </set> WHERE empno=#{emp.empno} </select>
執行結果:
ename爲空且job不爲空 ==> Preparing: UPDATE t_emp SET job=? WHERE empno=? ==> Parameters: mannager(String), 7100(Integer) job爲空且ename不爲空 ==> Preparing: UPDATE t_emp SET ename=? WHERE empno=? ==> Parameters: itpsc2(String), 7100(Integer) job和ename都不爲空 ==> Preparing: UPDATE t_emp SET ename=?,job=? WHERE empno=? ==> Parameters: itpsc2(String), mannager(String), 7100(Integer)
需求:根據員工編號列表查詢員工信息。7369,7499,7521。
Sql的寫法是:select * from t_emp where 1=1 and empno=7369 or empno=7499 or empno=7521
mybatis的foreach語句能夠幫咱們實現相似功能。
<select id="queryByIds" parameterType="com.itpsc.request.IdRequest" resultType="com.itpsc.vo.EmpVo"> SELECT * FROM t_emp <where> <foreach collection="ids" item="id" open="and (" close=")" separator="or"> empno=#{id} </foreach> </where> </select>
collection:指定輸入對象中的集合屬性
item:每次遍歷生成的對象
open:開始遍歷時的拼接字符串
close:結束時拼接的字符串
separator:遍歷對象之間須要拼接的字符串
運行結果:
==> Preparing: SELECT * FROM t_emp WHERE ( empno=? or empno=? or empno=? ) ==> Parameters: 7369(Integer), 7499(Integer), 7521(Integer) <== Columns: empno, ename, job, mgr, hiredate, sal, comm, deptno <== Row: 7369, SMITH, CLERK, 7902, 1980-12-17, 800.00, null, 20 <== Row: 7499, ALLEN, SALESMAN, 7698, 1981-02-20, 1600.00, 300.00, 30 <== Row: 7521, WARD, SALESMAN, 7698, 1981-02-22, 1250.00, 500.00, 30 <== Total: 3
將上面動態sql代碼塊抽取出來,組成一個sql片斷,其它的statement中就能夠引用該sql片斷。提供代碼複用性,方便團隊成員之間進行開發。
<select id="queryCount2" parameterType="com.itpsc.request.EmpRequest" resultType="int"> SELECT count(*) FROM t_emp <where> <if test="emp!=null"> <if test="emp.deptno!=null"> and emp.deptno=#{emp.deptno} </if> <if test="emp.ename!=null"> and emp.ename=#{emp.ename} </if> <if test="emp.job!=null"> and emp.job=#{emp.job} </if> </if> </where> </select>
上面where語句中代碼,咱們能夠經過<sql>標籤封裝成一個sql片斷,而後在其它statement中經過<include>引用。
<sql id="querySql"> <if test="emp!=null"> <if test="emp.deptno!=null"> and emp.deptno=#{emp.deptno} </if> <if test="emp.ename!=null"> and emp.ename=#{emp.ename} </if> <if test="emp.job!=null"> and emp.job=#{emp.job} </if> </if> </sql> <select id="queryCount2" parameterType="com.itpsc.request.EmpRequest" resultType="int"> SELECT count(*) FROM t_emp <where> <include refid="querySql"></include> </where> </select>
本文到此,下篇 mybatis基礎系列(四)——關聯查詢、延遲加載、一級緩存與二級緩存。