当前位置: 首页 > news >正文

hibernate缓存机制及配置

为什么80%的码农都做不了架构师?>>>   hot3.png

一 简介

在hibernate框架中,使用缓存来减少对数据库的访问,以此来提高响应速度。hibernate中提供了三种缓存可供使用,分别是一级缓存、二级缓存、查询缓存

其中一级缓存是session级别的缓存,缓存周期即为session的寿命。同一个session进行的对象查询,无论是诸如session.get(Class arg0, Seralizable arg1)这样通过session直接调用的方法,还是该session下的query发起的hql查询,包括list查询,被取出的对象或对象集合都会被存在该session下的一级缓存中,以map<key, value>形式存储,key为主键,value为对象。因为key值是主键,所以只有使用主键查询的方法才可以使用该一级缓存,也就是只有三个方法可以使用

session.get(Class arg0, Seralizable arg1);
session.load(Class arg0, Seralizable arg1);
query.iterate();

*注意* query.iterate()与list()方法不同的是,调用时会发出一条sql语句,只查询主键值,并不查询整个对象。在遍历时,会根据主键值先去一级缓存中查找是否有匹配的,若匹配,返回该缓 存,不匹配,则去数据库中进行查询,但此时查询是单独发出一条sql语句,只查询一个对象,查询主键匹配的数据。这意味着,若此时一级缓存没有一条匹配,则整个遍历过程会发出 N + 1 条sql语句,而在最好的情况下则只产生一条查询ID列的sql语句

因为所有查询都放入了一级缓存,大数据量查找可能导致内存溢出,hibernate提供了以下两种方法对一级缓存进行清除

session.clear();
session.evict(arg0);

二级缓存是sessionFactory级别的缓存,缓存周期即为sessionFactory的寿命。二级缓存在使用上类似于一级缓存,只是作用范围不再局限于同一个session,并且需先指定使用的类才可以使用二级缓存。

查询缓存对所有hql发出的查询都有效,前提是必须先设置才能使用,设置方法在下文。设置完后,同样的hql查询就不会在去数据库进行查询。

二 配置及使用测试

以下例程定义了一个简单的POJO类:Position.java,使用JUnit,hibernate版本为hibernate4.14final

1 一级缓存,一级缓存不用进行任何设置,hibernate原生支持:

/**
	 * 一级缓存测试,session级别,同一session下只查询一次,此处只发出一条sql语句
	 * 不需要设置即可使用
	 */
	@Test
	public void testA(){
		Session session = HibernateUtil.getSession();
		Position pos1 = (Position) session.get(Position.class, 22);
		Position pos2 = (Position) session.get(Position.class, 22);
		System.out.println(pos1);
		System.out.println(pos2);
	}

2 二级缓存

/**
	 * 二级缓存测试,sessionFactory级别,不同session下只查询一次,只输出一条sql语句
	 * 二级缓存需进行相关设置
	 * 1 引入jar包:hibernate-ehcache-4.1.4.Final.jar,ehcache-core-2.4.3.jar
	 * 2 在hibernate.cfg.xml文件中开启二级缓存,并指定二级缓存产品提供商
	 *    <property name="hibernate.cache.user_second_level_cache">true</property>
	 *    <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
	 * 3 在hibernate.cfg.xml文件中或者实体类映射文件中指定实体类使用
	 *    <class-cache usage="read-only" class="com.bean.Position"/>
	 *  或者在其映射文件中
	 *    <cache usage="read-only"/>
	 * 4 之前的版本需设置ehcache.xml文件,此处省去,经测试正常
	 */
	@Test
	public void testB(){
		Session session1 = HibernateUtil.getSession();
		Session session2 = HibernateUtil.getSession();
		Position pos1 = (Position) session1.get(Position.class, 1);
		Position pos2 = (Position) session2.get(Position.class, 1);
		System.out.println(pos1);
		System.out.println(pos2);
	}

3 查询缓存

/**
	 * 查询缓存测试
	 * 1 使用前需开启二级缓存
	 * 2 在hibernate.cfg.xml文件中开启查询缓存
	 *    <property name="hibernate.cache.use_query_cache">true</property>
	 * 3 在query在query.setCacheable(true),即使用查询缓存
	 * 4 这样相同的hql语句就不会再去数据库查询
	 */
	@Test
	public void testC(){
		Session session = HibernateUtil.getSession();
		String hql = "from Position";
		List<Position> list1 = session.createQuery(hql).setCacheable(true).list();
		List<Position> list2 = session.createQuery(hql).setCacheable(true).list();
		System.out.println(list1);
		System.out.println(list2);
	}

