MyBatis
參數傳遞
-
單個參數:mybatis 不會做特殊處理
"#{參數名/任意名}:取出參數值"
-
多個參數:
多個參數會被封裝成一個 map,key:param1, .... paramN,或者參數的索引也可以,#{}就是從 map 中獲取指定的key的值
【命名參數】:明確指定封裝參數時map的key;
語法格式:@Param(“參數名”),多個參數會被封裝成一個map;
key:使用@Param注解指定的值
value:參數值
"#{指定的 key}取出對應的參數值"
-
傳入的是Java Bean、POJO、entity時
如果傳入參數正好是我們業務邏輯的數據模型,mybatis會把該對象的屬性作為封裝的map中的key,#{key}取出map中對應的值
-
map集合(多表幾個字段 )
mybatis的sql映射語句中的#{}需要更具傳入的map集合中的key進行取值
-
TO 或 VO 查詢多個
如果多個參數不是業務模型中的數據,但是經常要使用,推薦編寫一個TO(Transfer Object)或VO(View Object)數據傳輸對象,mybatis對其處理方式類似傳入一個entity實體類
-
其他類型
6.1 當傳入多個參數時,有的參數使用@Param注解修飾,有的沒有,怎么取值?
// 例如: public User getUser(@Param("id") Integer id, String userName); /* 取值:id ====> #{id} 或 #{param1} userName =====> #{param2} */
6.2 傳入多個參數,且其中一個參數為實體類並為@Param注解修飾時
//例如: public Employee getEmployee(Integer id, @Param("e") Employee employee); /* 取值:id =====> #{param1} employee =====> #{param2.userName} 或 #{e.userName} */
6.3 如果傳入的是Collection(List、Set)類型或者是數組,mybatis會進行特殊處理,會將傳入list或者數組封裝在map中。
key:1)Collection ====> collection作為key
2)如果是List還可以使用 list 作為key
3)如果是數組,可以使用array作為key
多表映射
- 一對一:OrderDetail表對Order表,OrderDetail表對Items表
- 一對多:User表對Order表,Order表對OrderDetail表
- 多對一:Order表對User表,Items表對Order表
- 多對多:User表對Items表,Order表對Items表
resultMap:封裝多表查詢結果的字段 和 對應實體類的屬性之間的關系
屬性:
id ---> resultMap的唯一標識,
type:與resultMap相關聯的實體類型,
extends:繼承已經定義過的其他resultMap
內部標簽:
id:主鍵標簽 property:實體類中對應屬性 column:數據庫表中的字段
assocation用於多表查詢時,實體類屬性為對象類型時,進行數據封裝
assocation可以通過select屬性(指定對應的sql映射語句),並通過column屬性指定傳入select語句中的參數從哪里獲取,實現懶加載
collection用於多表查詢時,實體類屬性中為對象集合類型時,進行數據封裝
注意:
1、分布查詢時,傳入多個參數?
使用{key1=column1,key2=column2....}的形式
key:就是分段查詢的sql映射的#{key}
column:傳遞給分步查詢sql映射的參數的值從那個列中獲取
2、大部分操作需要延遲加載,但小部分操作需要及時加載 怎么實現?
可以通過fetchType屬性指定屬性值來實現
動態SQL
where標簽的使用
<!--
查詢用戶:要求,攜帶哪些字段查詢條件就按這些字段進行查詢
使用的OGNL,類似與EL表達式
從參數中取值進行判斷,遇見特殊符號使用轉義字符
使用where標簽時要注意,它只能去除第一個多出來的and或or
-->
<select id="queryUserByCondition" resultType="user">
select * from easybuy_user
<where>
<if test="id != null">
and id = #{id}
</if>
<if test="userName != null and userName!=""">
and userName like #{userName}
</if>
<if test="email != null and email!=""">
and email = #{email}
</if>
</where>
</select>
trim標簽的使用
<!--
trim標簽的使用:解決后面多出的and或or
prefix="":前綴,trim標簽體中是整個字符串拼串后的結果
prefix給拼串后的整個字符串加一個前綴
prefixOverrides="":前綴覆蓋:去掉整個字符串前面多余的字符
suffix="":后綴,給拼串后的整個字符串加一個后綴
suffixOverrides="":后綴覆蓋,去掉整個字符串后面多余的字符
-->
<select id="queryUserByTrim" resultType="user">
select * from easybuy_user
<trim prefix="where" suffixOverrides="and">
<if test="id != null">
id = #{id} and
</if>
<if test="userName != null and userName!=""">
userName like #{userName} and
</if>
<if test="email != null and email!=""">
email = #{email} and
</if>
</trim>
</select>
choose和when標簽的使用(作用類似與java中的switch-case)
<select id="queryUserByChoose" resultType="com.unistart.entity.User">
select * from easybuy_user
<where>
<choose>
<when test="id != null">
id=#{id}
</when>
<when test="userName != null">
userName like #{userName}
</when>
<when test="sex != null">
sex = #{sex}
</when>
<otherwise>
1=1;
</otherwise>
</choose>
</where>
</select>
set標簽的使用
<!--
使用set標簽或者trim標簽與if標簽相結合
實現動態更新sql語句的拼接
-->
<update id="updateUserByCondition" parameterType="user">
update easybuy_user
<set>
<if test="userName != null">
username = #{userName},
</if>
<if test="email != null">
email = #{email},
</if>
</set>
where id = 26;
</update>
foreach標簽的使用
<!--
foreach
collection:指定要遍歷的集合
list類型的參數會特殊處理封裝在map中,map的key就叫list
item:將當前遍歷出的元素賦值給指定的變量
separator:元素之間的分割符
open: 遍歷出的所有結果拼接一個開始字符
close:遍歷出的所有結果拼接一個結束字符
index:索引,遍歷list的時候是索引,item就是當前值;
遍歷map時index標識的就是map的key,item就是map的值
#{變量名}: 就能取出變量的值就是當前遍歷出的元素
-->
<select id="queryUserByForEach" resultType="user">
select * from easybuy_user where id in
<foreach collection="ids" item="item_id" separator=","
open="(" close=")">
#{item_id}
</foreach>
</select>
<insert id="batchSaveUser" parameterType="user">
insert into easybuy_user(loginName, userName, password) values
<foreach collection="userList" item="user" separator=",">
(#{user.loginName}, #{user.userName}, #{user.password})
</foreach>
</insert>