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>