最近学习mybatis的时候了解到的一级缓存与二级缓存的概念,这也是面试官常问的一个问题。以下是我个人的一些见解与学习总结,欢迎各位大神前来指导。
1. 什么是mybatis
概念:
mybatis是一款优秀的持久层框架,并且支持定制化 SQL、存储过程以及高级映射。
mybatis 几乎避免了所有的 JDBC 代码和手动设置参数以及获取结果集。还可以使用简单的 XML 或者是注解来配置和映射一些信息,将接口和普通的对象映射为数据库中的记录。
特点:
1.简单易学
2.灵活
3.解除sql与程序代码的耦合
4.提供映射标签,支持对象与数据库的ORM字段关系映射。
5.提供对象关系映射标签,支持对象关系组建维护。
6.提供xml标签,支持编写动态sql。
2.使用mybatis的流程
(1)加载配置并初始化
将SQL的配置信息加载成为一个个MappedStatement对象存储在内存中。例如传入参数映射配置、执行的SQL语句、结果映射配置,
(2)接收调用请求
调用Mybatis提供的API,参数是SQL的ID和传入参数对象,然后将请求传递给下层的请求处理层进行处理。
(3)处理操作请求
API接口层传递请求过来,参数是SQL的ID和传入参数对象
处理过程:
- 根据SQL的ID查找对应的MappedStatement对象。
- 根据传入参数对象解析MappedStatement对象,得到最终要执行的SQL和执行传入参数。
- 获取数据库连接,根据得到的最终SQL语句和执行传入参数到数据库执行,并得到执行结果。
- 根据MappedStatement对象中的结果映射配置对得到的执行结果进行转换处理,并得到最终的处理结果。
- 释放连接资源。
(4)返回处理结果将最终的处理结果返回。
3.mybatis的缓存
Mybatis对缓存提供支持,一级缓存是默认使用的,二级缓存需要手动开启。
区别:
- 一级缓存的作用域是一个sqlsession内;
- 二级缓存作用域是针对mapper进行缓存;
一级缓存
一级缓存的作用域是SqlSession范围的,在参数和SQL完全一样的情况下,使用同一个sqlSession中执行两次相同的sql语句时,第一次执行完毕会将数据库中查询的数据写到缓存(内存),
第二次查询时SqlSession都会取出当前缓存的数据,不再去底层数据库查询。
如果SqlSession执行了增删改操作,并且提交到数据库,MyBatis就会清空SqlSession中的一级缓存,这样做的目的是为了保证缓存中存储的是最新的信息,避免出现脏读现象。
当一个SqlSession结束后该SqlSession中的一级缓存也就不存在了。
关闭一级缓存后,再次访问,需要再次获取一级缓存,然后才能查找数据,否则会抛出异常。
二级缓存:
二级缓存指的就是同一个namespace下的mapper,二级缓存中,也有一个map结构,这个区域就是一级缓存区域。一级缓存中的key是由sql语句、条件、statement等信息组成一个唯一值。一级缓存中的value,就是查询出的结果对象。
代码
<settings>
<!-- 开启二级缓存 -->
<setting name="cacheEnabled" value="true" />
</settings>
public void getEmpById() {
SqlSession session = MybatisUtils.createSqlSession();
long startTime1=System.currentTimeMillis();
Emp emp = new Emp();
emp.setEname("王依");
emp.setJob("后勤");
Emp es = session.getMapper(EmpMapper.class).getEmpById(emp);
System.out.println(es);
System.out.println("第一次执行时间:"+(System.currentTimeMillis()-startTime1));
long startTime2=System.currentTimeMillis();
Emp emp1 = new Emp();
emp.setEname("王依");
emp.setJob("后勤");
Emp ess = session.getMapper(EmpMapper.class).getEmpById(emp);
System.out.println(ess);
System.out.println("第二次执行时间:"+(System.currentTimeMillis()-startTime2));
MybatisUtils.closeSqlSession(session);
}
由此,我们可以知道,第一次执行时经过了数据库,但第二次执行时为二次缓存