mysql一级缓存和二级缓存_Mybatis一级缓存和二级缓存

Mybatis一级缓存和二级缓存

缓存到底是什么东西呢??

缓存是数据交换的缓冲区,简单点理解就是存在于内存中的临时数据。

那我们为什么要使用缓存?

例如我们每次查询用户信息,每次都要请求数据库,数据库会编译并执行你的SQL语句,这样效率就会很低。针对一些频繁访问并不经常改变的数据,而且数据量较大的情况,通常做法,就是把他加入缓存,每次取数前先去判断,如果缓存不为空,那么就从缓存取值,如果为空,再去请求数据库,并将数据加入缓存。

缓存的目的就是:减少和数据库的交互次数,提高执行效率。

大概了解了一下缓存的概念我们现在开始聊聊Mybatis中的缓存吧!下面会分别介绍一下Mybatis中的一级缓存和二级缓存。

这里先把目录结构给放出来

mysql一级缓存和二级缓存_Mybatis一级缓存和二级缓存_第1张图片

UserDao接口

public interface UserDao {

/**

* 根据id查询用户信息

*/

User findById(Integer id);

}

User类(实体类)

public class User implements Serializable {

private Integer id;

private String username;

private Date birthday;

private String sex;

private String address;

public User() {

}

为了代码篇幅,这里省略了getter和setter方法

}

Mybatis主配置文件SqlMapConfig.xml

/p>

PUBLIC "-//mybatis.org//DTD Config 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-config.dtd">

UserDao.xml(dao映射文件)

/p>

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

select * from user where id = #{uid}

一级缓存:Mybatis中SqlSession对象的缓存

当我们执行查询之后,查询的结果会同时存入到SqlSession中的一块区域。当我们再次查询同样的数据时,Mybatis会先去SqlSession中查询是否有,有的话就直接使用不用再次请求数据库。

测试一级缓存

一级缓存是 SqlSession范围的缓存,当调用 SqlSession的修改,添加,删除,commit(),close()、clearCache()

通过两次查询同一个id,看第二次是否再次执行了查询语句就可以说明是否使用了一级缓存。也可通过两次是否是同一个对象说明。

public class FirstLevelCacheTest {

InputStream in;

SqlSessionFactoryBuilder builder;

SqlSessionFactory factory;

SqlSession session;

UserDao userDao;

/**

* 标注了Before注解会在执行Test方法之前执行

* @throws Exception

*/

@Before

public void init() throws Exception{

//1.读取配置文件

in = Resources.getResourceAsStream("SqlMapConfig.xml");

//2.创建SqlSessionFactory工厂

builder = new SqlSessionFactoryBuilder();

factory = builder.build(in);

//3.使用工厂生产SqlSession对象

session = factory.openSession();

//4.使用SqlSession创建dao接口代理对象

userDao = session.getMapper(UserDao.class);

}

/**

* 标注了After注解会在执行Test方法之后执行

* @throws Exception

*/

@After

public void destroy()throws Exception{

//提交事务

session.commit();

//6.释放资源

session.close();

in.close();

}

@Test

public void testCache(){

User user1 = userDao.findById(45);

System.out.println(user1);

//此句话为清理缓存

//session.clearCache();

User user2 = userDao.findById(45);

System.out.println(user2);

//通过比较两次是否是同一个对象

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

}

}

结果:

b3169121bff367d28a2ed87346a99dcc.png

mysql一级缓存和二级缓存_Mybatis一级缓存和二级缓存_第2张图片

当我们把session.clearCache();这句话的注释打开,这句话的意思是清理了SqlSession对象缓存,即清理了一级缓存。我们会发现,第二次查询又会请求了数据库。

mysql一级缓存和二级缓存_Mybatis一级缓存和二级缓存_第3张图片

二级缓存:Mybatis中SqlsessionFactory对象的缓存,同一个SqlsessionFactory创建的SqlSession对象共享缓存

要使用Mybatis的二级缓存还需要额外的配置

在Mybatis主配置文件中配置 ,即上面的SqlMapConfig.xml

在dao的映射文件中配置 和在select标签中配置useCache="true",即上面的UserDao.xml

/p>

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

select * from user where id = #{uid}

测试二级缓存

通过同一个SqlSessionFactory对象创建的两个sqlSession测试,

在用sqlSession1执行查询操作之后,我们调用sqlSession1.close(),把一级缓存关闭,第二次用sqlSession2再次进行查询,因为上面已经关闭了一级缓存,而且时不同的sqlSession对象,第二次查询的结果如果没用执行sql语句说明二级缓存生效了!

public class SecondLevelCacheTest {

InputStream in;

SqlSessionFactoryBuilder builder;

SqlSessionFactory factory;

/**

* 标注了Before注解会在执行Test方法之前执行

* @throws Exception

*/

@Before

public void init() throws Exception{

//1.读取配置文件

in = Resources.getResourceAsStream("SqlMapConfig.xml");

//2.创建SqlSessionFactory工厂

builder = new SqlSessionFactoryBuilder();

factory = builder.build(in);

//3.使用工厂生产SqlSession对象

}

/**

* 标注了After注解会在执行Test方法之后执行

* @throws Exception

*/

@After

public void destroy()throws Exception{

in.close();

}

@Test

public void testCache(){

SqlSession sqlSession1 = factory.openSession();

UserDao dao1 = sqlSession1.getMapper(UserDao.class);

User user1 = dao1.findById(45);

sqlSession1.close();

SqlSession sqlSession2 = factory.openSession();

UserDao dao2 = sqlSession2.getMapper(UserDao.class);

User user2 = dao2.findById(45);

sqlSession2.close();

}

}

mysql一级缓存和二级缓存_Mybatis一级缓存和二级缓存_第4张图片

注意:当我们在使用二级缓存时,所缓存的类一定要实现java.io.Serializable接口,这种就可以使用序列化方式来保存对象。

你可能感兴趣的:(mysql一级缓存和二级缓存)