4 iterator测试

/**
	 * 因为list()查询完后结果保存在缓存了,此处在list()后只有一条sql语句
	 */
        @Test
	public void testD(){
		Session session = HibernateUtil.getSession();
		String hql = "from Position";
		List<Position> list = session.createQuery(hql).list();
		System.out.println(list);
		Iterator<Position> iterator = session.createQuery(hql).iterate();
		System.out.println("--- iterator ");
		while(iterator.hasNext()){
			System.out.println("Iterator " + iterator.next());
		}
	}


转载于:https://my.oschina.net/idaren/blog/622443

相关文章:

  • 独立制作人
  • 一分钟了解阿里云产品:批量计算五大热点技术问题分析
  • 发表学术论文必须做的十件事(下)(转)
  • Oracle Help Center
  • WebService的初级学习
  • ZOJ1372 POJ 1287 Networking 网络设计 Kruskal算法
  • UVA 10689 Yet another Number Sequence
  • Web 服务器基准测试,nginx+php vs Apache+php
  • 如何使用一台PC搭建可以在线迁移的KVM学习环境
  • 【转】linux(Ubuntu)配置svn仓库,搭建svn服务器
  • JQuery判断数组中是否包含某个元素$.inArray(元素字符串, 数组名称);
  • eclipse安装pydev
  • 看opengl写代码(7) 使用混合数组(glInterLeavedArrays)
  • 将已有项目导入Gitlab
  • innerText兼容处理
  • [rust! #004] [译] Rust 的内置 Traits, 使用场景, 方式, 和原因
  • Android 初级面试者拾遗(前台界面篇)之 Activity 和 Fragment
  • Brief introduction of how to 'Call, Apply and Bind'
  • github从入门到放弃(1)
  • JavaScript标准库系列——Math对象和Date对象(二)
  • JavaScript创建对象的四种方式
  • Java应用性能调优
  • Mysql数据库的条件查询语句
  • Promise面试题2实现异步串行执行
  • Puppeteer:浏览器控制器
  • rabbitmq延迟消息示例
  • React16时代,该用什么姿势写 React ?
  • Theano - 导数
  • Zsh 开发指南(第十四篇 文件读写)
  • 代理模式
  • 后端_ThinkPHP5
  • 技术攻略】php设计模式(一):简介及创建型模式
  • 前端学习笔记之原型——一张图说明`prototype`和`__proto__`的区别
  • 如何在GitHub上创建个人博客
  • 如何抓住下一波零售风口?看RPA玩转零售自动化
  • 我的面试准备过程--容器(更新中)
  • 找一份好的前端工作,起点很重要
  • 看到一个关于网页设计的文章分享过来!大家看看!
  • 你学不懂C语言,是因为不懂编写C程序的7个步骤 ...
  • #QT(一种朴素的计算器实现方法)
  • #快捷键# 大学四年我常用的软件快捷键大全,教你成为电脑高手!!
  • #前后端分离# 头条发布系统
  • $redis-setphp_redis Set命令,php操作Redis Set函数介绍
  • (Matalb回归预测)PSO-BP粒子群算法优化BP神经网络的多维回归预测
  • (PyTorch)TCN和RNN/LSTM/GRU结合实现时间序列预测
  • (Redis使用系列) Springboot 整合Redisson 实现分布式锁 七
  • (笔记)Kotlin——Android封装ViewBinding之二 优化
  • (附源码)springboot 房产中介系统 毕业设计 312341
  • (考研湖科大教书匠计算机网络)第一章概述-第五节1:计算机网络体系结构之分层思想和举例
  • (离散数学)逻辑连接词
  • (六) ES6 新特性 —— 迭代器(iterator)
  • (十)T检验-第一部分
  • (算法设计与分析)第一章算法概述-习题
  • (一)使用Mybatis实现在student数据库中插入一个学生信息
  • .360、.halo勒索病毒的最新威胁:如何恢复您的数据?