- 浏览: 188174 次
- 性别:
- 来自: 青岛
-
文章分类
- 全部博客 (117)
- java基础知识 (17)
- 技术积攒 (9)
- Oracle技术 (4)
- JSP技术 (6)
- Spring技术 (15)
- Linux技术 (6)
- Hibernate技术 (24)
- JPA技术 (1)
- Struts技术 (1)
- Struts2技术 (6)
- javascript知识 (4)
- myeclipse 使用技巧 (3)
- JavaEE技术 (2)
- JSTL (1)
- javamail技术 (1)
- jaf 技术 (1)
- 测试方法 (1)
- web技术积攒 (1)
- tomcat事项 (5)
- mysql使用 (1)
- 趣味题目 (2)
- 技术词汇 (1)
- EJB3.0 (2)
- weblogic 使用说明 (1)
- CSS (1)
最新评论
-
chenhao_java:
知识点五:依赖注入-自动装配依赖对象 -
黑白配:
为什么没有看见三个附件呢?
JavaMail jsp发送邮件 html格式 -
chunchong:
真晕,这样怎么能行呢
JAVA中防止SQL注入攻击类的源代码 -
Rod_johnson:
学习了!真不错
Hibernate:类继承的实现方式(二)--父子类各自一个表 -
erchong2011:
恩 很不错 学习了 简单
jsp页面自动跳转方式
缓存是介于应用程序和物理数据源之间,其作用是为了降低应用程序对物理数据源访问的频次,从而提高了应用的运行性能。缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事件会同步缓存和物理数据源的数据。
缓存的介质一般是内存,所以读写速度很快。但如果缓存中存放的数据量非常大时,也会用硬盘作为缓存介质。缓存的实现不仅仅要考虑存储的介质,还要考虑到管理缓存的并发访问和缓存数据的生命周期。
hibernate 一级缓存:(缓存的是实体对象)
一级缓存很短和session的生命周期一致,一级缓存也叫session级的缓存或事务缓存
哪些方法支持一级缓存:
*get()
*load()
*iterate() (查询实体对象)
如何管理一级缓存:
* session.clear() session.evict()
如何避免一次性大量的实体数据入库导致内存溢出
*先flush,再clear
如果数据量特别大,考虑采用jdbc实现,如果jdbc也不能满足要求,可以考虑采用数据库本身的特定导入工具
一.Load测试: 在同一个session中发出两次load查询
Student sutdent = (Student)session.load(Student.class,1); System.out.println(student.getName()); sutdent = (Student)session.load(Student.class,1); System.out.println(student.getName());
在同一个session中发出两次load查询,第一次load的时候不会去查询数据库,因为他是LAZY的,当使用的时候才去查询数据库, 第二次load的时候也不会,当使用的时候也不会查询数据库,因为他在缓存里找到,不会发出sql
Load测试: 开启两个session中发出两次load查询
Student sutdent = (Student)session.load(Student.class,1); System.out.println(student.getName()); sessioin.close(); ……….. sutdent = (Student)session.load(Student.class,1); System.out.println(student.getName());
开启两个session中发出两次load查询,第一次load的时候不会去查询数据库,因为他是LAZY的,当使用的时候才去查询数据库, 第二次load的时候也不会,当使用的时候查询数据库,因为session间不能共享一级缓存的数据,因为他会随session的生命周期存在和消亡
二.Get测试: 在同一个session中发出两次get查询
Student sutdent = (Student)session.get(Student.class,1); System.out.println(student.getName()); sutdent = (Student)session.get(Student.class,1); System.out.println(student.getName());在同一个session中发出两次get查询, 第一次get的时候去查询数据库,第二次get的时候不会查询数据库,因为他在缓存里找到,不会发出sql
三.iterate测试: 在同一个session中发出两次iterator查询
Student student = (Student)session.createQuery(“from Student s where s.id=1”).iterate().next(); System.out.println(student.getName()); student = (Student)session.createQuery(“from Student s where s.id=1”).iterate().next(); System.out.println(student.getName());
在同一个session中发出两次iterator查询,第一次iterate().next()的时候会发出查询id的sql,使用的时候会发出相应的查询实体对象,第二次iterate().next()的时候会发出查询id的sql,不会发出查询实体对象的sql,因为iterate使用缓存,不会发出sql
四.Iterate查询属性测试: 同一个session中发出两次查询属性
String name = (String)session.createQuery(“select s.name from Student s where s.id=1”).iterate().next(); System.out.println(name); String name = (String)session.createQuery(“select s.name from Student s where s.id=1”).iterate().next(); System.out.println(name);
在同一个session中发出两次查询属性, 第一次iterate().next()的时候会发出查询属性的sql,第二次iterate().next()的时候会发出查询属性的sql,iterate查询普通属性,一级缓存不会缓存,所以会发出sql
五.同一个session中先save,再发出load查询save过的数据
Student stu = new Student(); stu.setName(“王五”); Serializable id = session.save(stu); Student sutdent = (Student)session.load(Student.class,id); System.out.println(student.getName());
save的时候,他会在缓存里放一份,不会发出sql,因为save是使用缓存的
六.同一个session中先调用load查询,然后执行sessio.clear()或session.evict(),再调用load查询
Student sutdent = (Student)session.load(Student.class,1); System.out.println(student.getName()); session.clear(); Student sutdent = (Student)session.load(Student.class,1); System.out.println(student.getName());
sessio.clear()或session.evict()可以管理一级缓存,一级缓存无法取消,但可以管理.
上面的语句都会发出sql 因为一级缓存中的实体被清除了
七.向数据库中批量加入1000条数据
for(int i=0;i<1000;i++){ Student student = new Student(); student.setName(“s” + i); session.save(student); //每20条数据就强制session将数据持久化,同时清除缓存,避免大量数据造成内存溢出 if( i %20 == 0 ){ session.flush(); session.clear(); } }
=========================================================================================
hibernate 二级缓存:(缓存的是实体对象,二级缓存是放变化不是很大的数据)


二级缓存也称进程级的缓存或SessionFactory级的缓存,而二级缓存可以被所有的session(hibernate中的)共享二级缓存的生命周期和SessionFactory的生命周期一致,SessionFactory可以管理二级缓存
二级缓存的配置和使用:
1.将echcache.xml文件拷贝到src下, 二级缓存hibernate默认是开启的,手动开启
2.开启二级缓存,修改hibernate.cfg.xml文件,
<property name=”hibernate.cache.user_second_level_cache”>true</property>
3.指定缓存产品提供商
<property name=”hibernate.cache.provider_calss”>org.hibernate.cache.EhCacheProvider</property>
4.指定那些实体类使用二级缓存(两种方法,推荐使用第二种)
第一种:在*.hbm.xml中,在<id>之前加入
<cache usage=”read-only” />, 使用二级缓存
第二种:在hibernate.cfg.xml配置文件中,在<mapping resource=”com/Studnet.hbm.xml” />后面加上:
<class-cache class=” com.Studnet” usage=”read-only” />
二级缓存是缓存实体对象的
了解一级缓存和二级缓存的交互
测试二级缓存:
一.开启两个session中发出两次load查询(get与load一样,同样不会查询数据库),
Student sutdent = (Student)session.load(Student.class,1); System.out.println(student.getName()); sessioin.close(); ……….. sutdent = (Student)session.load(Student.class,1); System.out.println(student.getName());
开启两个session中发出两次load查询,第一次load的时候不会去查询数据库,因为他是LAZY的,当使用的时候才去查询数据库, 第二次load的时候也不会,当使用的时候查询数据库,开启了二级缓存,也不会查询数据库。
二.开启两个session,分别调用load,再使用sessionFactory清楚二级缓存
Student sutdent = (Student)session.load(Student.class,1); System.out.println(student.getName()); sessioin.close(); ……….. SessionFactory factory = HibernateUtil.getSessionFactory(); //factory.evict(Student.class); //清除所有Student对象 Factory.evict(Student.class,1); //清除指定id=1 的对象 sutdent = (Student)session.load(Student.class,1); System.out.println(student.getName());
开启两个session中发出两次load查询,第一次load的时候不会去查询数据库,因为他是LAZY的,当使用的时候才去查询数据库, 第二次load的时候也不会,当使用的时候查询数据库,它要查询数据库,因为二级缓存中被清除了
三.一级缓存和二级缓存的交互
session.setCacheMode(CacheMode.GET); //设置成 只是从二级缓存里读,不向二级缓存里写数据
Student sutdent = (Student)session.load(Student.class,1); System.out.println(student.getName()); sessioin.close(); ……….. SessionFactory factory = HibernateUtil.getSessionFactory(); //factory.evict(Student.class); //清除所有Student对象 Factory.evict(Student.class,1); //清除指定id=1 的对象 sutdent = (Student)session.load(Student.class,1); System.out.println(student.getName());
开启两个session中发出两次load查询,第一次load的时候不会去查询数据库,因为他是LAZY的,当使用的时候才去查询数据库, 第二次load的时候也不会,当使用的时候查询数据库,它要查询数据库,因为 设置了CacheMode为GET,(load设置成不能往二级缓冲中写数据), 所以二级缓冲中没有数据
session.setCacheMode(CacheMode.PUT); //设置成只是向二级缓存里写数据,不读数据 Student sutdent = (Student)session.load(Student.class,1); System.out.println(student.getName()); sessioin.close(); ……….. SessionFactory factory = HibernateUtil.getSessionFactory(); //factory.evict(Student.class); //清除所有Student对象 Factory.evict(Student.class,1); //清除指定id=1 的对象 sutdent = (Student)session.load(Student.class,1); System.out.println(student.getName());
开启两个session中发出两次load查询,第一次load的时候不会去查询数据库,因为他是LAZY的,当使用的时候才去查询数据库, 第二次load的时候也不会,当使用的时候查询数据库,它要查询数据库,因为设置了CacheMode为POST,(load设置成只是向二级缓存里写数据,不读数据)
====================================================================================
hibernate查询缓存(hibernate默认是关闭的)
查询缓存是针对普通属性结果集的缓存
对实体对象的结果集只缓存id
查询缓存的生命周期,当前关联的表发生修改,那么查询缓存生命周期结束
查询缓存的配置和使用:
1. 启用查询缓存:在hibernate.cfg.xml中加入:
<property name=”hibernate.cache.use_query_cache”>true</property>
2. 在程序中必须手动启用查询缓存,如:query.setCacheable(true);
测试查询缓存:
一. 开启查询缓存,关闭二级缓存,开启一个session,分别调用query.list (查询属性)
Query query = session.createQuery(“select s.name from Student s”); //启用查询缓存 query.setCacheable(true); List names = query.list(); for(Iterator iter = names.terator();iter.hasNext();){ String name = (String)iter.next(); System.out.println(name); } System.out.println(“------------------------------------------”); query = session.createQuery(“select s.name from Student s”); //启用查询缓存 query.setCacheable(true); names = query.list(); for(Iterator iter = names.terator();iter.hasNext();){ String name = (String)iter.next(); System.out.println(name); }
第二次没有去查询数据库,因为启用了查询缓存
二. 开启查询缓存,关闭二级缓存,开启两个session,分别调用query.list (查询属性)
Query query = session.createQuery(“select s.name from Student s”); //启用查询缓存 query.setCacheable(true); List names = query.list(); for(Iterator iter = names.terator();iter.hasNext();){ String name = (String)iter.next(); System.out.println(name); } session.close(); System.out.println(“------------------------------------------”); ……… Query query = session.createQuery(“select s.name from Student s”); //启用查询缓存 query.setCacheable(true); List names = query.list(); for(Iterator iter = names.terator();iter.hasNext();){ String name = (String)iter.next(); System.out.println(name); }
第二次没有去查询数据库,因为查询缓存生命周期与session生命周期无关
三. 开启查询缓存,关闭二级缓存,开启两个session,分别调用query.iterate (查询属性)
Query query = session.createQuery(“select s.name from Student s”); //启用查询缓存 query.setCacheable(true); for(Iterator iter =query.iterate();iter.hasNext();){ String name = (String)iter.next(); System.out.println(name); } session.close(); System.out.println(“------------------------------------------”); ……… Query query = session.createQuery(“select s.name from Student s”); //启用查询缓存 query.setCacheable(true); for(Iterator iter = query.iterate();iter.hasNext();){ String name = (String)iter.next(); System.out.println(name); }
第二去查询数据库,因为查询缓存只对query.list()起作用,对query.iterate()不起作用,也就是说query.iterate()不使用查询缓存
四. 关闭查询缓存,关闭二级缓存,开启两个session,分别调用query.list (查询实体对象)
Query query = session.createQuery(“ from Student s”); //query.setCacheable(true); List students = query.list(); for(Iterator iter = students.iterate();iter.hasNext();){ Student stu = (Student)iter.next(); System.out.println(stu.getName()); } session.close(); System.out.println(“------------------------------------------”); ……… Query query = session.createQuery(“ from Student s”); //query.setCacheable(true); List students = query.list(); for(Iterator iter = students.iterate();iter.hasNext();){ Student stu = (Student)iter.next(); System.out.println(stu.getName()); }
第二去查询数据库,因为list默认每次都会发出查询sql
五. 开启查询缓存,关闭二级缓存,开启两个session,分别调用query.list (查询实体对象)
Query query = session.createQuery(“ from Student s”); query.setCacheable(true); List students = query.list(); for(Iterator iter = students.iterate();iter.hasNext();){ Student stu = (Student)iter.next(); System.out.println(stu.getName()); } session.close(); System.out.println(“------------------------------------------”); ……… Query query = session.createQuery(“ from Student s”); query.setCacheable(true); List students = query.list(); for(Iterator iter = students.iterate();iter.hasNext();){ Student stu = (Student)iter.next(); System.out.println(stu.getName()); }
第二去查询数据库时,会发出N条sql语句,因为开启了查询缓存,关闭了二级缓存,那么查询缓存会缓存实体对象的id,所以hibernate会根据实体对象的id去查询相应的实体,如果缓存中不存在相应的实体,那么将发出根据实体id查询的sql语句,否则不会发出sql,使用缓存中的数据
六. 开启查询缓存,开启二级缓存,开启两个session,分别调用query.list (查询实体对象)
Query query = session.createQuery(“ from Student s”); query.setCacheable(true); List students = query.list(); for(Iterator iter = students.iterate();iter.hasNext();){ Student stu = (Student)iter.next(); System.out.println(stu.getName()); } session.close(); System.out.println(“------------------------------------------”); ……… Query query = session.createQuery(“ from Student s”); query.setCacheable(true); List students = query.list(); for(Iterator iter = students.iterate();iter.hasNext();){ Student stu = (Student)iter.next(); System.out.println(stu.getName()); }
第二不会发出sql,因为开启了二级缓存和查询缓存,查询缓存缓存了实体对象的id列表,hibernate会根据实体对象的id列表到二级缓存中取得相应的数据
发表评论
-
关于Hibernate一个配置参数hibernate.hbm2ddl.auto
2010-03-02 08:43 1170<?xml version="1.0" ... -
Hibernate 复合主键
2009-09-25 09:13 1589[zt]hibernate复合主键 key words:hi ... -
映射文件class元素的dymanic-insert和dymanic-update的作用
2009-06-05 09:36 945SQL update语句是预先生成的,如果加上dynamic的 ... -
hibernate的各种保存方式的区别
2009-06-05 08:59 691hibernate的保存 hibernate对于对象的保存提供 ... -
one-to-many的懒加载及原理分析
2009-06-04 14:42 933如果是一对多,多对一,甚至是多对多那效率就差别大了!!如果一对 ... -
one-to-one的懒加载及原理分析
2009-06-04 13:57 1053Lazy=”” :告诉hibernate什么时候抓取 1 fa ... -
load方法的懒加载及原理分析
2009-06-04 11:09 1842懒加载: load方法与get ... -
Hibernate:类继承的实现方式(四)--每个具体类映射一张独立表
2009-06-04 10:58 1046这种方式会把继承链的所有类保持到数据库中单独的表中,而且标语表 ... -
Hibernate:类继承的实现方式(三)--鉴别器与内连接相结合
2009-06-04 10:49 1137当子类中有的有很多自己特有的属性,而部分子类有较少的自己的属性 ... -
Hibernate:类继承的实现方式(二)--父子类各自一个表
2009-06-04 10:41 1418将继承链中的各个类映射到数据库中的一个单独的表中 domai ... -
Hibernate:类继承的实现方式(一)--父子类在同一个表中
2009-06-04 10:19 1929Hibernate对继承关系的对象的处理分为多种形式: 第一 ... -
cascade和inverse
2009-06-04 09:10 1398Cascade与inverse这两个属性都用于一对多或者多对多 ... -
关联关系的级联操作
2009-06-03 17:17 879Cascade和inverse (Employee-Depar ... -
POJO对象与映射文件 : 集合映射
2009-06-03 15:36 1264集合属性大致有两种:第一种是单纯的集合属性,如像 List、S ... -
关联关系的总结
2009-06-03 14:50 804查询的时候出现sql语句的条数: Hibernate查询输出 ... -
将一个对象(组件)作为属性,但是不想建立这个表
2009-06-03 14:38 845如果对象的某个属性为一个对象,而且不想单独对该对象建立一个表, ... -
Hibernate:多对多
2009-06-03 14:10 1077Hibernate处理多对多的情况,在操作和性能方面都不太理想 ... -
Hibernate:一对一(2)
2009-06-03 11:11 816Hibernate处理一对一的另外一种方式是:将多对一加上唯一 ... -
Hibernate:多对一
2009-06-03 11:05 923Hibernate对多对一有两种,分为单向和双向。一般都是采用 ... -
Hibernate:一对一(1)
2009-06-03 10:40 834Hibernate中一对一关联两种处理方式之一:参照表主键参照 ...
相关推荐
7. **性能优化**:讨论Hibernate的缓存机制,包括第一级缓存和第二级缓存,以及如何通过配置和设计优化提升系统性能。 8. **案例实战**:通过实际项目或示例,演示如何在开发中应用Hibernate,解决常见问题。 通过...
这包括了Hibernate的XML配置文件(hibernate.cfg.xml),用于设置数据库连接、方言、缓存等信息;以及实体类的注解或XML映射文件(.hbm.xml),用于定义对象与表之间的映射关系。这些配置文件是使用Hibernate的第一...
- **提高效率**: 通过缓存机制、懒加载等技术,Hibernate 可以有效提高应用程序性能。 - **增强可维护性**: 采用 ORM 技术后,代码结构更加清晰,便于维护和扩展。 #### 本书特色 - **专注 Hibernate**: 本书重点...
6. **缓存机制**:解析Hibernate的缓存策略,包括一级缓存(Session缓存)和二级缓存(如Ehcache、Infinispan),以及缓存的配置和使用。 7. **性能优化**:讨论如何通过优化配置、批处理、延迟加载、懒加载等手段...
Hibernate提供了第一级缓存和第二级缓存,以及查询缓存的配置和使用。 6. **Chapter 7**:在这一部分,作者可能讲解了多态性在Hibernate中的应用,以及集合映射的高级特性,如元素类型、Map的映射等。 7. **...
7:Hibernate查询缓存Query Cache及实现
### 深入理解Hibernate缓存 #### 一、Hibernate缓存概述 Hibernate作为一款流行的Java持久层框架,为开发者提供了高效且灵活的数据访问能力。其中,缓存机制是Hibernate性能优化的重要组成部分之一。理解Hibernate...
5. **第二级缓存**:Hibernate支持查询结果的缓存,可以显著提高系统性能,特别是对于经常被查询但很少修改的数据。 6. **实体生命周期管理**:Hibernate自动管理对象的状态,包括瞬态、持久化、托管和脱管四种状态...
这包括选择合适的缓存插件、设置合理的缓存策略等。 - **监控与调试**:通过对缓存的监控,可以及时发现潜在的问题并进行优化调整。例如,监控缓存命中率可以帮助评估缓存的有效性。 #### 七、总结 缓存是提高应用...
Hibernate缓存机制是提高应用程序性能的关键特性,尤其是在频繁与数据库交互的应用中。缓存通过减少对物理数据库的直接访问次数,显著提升了数据读取和写入的速度。这主要是因为从缓存中读取数据比从数据库中获取更...
3. Hibernate配置:学习如何配置Hibernate,包括hibernate.cfg.xml文件的编写,数据库连接参数的设置,以及实体类的配置。此外,还有程序化配置和基于Java的配置方式。 4. CRUD操作:掌握使用Hibernate进行创建...
hibernate008:查询 hibernate009 示例:spring hibernate010 事务示例:dbUnit 单元测试示例 hibernate011:拦截器中的事件示例 hibernate012:hibernate 验证器示例 hibernate013:hibernate 缓存搜索示例 ...
Ehcache.xml文件就是用于配置Ehcache作为二级缓存的配置文件,其中会包含缓存策略、大小限制、过期策略等设置。 **查询缓存**: 查询缓存主要用于存储查询结果,当执行相同的HQL或SQL查询时,如果查询结果已存在于...
4. Hibernate的二级缓存: - Hibernate支持缓存机制,提高数据访问效率。一级缓存是Session级别的,每个Session有自己的缓存;二级缓存是SessionFactory级别的,可跨Session共享数据。 5. ORM映射: - 基本类型...
### Hibernate缓存技术研究 #### 一、引言 Hibernate是一种强大的对象-关系映射(Object-Relational Mapping,简称ORM)工具,主要用于Java环境下的应用程序。它能够将应用程序中的对象模型映射到关系型数据库的表...
4. 配置缓存策略:定义缓存区域,设置缓存策略(如过期时间、更新策略等)。 5. 应用到查询:对于查询结果,可以使用`SessionFactory.getCache()`方法获取二级缓存对象,然后进行相关的读写操作。 在源码实例中,...
Hibernate缓存可以针对实体类、集合类、SQL查询结果等设置不同的缓存区域。根据业务需求,可以自定义缓存策略,为不同类型的对象设置不同的缓存过期时间。 **六、缓存同步** 为了保证多线程环境下的数据一致性,...
本文将详细讲解Hibernate中的三级缓存:一级缓存、二级缓存和查询缓存。 ### 1. 一级缓存 一级缓存是Hibernate内置的Session级别的缓存,也被称为事务性缓存。每当我们在Session中进行对象的CRUD(创建、读取、...
本篇文章将深入探讨Hibernate的二级缓存机制,以及如何进行一级缓存与二级缓存的同步,同时还会介绍二级缓存的配置文件设置。 一级缓存是Hibernate默认提供的缓存,每个SessionFactory实例都有一个一级缓存。当对象...
Hibernate缓存机制是提高应用程序性能的关键技术之一,它通过存储数据副本减少对物理数据库的访问。缓存可以分为两层:第一级缓存和第二级缓存。 **第一级缓存**是内置在Session中的,它是不可卸载的,也称为...