文章目录
一、课程目标
【掌握】MyBatis缓存
【掌握】MyBatis延迟加载
【掌握】MyBatis动态sql
二、MyBatis缓存
2.1 概念
在客户进行查询操作时,往往可能对重复的查询执行很多次,mybatis提供了默认的缓存机制一级缓存、二级缓存其中一级缓存默认开启,二级缓存需要进行配置才能进行使用,将查询的结果放置至对应的缓存,在用户重复查询时可以直接获取上一次的结果(在没有进行修改的情况下)
2.2 一级缓存
在mybatis核心配置文件中设置相应的配置开启缓存默认会直接开启一级缓存,将查询的数据缓存至当前的sqlsession会话中,当对同一sql语句进行多次查询时,除第一次进行查询外,其余直接获取当前缓存中的数据(没有被修改的前提下)
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
mybatis为了提高用户的查询效率,会将一级缓存存储在客户连接的sqlsession中。同一个sqlsession默认会使用同一个查询的结果
2.3 二级缓存
由于二级缓存是所有的sqlsession都可以访问,如果将所有的查询结果都保存可能造成数据的溢出,所以mybaits提供了2种共同实行的解决方案,首先需要对开启二级缓存的mapper进行设置,并且提供可以与第三方存储联合的方法,将缓存存储至像是radis这样的内存服务器中(默认存储在服务器中)
开启二级缓存只需要在对应mapper中书写cache标签(无属性)
<!--开启二级缓存 默认存储在当前系统内存中-->
<cache/>
注意:二级缓存会将结果存储在内存中,所以需要存储数据实现序列化接口,并且只有在当前的sqlsession使用结束,才会将一级缓存数据推送至二级缓存
三、MyBatis延迟加载
3.1 概念
在进行查询时只将核心数据进行查询(不将所有数据全部查询),而是在达到指定触发条件时自动调用查询返回结果。
常用于多个表之间的对应关系
3.2 书写
使用的是resultMap 集合映射与类映射的三个属性
select:指向其他mapper的查询语法是namespace.id
column:调用其他查询时需要传入的参数(使用已有查询结果列进行使用)
fetchType: 设置延迟加载样式
lazy深入式 :只有使用到对应属性时才进行查询(根据需要使用的属性进行查询)
eager侵入式:无延迟加载直接执行将数据查询
<resultMap id="user" type="com.yunhe.vo.User">
<association property="role" column="uid" select="com.yunhe.mapper.RoleMapper.selectByUid" fetchType="lazy"/>
</resultMap>
四、MyBatis动态sql
4.1 概念
根据传入的参数获取书写一些带有逻辑功能的标签,实现相同的方法执行不同的sql语句,语法类似于jstl
4.2 if 标签
可以动态的在sql中进行判断,只有返回true时才会将指定的sql语句拼写进行执行
<select id="findUserWhereId" resultType="User">
SELECT * FROM User
WHERE state = 0
<if test="id != null">
AND id = #{id}
</if>
</select>
4.3 choose、when、otherwise 标签
相比较if标签用的比较多,类似于java中的switch
<select id="findUser" resultType="User">
SELECT * FROM User WHERE state = 0
<choose>
<when test="id != null">
AND title like #{id}
</when>
<when test="name!= null">
AND name like '%#{name}%'
</when>
<otherwise>
AND sal= 1
</otherwise>
</choose>
</select>
4.4 where标签
动态的添加where ,当标签中有数据时会自动添加where 否则不会添加 ,并且如果where标签中数据是以and 或者or开头 会自动删除and或者or 防止语句出现问题
<select id="findUser" resultType="User">
SELECT * FROM User
<where>
<if test="id != null">
state = #{state}
</if>
<if test="name!= null">
AND title like #{title}
</if>
</where>
</select>
4.5 set标签
常用于修改数据时,根据传入的数据拼写修改数据的sql
<update id="updateUserIfNecessary">
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>
4.6 foreach标签
当传递的数据是数组或者集合时,需要使用foreach标签进遍历拼写sql
<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>
item:遍历取出的数据
index:遍历数据的索引
colleaction:遍历的数据集合
open:开始拼接时添加的字符串
separator:每次遍历中间的字符串
close:结束后最后添加的字符串
实例
根据传入实体类数据对多个字段sql拼接查询
<select id="selectByAuthor" resultType="com.yunhe.vo.Author">
select * from author
<!-- where 标签 当标签内存在数据时 自动以where 作为前缀 并且将数据起始的and和or删除-->
<where>
<!-- if标签 当test返回为true时 将对应内容输出sql拼接 -->
<if test="aid !=0">
and aid=#{aid}
</if>
<if test="aname!=null">
and aname like '%${aname}%'
</if>
<if test="aage!=0">
and aage=#{aage}
</if>
<if test="atel!=null">
and atel=#{atel}
</if>
<if test="aaddress!=null">
and aaddress like concat('%',#{aaddress},'%')
</if>
</where>
</select>
在修改时根据传入的参数动态修改
<update id="updateByAuthor" parameterType="com.yunhe.vo.Author">
update author
<!-- set 标签 当标签内存在数据时 自动以set 作为前缀 并且将数据结尾的 ,删除*/-->
<set>
<if test="aname!=null">
aname = #{aname} ,
</if>
<if test="aage!=0">
aage = #{aage} ,
</if>
<if test="atel!=null">
atel=#{atel} ,
</if>
<if test="aaddress!=null">
aaddress = #{aaddress}
</if>
</set>
where aid=#{aid}
</update>
批量添加
传入数据集合根据集合生成sql批量添加
<insert id="insertList" parameterType="java.util.ArrayList">
insert into author (aname,aage,atel,aaddress) values
<!--foreach遍历标签 遍历请求参数的集合 -->
<!-- collection请求参数的集合 -->
<!-- item 每次取出数据存放的中间遍历 -->
<!-- separator 每次循环之间书写的分隔符 -->
<foreach collection="list" item="author" separator=",">
(#{author.aname},#{author.aage},#{author.atel},#{author.aaddress})
</foreach>
</insert>
批量删除
传入id数组,将指定数组对应id数据删除
<delete id="deleteArray">
delete from author where aid in
<!-- open 在循环开始前添加的数据 -->
<!-- close 在循环结束后添加的数据 -->
<foreach collection="arr" item="i" separator="," open="(" close=")">
#{i}
</foreach>
</delete>