关于Mybatis内置的缓存机制

Mybatis框架是内置缓存机制的,区分为一级缓存和二级缓存。

所有的缓存机制都是为了提高查询/获取数据的效率而存在的。

1.一级缓存 

Mybatis的一级缓存也称之为SqlSession会话缓存,该缓存是Mybatis自动管理的,不需要开发人员自行维护或管理。

2.二级缓存

Mybatis的二级缓存是基于namespace的,所以也称之为namespace缓存,它针对是对应某个接口的XML文件(因为每个配置SQL语句的XML文件的根节点都需要配置namespace属性),如果需要开启namespace缓存,需要在XML文件中显式的添加<cache/>节点,例如:

关于Mybatis内置的缓存机制

一旦开启二级缓存,则当前XML中所有的查询都可以缓存数据!但并不代表所有的查询都会缓存数据!如果某个查询需要缓存数据,则需要在<select>节点上配置useCache="true",例如:

关于Mybatis内置的缓存机制

则Mybatis在执行查询后,就会自动缓存该查询的结果,当后续再次需要执行这项查询时,就会自动将此前查询的结果返回,并不会连接数据库再次查询数据!

注意:在使用二级缓存时,封装查询结果的类型必须实现序列化接口如果没有实现序列化接口,将无法实现缓存,执行查询时会出现异常,例如:

关于Mybatis内置的缓存机制

如果在配置<select>节点时,使用resultMap来映射到一个<resultMap>节点,以指定封装查询结果的映射规则,则<resultMap>中通过type属性配置的类型也需要实现序列化接口!并且,在配置<resultMap>时,必须使用<id>节点来配置主键,或数据的唯一标识字段(例如用户名或手机号)!

在执行单表查询时,如果不考虑缓存数据,在<resultMap>中的<id>节点与<result>节点的配置和效果,从表面看来是没有区别的,也就是说:把<id>节点换成<result>节点,查询并不会受到影响!

需要注意的是:Mybatis也有管理二级缓存的规则,毕竟缓存的数据可能是不准确的(如果数据库中的数据发生了变化,但是缓存的数据没有更新,则缓存的数据不准确),如果是同一个namespace中执行了增、删、改操作,则Mybatis会将当前namespace中执行查询后缓存的数据视为无效!

由于某些数据操作频率可能较高,如果使用缓存,每当数据发生变化,以前的缓存失效,重新缓存,但是,可能缓存的数据都没有被使用,又因为数据再次发生变化而重新缓存,就会导致这个缓存机制没有存在的价值!所以,在这种机制下,并不是所有的数据都适合缓存,需要根据数据发生变化的频率进行评估!

由于在实际应用中,也许并不存在数据是否完全精准,所以,通常会使用其它的缓存机制或实现方案,例如使用Redis来缓存数据!