【MyBatis】day03动态SQL和缓存机制

第九章 Mybatis动态SQL【重点】

SQL中注释

//方式一
-- 1=1
//方式二【推荐使用】
<!-- 1=1 -->

9.1 动态SQL概述

  • 动态SQL指的是:SQL语句可动态化

  • Mybatis的动态SQL中支持OGNL表达式语言,OGNL( Object Graph Navigation Language )对象图导航语言

9.2 常用标签

  • if标签:用于完成简单的判断

  • where标签:用于解决where关键字及where后第一个and或or的问题

  • trim标签: 可以在条件判断完的SQL语句前后添加或者去掉指定的字符

    • prefix: 添加前缀

    • prefixOverrides: 去掉前缀

    • suffix: 添加后缀

    • suffixOverrides: 去掉后缀

  • set标签:主要用于解决set关键字及多出一个【,】问题

  • choose标签:类似java中if-else【switch-case】结构

  • foreach标签:类似java中for循环

    • collection: 要迭代的集合

    • item: 当前从集合中迭代出的元素

    • separator: 元素与元素之间的分隔符

    • open: 开始字符

    • close:结束字符

  • sql标签:提取可重用SQL片段

9.3 示例代码

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.atguigu.mybatis.mapper.EmployeeMapper">
    <sql id="emp_col">
        id,
        last_name,
        email,
        salary
    </sql>
    <sql id="select_employee">
        select
            id,
            last_name,
            email,
            salary
        from
            tbl_employee
    </sql>
