XML對映器
SQL對映檔案的幾個頂級元素:
-
cache
- 該名稱空間的快取配置 -
cache-ref
- 引用其他名稱空間的快取配置 -
resultMap
- 描述如何從資料庫結果集中載入物件 -
sql
- 可被其他語句引用的可重用語句塊 -
insert
- 增 -
update
- 改 -
delete
- 刪 -
select
- 查
select屬性
屬性 | 描述 |
---|---|
id |
識別符號,與Mapper中對應方法的方法名一致 |
parameterType |
傳入這條語句的引數的類全限定名或別名 |
resultType |
返回結果的類全限定名或別名,如果返回的是集合,應設定為集合包含的型別而不是集合本身的型別。resultType和resultMap之間只能使用一個 |
resultMap |
對外部resultMap的命名引用,結果對映是Mybatis的最強大的特性 |
sql
sql元素可以用來定義可重用的SQL程式碼片段,以便在其他語句中使用。引數可以靜態地(載入的時候)確定下來並且可以在不同的include元素中定義不同的引數值
<sql id="userColumns">
${alias}.id,${alias}.usernname,${alias}.password
</sql>
常用在include元素的refid屬性或內部語句中使用屬性值
<sql id="sometable">
${preifx}Table
</sql>
<sql id="someinclude">
FROM
<include refid="${include_target}"/>
</sql>
<select id="select" resultType="Map">
SELECT
field1,field2,field3
<include refid="someinclude">
<property name="prefix" value="Some"/>
<property name="include_target" value="sometable"/>
</include>
</select>
ResultMap
一對一查詢:
<!-- 屬性名不一致或進行關聯查詢時,可用resultMap標籤
以查詢訂單為例,從查詢訂單角度出發為一對一,因為一個訂單隻會是一個人下的 -->
1)改造實體類:
<!-- 在訂單類中新增User屬性,即一個引用型別 -->
2)編寫resultMap:
<resultMap type="order" id="orderUserResultMap">
<id property="id" column="id"/>
<result property="userId" column="user_id"/>
...
<result property="note" column="note"/>
<association property="user" javaType="user">
<id property="id" column="id"/>
<result property="username" column="username"/>
...
</association>
</resultMap>
3)呼叫例項:
<!-- 一對一關聯,查詢訂單,訂單內部包含使用者屬性 -->
<select id="queryOrderUserResultMap" resultMap="orderUserResultMap">
SELECT
o.id,
o.user_id,
o.number,
o.createtime,
o.note,
u.username,
u.address
FROM
`order` o
LEFT JOIN `user` u ON o.user_id = u.id
</select>
一對多查詢:
<!-- 查詢所有使用者資訊及相關訂單 -->
<!-- 對於使用者而言,一個使用者可能對應多個不同的訂單,即一對多 -->
1)改造實體類:
新增訂單集合屬性,如:List< Order > orders
2)編寫resultMap:
<resultMap type="user" id="userOrderResultMap">
<id property="id" column="id" />
<result property="username" column="username" />
<result property="birthday" column="birthday" />
<result property="sex" column="sex" />
<result property="address" column="address" />
<!-- 配置一對多的關係
property:填寫pojo類中List集合類類屬性的名稱
javaType:填寫集合型別的名稱
-->
<collection property="orders" javaType="list" ofType="order">
<!-- 配置主鍵,是關聯Order的唯一標識 -->
<id property="id" column="oid" />
<result property="number" column="number" />
<result property="createtime" column="createtime" />
<result property="note" column="note" />
</collection>
</resultMap>
3)呼叫例項:
<!-- 一對多關聯,查詢訂單同時查詢該使用者下的訂單 -->
<select id="queryUserOrder" resultMap="userOrderResultMap">
SELECT
u.id,
u.username,
u.birthday,
u.sex,
u.address,
o.id oid,
o.number,
o.createtime,
o.note
FROM
`user` u
LEFT JOIN `order` o ON u.id = o.user_id
</select>
動態SQL
簡介
主要介紹Mybatis提供的幾種用於實現動態SQL的標籤的基本使用方式:
- if
- choose、when、otherwise
- trim、where、set
- foreach
if
if 語句提供了可選的查詢文字功能
若 if 中條件成立,則執行 if 標籤中的語句,拼接至SQL語句中
若 if 中條件不成立,則忽略,舉個例子:
<select id="findActiveBlogWithTitleLike" resultType="Blog">
SELECT * FROM BLOG
WHERE state = 'ACTIVE'
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</select>
choose、when、otherwise
Mybatis提供的choose元素,類似Java的switch語句,可從多個條件中選擇一個使用
舉個例子:傳入了"title"就按"title"查詢,傳入了"author"就按"author"查詢的情形。
若兩者都沒有傳入,就返回標記為featured=1的BLOG(若多個條件滿足則遵循就近原則)
<select id="findActiveBlogLike" resultType="Blog">
SELECT * FROM BLOG
WHERE state = 'ACTIVE'
<choose>
<when test="title !=null">
AND title like #{title}
</when>
<when test="author != null and author.name != null">
AND author_name like #{author.name}
</when>
<otherwise>
AND featured = 1
</otherwise>
</choose>
</select>
trim、where、set
where
如何將上例中的"state='ACTIVE'"條件設定為動態條件,即WHERE標籤
<select id="findActiveBlogLike" resultType="Blog">
SELECT * FROM BLOG
WHERE
<if test="state != null">
state = #{state}
</if>
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</select>
按上面所寫,如果沒有匹配的條件,SQL會變成:
SELECT * FROM BLOG
WHERE
導致查詢失敗。如果匹配的只是第二/三個條件,SQL會變成:
SELECT * FROM BLOG
WHERE
AND title like 'title'
從上例可看出 WHERE 語句後的第一個條件想要實現動態SQL不能簡單使用條件元素來解決,對此可以使用Mybatis提供的where元素
<select id="findActiveBlogLike" resultType="Blog">
SELECT * FROM BLOG
<where>
<if test="state != null">
state = #{state}
</if>
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</where>
</select>
where元素只會在子元素返回任何內容的情況下才插入"WHERE"子句。並且若子句的開頭為"AND"或"OR",where元素也會將它們去除
set
用於動態更新語句的類似解決方案叫set。set元素可以用於動態包含需要更新的列,忽略其他不更新的列,比如:
<update id="updateAuthorIfNecessary">
UPDATE Author
<set>
<if test="username != null">
username=#{username},
</if>
<if test="password != null">
password=#{password},
</if>
<if test="email != null">
email=#{email},
</if>
<if test="bio != null">
bio=#{bio}
</if>
</set>
where id = #{id}
</update>
trim
如果選擇的元素與你期望的不大一樣,可以通過自定義trim元素來制定元素的功能,比如:
where標籤:
<trim prefix="WHERE" prefixOverrides="AND |OR ">
...
</trim>
set標籤:
<trim prefix="set" suffixOverrides=",">
...
</trim>
prefix:字首
prefixOverrides:字首覆蓋,忽略通過管道符分隔的文字序列
suffixOverrides:字尾覆蓋,覆蓋了字尾值的設定
foreach
動態SQL的另一個常見使用場景是對集合進行遍歷(尤其是在構建IN條件語句的時候)
<select id="selectPostIn" resultType="domain.blog.Post">
SELECT *
FROM POST P
WHERE ID in
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
</foreach>
</select>
可以將任何可迭代物件(List, Set)、Map或陣列物件作為集合引數傳遞給foreach。當使用可迭代物件或者陣列時,index是當前迭代的序號,item的值是本次迭代獲取到的元素。使用Map物件時,index是key,item是value