Mybatis的缓存

Mybatis中具有一级缓存二级缓存

一级缓存

一级缓存是SqlSession级别的缓存,只要SqlSession缓存没有被清除,则一级缓存就存在

  1. 编写账户实体类
package com.liang.domain;

import java.io.Serializable;

/**
 * 账户实体类
 */
public class Account implements Serializable {

    private int id;
    private int uid;
    private Double money;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getUid() {
        return uid;
    }

    public void setUid(int uid) {
        this.uid = uid;
    }

    public Double getMoney() {
        return money;
    }

    public void setMoney(Double money) {
        this.money = money;
    }

    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", uid=" + uid +
                ", money=" + money +
                '}';
    }
}
  1. 编写持久层接口
package com.liang.dao;

import com.liang.domain.Account;

import java.util.List;

/**
 * 账户的持久层接口
 */
public interface AccountDao {

    /**
     * 通过用户id查询账户信息
     * @param uid
     * @return
     */
    List<Account> findByUid(int uid);
}
  1. 编写用户持久层映射文件
<?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.liang.dao.AccountDao">

    <select id="findByUid" parameterType="int" resultType="com.liang.domain.Account">
        select *from account where uid = #{uid}
    </select>

</mapper>
  1. 编写测试方法、
 /**
     * 查询所有用户信息
     */
    @Test
    public void testFindAll() {
        List<Account> accounts = accountDao.findByUid(41);
        List<Account> accounts1 = accountDao.findByUid(41);
        if(accounts == accounts1)
        {
            System.out.println("accounts 和 accounts1 是同一个对象");
        }
    }

测试结果:
在这里插入图片描述
用上面的程序可以看出,调用了两次查询方法,但是实际只执行了一次SQL语句,这就是因为一级缓存的作用。一级缓存是SqlSession范围的缓存,所以SqlSession缓存没有被清除,当第二次执行相同的代码,MyBatis会从缓存中获取数据,而不是去数据库。
当对测试代码进行如下修改:

  /**
     * 查询所有用户信息
     */
    @Test
    public void testFindAll() {
        List<Account> accounts = accountDao.findByUid(41);
        sqlSession.clearCache();//清除缓存
        List<Account> accounts1 = accountDao.findByUid(41);
        if(accounts == accounts1)
        {
            System.out.println("accounts 和 accounts1 是同一个对象");
        }
    }

清除了SqlSession的缓存,则测试结果如下:
在这里插入图片描述
可见清楚缓存后,会执行两次数据库的查询。
当调用SqlSession的修改,添加,删除,commit(),close等方法时候,就会清除一级缓存,这样主要是为了让缓存中存储的数据是最新的数据,避免脏读。
测试一级缓存的清空
5. 持久层接口中添加方法

   /**
     * 更新账户信息
     * @param account
     */
    void updateAccount(Account account);
  1. 持久层接口对应的映射文件添加
  <update id="updateAccount" parameterType="com.liang.domain.Account">
       update  account set MONEY = #{money} where id = #{id}
    </update>
  1. 测试方法修改
   /**
     * 查询所有用户信息
     */
    @Test
    public void testFindAll() {
        List<Account> accounts = accountDao.findByUid(41);
        testUpdate();
        List<Account> accounts1 = accountDao.findByUid(41);
        if(accounts == accounts1)
        {
            System.out.println("accounts 和 accounts1 是同一个对象");
        }
    }

    /**
     * 更新账户信息
     */
    public void testUpdate()
    {
        Account account = new Account();
        account.setId(1);
        account.setMoney(200.0);
        accountDao.updateAccount(account);
    }

测试如下:
在这里插入图片描述
可以看出更新数据后,第二次根据用户id查询账户信息的数据来自于数据库查询,而不是缓存数据。

二级缓存

Mybatis的二级缓存指的是SqlSessionFactory对象的缓存,由同一个SqlSessionFactory对象创建的SqlSession共享其缓存。

  1. Mybatis配置文件中开启二级缓存
 <settings>
        <!--开启二级缓存的支持-->
        <setting name="cacheEnabled" value="true"/>
    </settings>
  1. 配置相关的持久层映射文件
    在这里插入图片描述
  2. 编写测试方法
  @Test
    public void testSecondLevelCache()
    {
        SqlSession sqlSession1 = sqlSessionFactory.openSession();
        AccountDao accountDao1 = sqlSession1.getMapper(AccountDao.class);
        List<Account> accounts1 = accountDao1.findByUid(41);
        System.out.println(accounts1);
        sqlSession1.close();

        SqlSession sqlSession2 = sqlSessionFactory.openSession();
        AccountDao accountDao2 = sqlSession2.getMapper(AccountDao.class);
        List<Account> accounts2 = accountDao2.findByUid(41);
        System.out.println(accounts2);
        sqlSession1.close();
        System.out.println(accounts1 == accounts2);
    }

测试结果:在这里插入图片描述
可见:SQL语句执行了一次,说明第二次数据来自于缓存
使用二级缓存时,所缓存的类一定要实现java.io.Serializable接口,因为二级缓存存放的是被序列化数据,而不是对象

通过注解配置二级缓存

1.在MyBatis配置文件中开启二级缓存

 <settings>
        <!--开启二级缓存的支持-->
        <setting name="cacheEnabled" value="true"/>
    </settings>

2.在持久层接口中通过注解配置二级缓存
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值