<!-- 按条件查询员工信息【条件不确定】-->
    <select id="selectEmpByOpr" resultType="employee">
        <include refid="select_employee"></include>
        <where>
            <if test="id != null">
               and id = #{id}
            </if>
            <if test="lastName != null">
                and last_name = #{lastName}
            </if>
            <if test="email != null">
                and email = #{email}
            </if>
            <if test="salary != null">
                and salary = #{salary}
            </if>
        </where>
    </select>

    <select id="selectEmpByOprTrim" resultType="employee">
        <include refid="select_employee"></include>
        <trim prefix="where" suffixOverrides="and">
            <if test="id != null">
                id = #{id} and
            </if>
            <if test="lastName != null">
                last_name = #{lastName} and
            </if>
            <if test="email != null">
                email = #{email} and
            </if>
            <if test="salary != null">
                salary = #{salary}
            </if>
        </trim>
    </select>

    <update id="updateEmpByOpr">
        update
            tbl_employee
        <set>
            <if test="lastName != null">
                last_name=#{lastName},
            </if>
            <if test="email != null">
                email=#{email},
            </if>
            <if test="salary != null">
                salary=#{salary}
            </if>
        </set>
        where
            id = #{id}
    </update>


    <select id="selectEmpByOneOpr" resultType="employee">
        select
            <include refid="emp_col"></include>
        from
            tbl_employee
        <where>
            <choose>
                <when test="id != null">
                    id = #{id}
                </when>
                <when test="lastName != null">
                    last_name = #{lastName}
                </when>
                <when test="email != null">
                    email = #{email}
                </when>
                <when test="salary != null">
                    salary = #{salary}
                </when>
                <otherwise>
                    1=1
                </otherwise>
            </choose>
        </where>
    </select>

    <select id="selectEmpByIds" resultType="employee">
        select
            id,
            last_name,
            email,
            salary
        from
            tbl_employee
        <where>
            id in(
            <foreach collection="ids" item="id" separator=",">
                #{id}
            </foreach>
            )
        </where>

    </select>

    <insert id="batchInsertEmp">
        INSERT INTO
            tbl_employee(last_name,email,salary)
        VALUES
            <foreach collection="employees" item="emp" separator=",">
                (#{emp.lastName},#{emp.email},#{emp.salary})
            </foreach>
    </insert>
</mapper>

第十章 Mybatis中缓存机制

10.1 缓存概述

  • 生活中缓存

    • 缓存一些音频、视频优势

      • 节约数据流量

      • 提高播放性能

  • 程序中缓存【Mybatis缓存】

    • 使用缓存优势

      • 提高查询效率

      • 降低服务器压力

10.2 Mybatis中的缓存概述

  • 一级缓存

  • 二级缓存

  • 第三方缓存

10.3 Mybatis缓存机制之一级缓存

  • 概述:一级缓存【本地缓存(Local Cache)或SqlSession级别缓存】

  • 特点

    • 一级缓存默认开启

    • 不能关闭

    • 可以清空

  • 缓存原理

    • 第一次获取数据时,先从数据库中加载数据,将数据缓存至Mybatis一级缓存中【缓存底层实现原理Map,key:hashCode+查询的SqlId+编写的sql查询语句+参数】

    • 以后再次获取数据时,先从一级缓存中获取,如未获取到数据,再从数据库中获取数据。

  • 一级缓存五种失效情况

    1. 不同的SqlSession对应不同的一级缓存

    2. 同一个SqlSession但是查询条件不同

    3. 同一个SqlSession两次查询期间执行了任何一次增删改操作

    • 清空一级缓存

    1. 同一个SqlSession两次查询期间手动清空了缓存

    • sqlSession.clearCache()

    1. 同一个SqlSession两次查询期间提交了事务

    • sqlSession.commit()

10.4 Mybatis缓存机制之二级缓存

  • 二级缓存【second level cache】概述

    • 二级缓存【全局作用域缓存】

    • SqlSessionFactory级别缓存

  • 二级缓存特点

    • 二级缓存默认关闭,需要开启才能使用

    • 二级缓存需要提交sqlSession或关闭sqlSession时,才会缓存。

  • 二级缓存使用的步骤:

    ① 全局配置文件中开启二级缓存<setting name="cacheEnabled" value="true"/>

    ② 需要使用二级缓存的映射文件处使用cache配置缓存<cache />

    ③ 注意:POJO需要实现Serializable接口

    关闭sqlSession或提交sqlSession时,将数据缓存到二级缓存

  • 二级缓存底层原理

    • 第一次获取数据时,先从数据库中获取数据,将数据缓存至一级缓存;当提交或关闭SqlSession时,将数据缓存至二级缓存

    • 以后再次获取数据时,先从一级缓存中获取数据,如一级缓存没有指定数据,再去二级缓存中获取数据。如二级缓存也没有指定数据时,需要去数据库中获取数据,......

  • 二级缓存相关属性

    • eviction=“FIFO”:缓存清除【回收】策略。

      • LRU – 最近最少使用的:移除最长时间不被使用的对象。

      • FIFO – 先进先出:按对象进入缓存的顺序来移除它们。

    • flushInterval:刷新间隔,单位毫秒

    • size:引用数目,正整数

    • readOnly:只读,true/false

  • 二级缓存的失效情况

    • 在两次查询之间,执行增删改操作,会同时清空一级缓存和二级缓存

    • sqlSession.clearCache():只是用来清除一级缓存。

10.5 Mybatis中缓存机制之第三方缓存

  • 第三方缓存:EhCache

  • EhCache 是一个纯Java的进程内缓存框架

  • 使用步骤

    • 导入jar包

      <!-- mybatis-ehcache -->
      <dependency>
          <groupId>org.mybatis.caches</groupId>
          <artifactId>mybatis-ehcache</artifactId>
          <version>1.0.3</version>
      </dependency>
      
      <!-- slf4j-log4j12 -->
      <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-log4j12</artifactId>
          <version>1.6.2</version>
          <scope>test</scope>
      </dependency>
    • 编写配置文件【ehcache.xml】

      <?xml version="1.0" encoding="UTF-8"?>
      <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
          <!-- 磁盘保存路径 -->
          <diskStore path="E:\mybatis\ehcache" />
      
          <defaultCache
                  maxElementsInMemory="512"
                  maxElementsOnDisk="10000000"
                  eternal="false"
                  overflowToDisk="true"
                  timeToIdleSeconds="120"
                  timeToLiveSeconds="120"
                  diskExpiryThreadIntervalSeconds="120"
                  memoryStoreEvictionPolicy="LRU">
          </defaultCache>
      </ehcache>
    • 加载第三方缓存【映射文件】

    • 开始使用

  • 注意事项

    • 第三方缓存,需要建立在二级缓存基础上【需要开启二级缓存,第三方缓存才能生效】

    • 如何让第三方缓存失效【将二级缓存设置失效即可】

猜你喜欢

转载自blog.csdn.net/weixin_45481821/article/details/130348295