16-二级缓存

Posted zuiren

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了16-二级缓存相关的知识,希望对你有一定的参考价值。

二级缓存:

  1. 它指的是 Mybatis 中 SqlSessionFactory 对象的缓存。由同一个 SqlSessionFactory 对象创建的 SqlSession 共享其缓存
  2. 二级缓存的使用步骤
    1. 让 Mybatis 框架支持二级缓存(在SqlMapConfig.xml配置)
    2. 让当前的映射文件支持二级缓存(在IUserDao.xml中配置)
    3. 让当前的操作支持二级缓存(在select标签中配置)

一、SqlMapConfig.xml

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

<configuration>

    <properties resource="jdbcConfig.properties"/>
    
    <settings>
        <!--默认为 true-->
        <setting name="cacheEnabled" value="true"/>
    </settings>
    
    <typeAliases>
        <package name="domain"/>
    </typeAliases>

    <environments default="mysql">
        <environment id="mysql">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="$driver" />
                <property name="url" value="$url"/>
                <property name="username" value="$username"/>
                <property name="password" value="$password"/>
            </dataSource>
        </environment>
    </environments>
    
    <mappers>
        <package name="dao"/>
    </mappers>
</configuration>

二、IUserDao.xml

<?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="dao.IUserDao">
    <!--开启 uer 支持二级缓存-->
    <cache/>

    <!--不管有没有账户,用户的信息都得有,所以不能用内连接,所以用左外连接,会返回左表的所有数据-->

    <select id="findAll" resultType="user">
        select *from user
    </select>

    <select id="findById" parameterType="integer" resultType="user" useCache="true">
        select *from user where id=#userId
    </select>

    <update id="updateUser" parameterType="User">
        update user set username=#username,address=#address where id=#id
    </update>
</mapper>

三、JAVA 代码

    @Test
    public void testFirstLevelCache()
        SqlSession sqlSession1=factory.openSession();
        IUserDao dao1=sqlSession1.getMapper(IUserDao.class);
        User user1=dao1.findById(1);
        System.out.println(user1);
        //一级缓存消失
        sqlSession1.close();

        SqlSession sqlSession2=factory.openSession();
        IUserDao dao2=sqlSession2.getMapper(IUserDao.class);
        User user2=dao2.findById(1);
        System.out.println(user2);
        //一级缓存消失
        sqlSession1.close();

        System.out.println(user1==user2);
    

四、Log 输出

Opening JDBC Connection
[DEBUG] 2019-08-17 09:09:12,364 method:org.apache.ibatis.datasource.pooled.PooledDataSource.popConnection(PooledDataSource.java:424)
Created connection 1634132079.
[DEBUG] 2019-08-17 09:09:12,365 method:org.apache.ibatis.transaction.jdbc.JdbcTransaction.setDesiredAutoCommit(JdbcTransaction.java:100)
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@6166e06f]
[DEBUG] 2019-08-17 09:09:12,369 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
==>  Preparing: select *from user where id=? 
[DEBUG] 2019-08-17 09:09:12,389 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
==> Parameters: 1(Integer)
[DEBUG] 2019-08-17 09:09:12,437 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
<==      Total: 1
domain.User@4d49af10
[DEBUG] 2019-08-17 09:09:12,451 method:org.apache.ibatis.transaction.jdbc.JdbcTransaction.resetAutoCommit(JdbcTransaction.java:122)
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@6166e06f]
[DEBUG] 2019-08-17 09:09:12,451 method:org.apache.ibatis.transaction.jdbc.JdbcTransaction.close(JdbcTransaction.java:90)
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@6166e06f]
[DEBUG] 2019-08-17 09:09:12,452 method:org.apache.ibatis.datasource.pooled.PooledDataSource.pushConnection(PooledDataSource.java:381)
Returned connection 1634132079 to pool.
[DEBUG] 2019-08-17 09:09:12,456 method:org.apache.ibatis.cache.decorators.LoggingCache.getObject(LoggingCache.java:60)
Cache Hit Ratio [dao.IUserDao]: 0.5
domain.User@c540f5a
false

五、总结

  1. 由 log 日志可知总共查询了一次,第二次是从缓存中查询的。
  2. 最后结果为 false,这个是因为二级缓存存储的是数据而不是对象
    1. "id":1,"username":"老王","address":"北京"
    2. 它会在第二次查询的时候创建一个新的对象,再把数据填充进去

以上是关于16-二级缓存的主要内容,如果未能解决你的问题,请参考以下文章

什么是一级缓存,什么是二级缓存?

一级缓存和二级缓存有啥区别

什么是缓存?一级缓存?二级缓存?

谁给我解释一下一级缓存和二级缓存啊~

mybatis二级缓存默认开启吗?

mybatis二级缓存原理