MyBatis延迟加载、动态sql

一、课程目标

【掌握】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>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值