基本上都是以前看书后写下的笔记和实践操作的记录。
一、关于查询迭代函数list.iterator(),Query.iterate()的比较
用hibernate进行查询,然后对查询结果进行迭代,有两种实现方法:
1、List ls = session.createQuery("...").list();
Iterator iter = ls.iterator();
while(iter.hasNext()){
//...
Object obj = (Object)iter.next();//以对象形式返回结果
//...
}
2、Iterator iter = session.createQuery("...").iterate();
//createQuery()返回Query类型
第一种查询方法list()函数,采用了一条语句直接查询了所有的结果;而第二种查询方法iterate(),则是先查询获得对象标识符(既是数据库主键),然后根据对象标识符,对每个标识符生成相应的查询语句,进行查询并实例化持久对象。
另外如果开启了二级缓存,第二种方法iterate()函数可以利用二级缓存,而list ()却只能利用到一级缓存。
对于海量信息的查询用两种方法都可以能会有内存溢出的情况出。但iterate()方法是对每一条记录进行了查询并实例化持久对象的,这样就可以对每次查询获得的结果进行缓存清理,从而解决内存溢出的问题。
while(iter.hasNext()){
Object obj = (Object)iter.next();
session.evict(obj);//一级清理
sessionFactory.evict(Object.class,obj.getId());//二级清理
}
二、JOIN FETCH连接查询的限制
例如,A(a_id,name)和B(b_id,name,a_id)是一对多的关系,对应的HQL语句为:FROM A a JOIN FETCH a.B b那么返回的结果只会有左边的对象A的集合(返回的左边结果可能会有重复数据),而右边的关联对象B则同父对象访问时获取。
1、不能使用Query.iterate()来取得结果集,iterate()不允许使用FETCH连接
2、不能在分页方法中使用,因为返回的左边结果的数据可能会重复,就无法获取正确的记录数。
3、不能带WITH条件,否则会抛出异常QuerySyntaxException
三、有关乐观锁
乐观锁的一般有两种实现方法:版本检查、时间截。
1、版本检查要在对应的表添加版本号(version)字段(为整数类型),hibernate先会查询获取对应记录的verstion字段的值,在进行更新时,使用主键和先前所查得的version字段作为条件,并把version的值加1。如果主键和version对对应不到记录,更新失败,那么就会抛出异常。配置:<class optimistic-lock="version" ...><version name="vs" column="vs" type="java.lang.Integer"/></class>。使用版本检查在一个系统使用,而其他的系统也对该数据库进行操作,并且该系统没有使用版本检查,就会导致数据的不一致。
2、时间截也是采用同样的过程也是一样的,只是把version字段设置为date类型,配置<class optimistic-lock="version" ...><timestamp name="vs" column="vs"/></class>,使用<timestap>节点一定要在<id>节点之后。由于时间的差异在并发线程同时读取和修改同一记录,可能导致数据的不一致,所以使用版本检查比较安全。
3、如果是使用HQL语句进行更新,UPDATE语句是不会更新version字段的,需要使用versioned字段进行手工明确指定。update versioned A set name=:newName where name=:name
四、在批量更新和删除HQL语句中使用别名是无意义的
UPDATE A SET name=:newName WHERE name=:name和UPDATE A a SET a.name=:newName WHERE a.name=:name生成的SQL是完全一样的:update A set name=? where name=?。如果该成UPDATE A a SET a.name=:newName WHERE a.name=:name AND a.B.name="123"就会生成sql语句:update A set name=? where name=? and name="123",显然这个sql语句是错误的,并非所期望的结果。
五、HQL的DML及其insert
DML的insert不支持insert into values形式的插入操作,也不支持多态。
DML即为数据操纵语言,对数据库的数据进行操作,而对象关系映射管理的对象状态是存在于内存的,所以执行DML批量操作并不会清理一级缓存,为了不得到脏数据,在执行批量操作时调用session.evict()清空一级缓存。
六、相同与不同的持久对象
当是同一个session两次加载同一个主键记录时,生成的两个持久对象是相同的,可用==比较。
当是不同session各自加载同一个主键记录时,生成的两个持久对象是不同的。
七、性能提高
1、提高Hibernate启动速度。使用Configuration.addCatcheableFile()方法提高启动速度。
2、<class>节点的属性dynamic-update的默认值为false,对所有的属性进行更新。修改为true,这样就只对更改了的属性进行更新。
3、绕过hibernate,直接使用JDBC或者存储过程来批处理数据时,同过session获得Connection对象,session.connection(),最后还要清理一级缓存中的数据,session.clear(),并不需要调用connection.close()关闭数据库连接,session会在关闭时关闭。
4、在循环中进行批量操作,可以这样
for(int i=0; i<100000; i++){
//...
session.save(obj);
session.flush();
session.evict();
}
在上面已经提到,但性能提高并不大
可以这样做:
for(int i=0; i<100000; i++){
//...
session.save(obj);
if(i%20==0){
session.flush();
session.evict();
}
}
5、使用DML风格的批量操作。[UPDATE|DELETE] FROM? EntityName [WHERE conditions?],INSERT INTO EntityName properties_list SELETE selete_statement
6、在WEB应用中使用Open Sesion In View模式可以在MVC框架中实现延迟加载,安全关闭,避免频繁创建销毁。
八、有关查询缓存
查询缓存是依赖于二级缓存的,查询结果较小,查询条件较稳定时方可以用查询缓存。
要在代码声明使用查询缓存,并设置区域,query.setCacheable(true);query.setCatcheRegion("abc");在对查询更改后,必须使用essionFactory.evictQueries("abc");清除查询缓存,否则会得到脏数据。
二级缓存的实现是以查询的HQL和查询参数作为key保持的,如果先后两个查询语句条件相近,查得的结果集相同或相近,第二个查询的部分结果集并不是在第一个查询结果集查找到的,而是重新全部从数据库加载。
例如:from A a where a.age>44和from A a where a.age>42,两个查询语句条件相近,第一条查询结果集是第二条查询结果集的一部分,但是第二条查询部分结果集并不是从第一条查询结果集来的。
可以用OSCache控制缓存失效。
分享到:
相关推荐
Hibernate学习笔记整理 以下是 Hibernate 框架的详细知识点: Hibernate 介绍 Hibernate 是一个 ORM(Object-Relational Mapping)框架,用于将 Java 对象映射到数据库表中。它提供了一个简洁的方式来访问和操作...
hibernate jar包整理,新手上路
【hibernate权威整理文档!】 一、Hibernate简介 Hibernate是一个强大的ORM(Object-Relational Mapping)框架,它致力于简化Java应用程序的持久层开发。通过Hibernate,开发者可以将Java对象映射到数据库表,从而实现...
**标题:“Hibernate配置连接池整理”** 在Java开发中,数据访问层的性能优化往往离不开高效的数据连接管理,而连接池就是实现这一目标的关键技术。Hibernate作为一款强大的对象关系映射(ORM)框架,它提供了与...
【Hibernate 知识整理】 1- Hibernate 是什么? Hibernate 是一个流行的对象关系映射(ORM)框架,它允许 Java 开发者用面向对象的方式来处理数据库交互。Hibernate 自动处理 SQL 转换和数据库访问,使得开发人员...
该笔记由作者根据马士兵老师的教程整理而成,其中包含了个人的学习注解,使得内容更加生动易懂。 1. **Hibernate简介** Hibernate是一种开放源代码的ORM框架,它简化了Java应用程序与数据库之间的交互,通过将对象...
在这个"hibernate整理"中,我们将深入探讨Hibernate的核心概念,包括SessionFactory、Session以及如何进行增、删、改、查(CRUD)操作。 首先,`SessionFactory`是Hibernate的核心组件之一,它是线程安全的,负责...
Hibernate 配置各种数据库 Hibernate 是一个基于 Java 的持久层框架,提供了一个抽象的数据访问层,能够与多种数据库进行集成。在 Hibernate 的配置文件中,我们可以配置不同的数据库连接,包括驱动程序、URL 等...
"Hibernate入门到精通" Hibernate 是一个基于Java的ORM(Object-Relational Mapping,对象关系映射)框架,它提供了一种简洁高效的方式来访问和操作关系数据库。下面是 Hibernate 的主要知识点: Hibernate 简介 ...
《Hibernate-Extensions全面指南》 Hibernate,作为Java领域中的一款著名对象关系映射(ORM)框架,极...无论你是初学者还是经验丰富的开发者,这个完整的安装包都值得你拥有,因为它将为你的开发工作带来极大的便利。
Hibernate.jar包,Hibernate可以应用在任何使用JDBC的场合,包含 hibernate-commons-annotations-4.0.1.Final.jar hibernate-core-4.1.12.Final.jar hibernate-ehcache-4.1.12.Final.jar hibernate-entitymanager-...
hibernate 5.2.15 hibernate 5.2.15 hibernate 5.2.15 hibernate 5.2.15 hibernate 5.2.15hibernate 5.2.15
Hibernate3 是一个非常重要的Java持久化框架,它简化了数据库操作,使得开发人员可以更加专注于业务逻辑而不是数据库的细节。这个`hibernate3.zip`压缩包包含了`hibernate3.jar`,它是Hibernate 3版本的核心库,包含...
综上所述,《Hibernate实战》是一本内容丰富、实用性强的专业书籍,无论对于初学者还是有经验的开发人员来说,都是学习Hibernate框架不可多得的宝贵资源。通过本书的学习,不仅可以快速掌握Hibernate的基本用法,还...
标题中的“hibernate和MySQL的jar”指的是Hibernate ORM框架与MySQL数据库之间的连接库。Hibernate是一种流行的Java对象关系映射(ORM)工具,它允许开发者使用面向对象的编程方式来操作数据库,而无需直接编写SQL...
在Java开发环境中,与KingbaseV8数据库进行交互通常会用到Hibernate框架和JDBC驱动。 Hibernate是一个优秀的对象关系映射(ORM)框架,它简化了Java应用程序对数据库的操作,通过将Java对象与数据库表进行映射,...
HibernateTools是Java开发人员在使用Hibernate ORM框架时的有力辅助工具集,主要目的是为了提高开发效率,简化数据库操作。在HibernateTools 3.2.4版本中,它包含了一系列的特性与插件,以支持更便捷地进行对象关系...
Hibernate3 是一个强大的Java持久化框架,它允许开发者将数据库操作与业务逻辑解耦,使得应用程序的开发更为简便。这个“hibernate3全部jar包:hibernate3.jar.zip”包含了所有必要的库文件,方便用户一次性下载并...
【描述】中的"hibernate的jar包"指的是Hibernate框架的运行库文件,这些JAR文件包含了Hibernate的所有核心API、实现和依赖库,如Hibernate Commons Annotations、Hibernate EntityManager、Hibernate Core等。...
Hibernate3是一个广泛使用的Java对象关系映射(ORM)框架,它允许开发者用面向对象的方式处理数据库操作,极大地简化了Java应用程序与数据库之间的交互。在这个"Hibernate3的依赖包"中,包含了运行Hibernate3应用...