MyBatis缓存(一级缓存和二级缓存)
和大多数持久化框架一样,MyBatis 提供了一级缓存和二级缓存的支持。默认情况下,MyBatis 只开启一级缓存。
一级缓存
一级缓存是基于 PerpetualCache(MyBatis自带)的 HashMap 本地缓存,作用范围为 session 域内。当 session flush(刷新)或者 close(关闭)之后,该 session 中所有的 cache(缓存)就会被清空。在参数和 SQL 完全一样的情况下,我们使用同一个 SqlSession 对象调用同一个 mapper 的方法,往往只执行一次 SQL。因为使用 SqlSession 次查询后,MyBatis 会将其放在缓存中,再次查询时,如果没有刷新,并且缓存没有超时的情况下,SqlSession 会取出当前缓存的数据,而不会再次发送 SQL 到数据库。
由于 SqlSession 是相互隔离的,所以如果你使用不同的 SqlSession 对象,即使调用相同的 Mapper、参数和方法,MyBatis 还是会再次发送 SQL 到数据库执行,返回结果。
示例
本节示例基于《个MyBatis程序》一节的代码实现。在 WebsiteMapper 类中添加 selectWebsiteById 方法,代码如下。
public Website selectWebsiteById(int id);
WebsiteMapper.xml 中添加相应的映射 SQL 语句,代码如下。
<select id="selectWebsiteById"
resultType="net.biancheng.po.Website">
SELECT * FROM website
WHERE id=#{id}
</select>
测试代码如下。
package net.biancheng.test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.log4j.Logger;
import net.biancheng.po.Website;
public class Test {
public static Logger logger = Logger.getLogger(Test.class);
public static void main(String[] args) throws IOException {
InputStream config = Resources.getResourceAsStream("mybatis-config.xml"); // 根据配置文件构建
SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(config);
SqlSession ss = ssf.openSession();
Website site = ss.selectOne("net.biancheng.mapper.WebsiteMapper.selectWebsiteById", 1);
logger.debug("使用同一个sqlsession再执行一次");
Website site2 = ss.selectOne("net.biancheng.mapper.WebsiteMapper.selectWebsiteById", 1);
// 请注意,当我们使用二级缓存的时候,sqlSession调用了 commit方法后才会生效
s网站站点" rel="nofollow" />
从运行结果可以看出,个 SqlSession 实际只发生过一次查询,而第二次查询就从缓存中取出了,也就是 SqlSession 层面的一级缓存。为了克服这个问题,我们往往需要配置二级缓存,使得缓存在 SqlSessionFactory 层面上能够提供给各个 SqlSession 对象共享。DEBUG [main] - ==> Preparing: SELECT * FROM website WHERE id=?
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - <== Total: 1
DEBUG [main] - 使用同一个sqlsession再执行一次
DEBUG [main] - 现在创建一个新的SqlSeesion对象在执行一次
DEBUG [main] - ==> Preparing: SELECT * FROM website WHERE id=?
DEBUG [main] - ==> Parameters: 1(Integer)DEBUG [main] - <== Total: 1
二级缓存
二级缓存是全局缓存,作用域超出 session 范围之外,可以被所有 SqlSession 共享。一级缓存缓存的是 SQL 语句,二级缓存缓存的是结果对象。
二级缓存的配置
1)MyBatis 的全局缓存配置需要在 mybatis-config.xml 的 settings 元素中设置,代码如下。
2)在 mapper 文件(如 WebMapper.xml)中设置缓存,默认不开启缓存。需要注意的是,二级缓存的作用域是针对 mapper 的 namescape 而言,即只有再次在 namescape 内(net.biancheng.WebsiteMapper)的查询才能共享这个缓存,代码如下。<settings>
<setting name="cacheEnabled" value="true" />
</settings>
以上属性说明如下。<mapper namescape="net.biancheng.WebsiteMapper">
<!-- cache配置 -->
<cache
eviction="FIFO"
flushInterval="60000"
size="512"
readOnly="true" />
...
</mapper>
属性 | 说明 |
|---|---|
eviction | 代表的是缓存回收策略,目前 MyBatis 提供以下策略。
|
flushInterval | 刷新间隔时间,单位为毫秒,这里配置的是 100 秒刷新,如果省略该配置,那么只有当 SQL 被执行的时候才会刷新缓存。 |
size | 引用数目,正整数,代表缓存最多可以存储多少个对象,不宜设置过大。设置过大会导致内存溢出。这里配置的是 1024 个对象。 |
readOnly | 只读,默认值为 false,意味着缓存数据只能读取而不能修改,这样设置的好处是可以快速读取缓存,缺点是没有办法修改缓存。 |
3)在 mapper 文件配置支持 cache 后,如果需要对个别查询进行调整,可以单独设置 cache,代码如下。
对于 MyBatis 缓存仅作了解即可,因为面对一定规模的数据量,内置的 Cache 方式就派不上用场了,并且对查询结果集做缓存并不是 MyBatis 所擅长的,它专心做的应该是 SQL 映射。对于缓存,采用 OSCache、Memcached 等专门的缓存服务器来做更为理。<select id="getWebsiteList" resultType="net.biancheng.po.Website" usecache="true">
...
</select>
- 随机文章
- 核心危机(核心危机魔石合成攻略)
- 风儿(风儿轻轻的吹)
- 儿童教育文章(儿童教育)
- 广州4a广告公司(广州4a广告公司创意总监年薪)
- xboxones(xboxone手柄怎么配对主机)
- 兵马俑(兵马俑介绍和历史背景)
- 陈武简历
- 帆船比赛(帆船比赛视频)
- 韩国媳妇和小雪(韩国媳妇和小雪的父亲工资是多少)
- 儋州市第二中学(儋州市第二中学录取分数线)
- 鬼泣5攻略(鬼泣5攻略第三关怎么跳)
- 地球日主题(2020年世界地球日主题)
- 和柳亚子(和柳亚子先生于田)
- 冰客(冰客果汁)
- 国外成人游戏(国外成人游戏注册需要visa信用卡)
- 充值卡代理(充值卡代理加盟)
- 拆奶罩
- 郭妮小说(恶魔的法则郭妮小说)
- 东天目山(东天目山景区)
- 杭同(杭同培训中心怎么样)
- 蝙蝠给人类的一封信(蝙蝠给人类的一封信)
- 大松电饭煲(美的大松电饭煲)
- 服饰加盟(服饰加盟店招商)
- 疯狂填字(疯狂填字5)
- 点对点短信息(点对点短信息费是什么意思)
- 观音普门品(观音普门品念诵全文)
- 河北省大运会(河北省大运会时间)
- 哈利波特官网(哈利波特官网在哪里)
- 骇客神条(骇客神条怎么辨别真假)
- 杜星霖(杜星霖图片)
