1.Hibernate是如今最流行的开源对象关系映射(ORM)持久化框架,SSH框架组合是很多JavaEE工程的首选,java持久化框架(JPA)的设计师是Hibernate的作者,因此对于Hibernate的一些基本知识在JPA学习笔记总结中具体总结。本篇只总结一些Hibernate使用中的一些小技巧。

2.实体对象的3中状态:

实体对象的生命周期是Hibernate中的一个关键概念,实体对象生命周期中有以下3种状态:

(1).Transient(自由状态):有人也叫透明状态,即在内存中自由存在的对象,与数据库中的记录无关。

(2).Persisent(持久态):也叫受管态,即实体对象处于由Hibernate持久化框架所管理的状态,这种状态下实体对象的引用被Hibernate实体容器管理,处于该状态的对象,其变更将被Hibernate持久化到数据库中。

(3).Datached(游离态):处于持久态的实体对象,其对应的Session实例关闭之后该对象就处于游离态。处于游离态的对象可以通过update再次变为持久态。

注意:自由状态和游离态的区别在于:自由状态在数据库中没有对于该对象的记录,而游离态对象在数据库中有对应的记录,只是脱离了Hibernate持久化框架的管理,其状态变化无法更新到数据库表中对应的记录。

3.值对象(VO)、持久化对象(PO)和数据传输对象(DTO):

(1). 值对象(VO):顾名思义是表示值的对象,是相对独立的对象,处于非管理状态。

(2). 持久化对象(PO):是由持久化框架所管理的对象,代表了与数据库中某条记录对应的实体,其变化在事务提交时将被更新到实际数据库中。

(3). 数据传输对象(DTO):持久化和业务逻辑层或者视图层交互时,持久化对象(PO)会首先通过构造变成一个值对象(VO),然后在将这个值对象(VO)传递给所需的层,这个充当数据传递媒介的值对象(VO)此时就被称为数据传输对象(DTO)。

4.Hibernate中get和load的区别:

在Hibernate中获取对象有两种方法:get方法和load方法,但是这两个方法有一些区别,初学者可能不太熟悉,有可能使用不当会出错,它们的区别如下:

(1).get方法是首先从内部缓存中查找,如果没有查找到则从数据库中直接取数据,若数据库中无相应的值时,get方法会返回null。

(2).load方法如果从内部缓存查找不到时,不是直接从数据库中取数据,而是还将查询二级缓存,可能返回对象代理,若数据库中无相应值时,load方法会ObjectNotFoundException抛异常。

5.Hibernate中save和persist方法的区别:

在Hibernate中对象持久化也有两种方法:save和persist,这两个方法是将游离态的对象保存到数据库中变为受管态的对象,但是这两个方法也有如下区别:

(1).若无事务时,persist方法不执行。

(2).若无事务时,save方法先在数据库中插入记录,然后又回滚数据库。

6.Hibernate的查询方式:

Hibernate支持两种查询方式:Hibernate查询语言(HQL)和Criteria查询。

(1).HQL:是Hibernate提供的面向对象查询语言,主要通过Query接口完成,和SQL写法类似,只是在HQL中不再对表和表中的列进行操作,而是对对象和对象的属性进行操作。如查询给定name的Person对象的HQL写法为:Query.createQuery(“Select p from  Person p where p.name = :name”).setParameter(“name”,name);
(2).Criteria:一种比HQL更加面向对象的查询方式,号称是完全面向对象方式的查询方式,和SQL写法相差比较大。和(1)中的例子一样,Criteria的写法如下:

  1. Criteria criteria = Session.createCriteria(Person.class);
  2. //添加查询条件
  3. criteria.add(Restrictions.eq(“name”,name));

对于HQL和Criteria仁者见仁,智者见智,根据个人的习惯选择使用,它们在运行时,Hibernate都会将它们转换成对应的本地的SQL语句。

7.Hibernate延迟加载问题:

在查询一个对象时,如果该对象还引用了其他对象,在查询时会将其引用的所有对象也一同查询出来,这样在大批量数据查询时性能会非常差,为了解决这个问题Hibernate使用了延迟加载(Lazy),即默认只查询要查询的对象本身,该对象所引用的对象只有当真正使用到时再从数据库中查询,这样就可以做到按需查询,大大提高性能。但是延迟加载也会带来其他的问题,比如在一个页面上查询出一个对象,而在其他地方又需要使用该对象的引用对象时,就会出现因为Hibernate会话(Session)关闭对象丢失无法查找所需对象的异常。解决延迟加载的常用办法:

(1).有人提供了一个过滤器,针对Hibernate的叫做:OpenSessionInView的过滤器,针对JPA的叫做OpenEntityManagerInView的过滤器。该过滤器作用是当页面在打开时,Hibernate会话(Session)和JPA的实体管理器(EntityManager)保存打开,这样当真正需要引用对象值时再从数据库中查找就不会出现异常。

(2).查出一个对象后使用Hibernate.initialize(对象)将该对象初始化,这样做延迟加载的机制就不再起作用。

8.线程局部变量ThreadLocal:

ThreadLocal是java的JDK中提供的一个叫做线程局部变量的类,该类的作用是针对共享数据每个线程在其本身保存一份拷贝,避免线程间相互影响。其简单用法如下:

  1. ThreadLocal session = new ThreadLocal();
  2. public static getThreadLocal(){
  3. //以当前线程作为key来获取线程局部变量的值
  4. Session s  =  (Session)session.get();
  5. if(s == null){
  6. s = this.getSession();
  7. session.set(s);
  8. }
  9. }

线程局部变量(ThreadLocal)相当于一个Map,其Key是当前的线程,只在一个线程内有效。

在Hibernate中用线程局部变量(ThreadLocal)来管理Hibernate会话(Session),可以实现多个操作共享一个Hibernate会话(Session),从而可以避免反复获取同一个session。

9.Hibernate批量操作:

Hibernate中Session是线程不安全的,而SessionFactory是线程安全的。

Hibernate执行flush刷新方法时,会将一级缓存中的数据与数据库同步。

Hibernate操作大批量数据时可能会造成内存溢出,解决办法:

(1).清除Session中的数据,如:

  1. for(int i = 0; i < 1000000; i++){
  2. session.save(obj);
  3. //每100条记录刷新一次session缓存
  4. if(i % 100 == 0){
  5. session.flush();
  6. session.clear();
  7. }
  8. }

(2).使用无状态会话接口StatelessSession,不和一级、二级缓存交互,不触发事件,通过该接口的所有操作会立刻发送给数据库。

(3).使用Hibernate中的Query.executeUpdate()执行批量更新时,会清除相关的二级缓存。

10.Hibernate中创建动态离线查询:

  1. DatachedCriteria dc = DatecheCriteria.forClass(要查询的类.class);
  2. //添加查询条件
  3. dc. add(Restrictions.eq(“name”,name));
  4. 使用动态离线查询:
  5. Criteria criteria = dc.getExecutable(Session对象);

11.Hibernate中的SQL查询和命名查询(NamedQuery):

(1).SQL查询时在hibernate创建query对象时可以直接使用SQL语句,如下:

  1. session.createSQLQuery(SQL语句);

SQL查询常用于一些对于性能要求比较高的地方,但是一般不推荐使用,因为涉及到SQL语句的兼容性,会影响到程序的可移植性。

(2)命名查询(NamedQuery)类似于jdbc中的prepareStatement对象,是一种预编译的查询,可以大大提高效率,创建方法如下:

  1. session.createNamedQuery(HQL查询语句);

12.Hibernate中使用集合时的一个小问题:

在Hibernate和JPA中使用集合对象时,如果使用的是List,在操作时经常会报一个MultiBagException的异常,解决方法为:

(1).最简单最方便的方法:使用Set代替List。

(2).在使用List集合的字段上添加@Cloumn或者@OrderCloumn注解,即给集合指定一个列索引。

13.Hibernate的缓存:

Hibernate中维持了两级缓存:

(1).内部缓存,即一级缓存,属于事务级缓存,在Session对象生命周期中,每个session都维护了一个独立的缓存,为当前session实例所独享。内部缓存有Hibernate自动维护,如需手动干预可以使用以下两个方法:

a.Session.evict:将某个特定的对象从内部缓存中清除。

b.Session.clear:清空内部缓存。

(2).二级缓存,由当前的SessionFactory创建的多个Session实例所共享,在Hibernate中二级缓存涵盖了应用级缓存和分布式缓存。

Hibernate中缓存在以下情况中发挥作用:

a.       通过Id(主键)加载数据时。

b.       延迟加载。

14.ibernate的二级缓存:

(1).引入Hibernate二级缓存的情况:

应用部署在集群环境中。

(2).使用二级缓存的条件:

a.数据不会被第三方修改。

b.数据大小在可接受范围之内。

c.数据的读取大于修改,即数据的更新频率比较低。

d.非关键的数据,可以容忍无效的数据。

(3).使用第三方提供的二级缓存实现:

Hibernate自身提供了二级缓存实现,但是功能比较有限,仅用于在开发调试时使用。Hibernate提供了面向第三方的二级缓存实现接口,常用的二级缓存如下:

a.JCS。  b. EHCache。 c. OSCache。 d. JBoss Cache。e. SwarmCache。

(4).缓存的同步策略:

缓存同步策略决定了数据对象在缓存中的存取规则,为了使得缓存调动遵循正确的应用级事务隔离机制,在使用缓存时必须为每个实体指定相应的缓存同步策略,Hibernate中提供了4中缓存同步策略:

a.       read-only:只读,针对不会发生改变的数据。

b.       nonstrict-read-write:非严格读写,针对于并非同步要求不是很严格,且数据更新频率很低的数据。

c.       read-write:严格可读性缓存,基于时间戳判断机制,实现了read committed事务隔离等级,用于对数据同步严格情况,但是该策略不支持分布式缓存,也是实际应用中使用最多的缓存策略。

d.       transactional:事务型缓存,必须运行在JTA环境,该策略实现了repeatable read事务隔离等级,适用于对关键性数据的缓存。

15.一个Hibernate使用二级缓存的小例子:

(1).在hibernate中启用二级缓存:

在hibernate的配置文件hibernate.cfg.xml中添加以下参数(以EHCache为例):

  1. <hibernate-configuration>
  2. <session-factory>
  3. <!--指定缓存提供者-->
  4. <property name=”hibernate.cache.provide_class”>
  5. net.sf.ehcache.hibernate.Provider
  6. </property>
  7. ……
  8. </session-factory>
  9. ……
  10. </hibernate-configuration>

(2).对象EHCache实现本身进行配置:

默认在类路径下加入ehcache.xml文件,添加如下配置:

  1. <ehcache>
  2. <diskStore path=”指定缓存存放目录”>
  3. <defaultCache
  4. mexElementsInMemory=”10000” //cache中最大允许保存的数据对象数量
  5. eternal=”false”                            //cache中数据是否为常量
  6. timeToIdleSeconds=”120”            //缓存数据钝化时间
  7. timeToLiveSeconds=”120”           //缓存数据的存活时间
  8. overflowToDisk=”true”                //内存不足时,是否启用硬盘缓存
  9. />
  10. </ehcache>

(3).指定缓存同步策略:

在各个实体映射文件中指定缓存同步策略,添加如下:

  1. <class name=”hibernate实体类全路径”>
  2. <cache usage=”read-write”/>
  3. ……
  4. <set name=”……”>.
  5. <cache usage=”read-only”/>
  6. </set>
  7. </class>

注意:缓存同步策略既可用于实体类,也可以用于集合属性。

16.       Hibernate的适用和不适用场景:

由于像Hibernate这样的对象关系映射(ORM)在对象和关系型数据库之间操作时,需要将面向对象的操作转化为本地数据库的SQL语句,存在一些性能上的劣势,另外如果对Hibernate熟悉还可以会出现N+1查询和延迟加载的一些问题,所以Hibernate有其适合和不适合的场景。

(1).不适用场景:

a.联机分析处理(OLAP):以大量的查询为主。

b.海里数据,同时性能要求苛刻的系统。

(2).适用场景:

联机事务处理(OLTP)。

Hibernate的一些使用技巧的更多相关文章

  1. JPA和Hibernate的相关使用技巧

    介绍 尽管有SQL标准,但每个关系数据库终将是唯一的,因此你需要调整数据访问层,以便充分利用在使用中的关系数据库. 在本文中,我们将介绍在使用带有JPA和Hibernate的MySQL时,为了提高性能 ...

  2. 三年总结出来的11个JPA和Hibernate查询配置小技巧

    JPA和Hibernate提供了一系列暗示hints能够帮助你更好地定制你的查询语言,这些小暗示或暗语是一种附加信息,你可以利用这些暗语做很多事情,比如设置查询的timeout,使用实体图或定义查询缓 ...

  3. java初学者必看的学习路线

    不管在编程语言的排行榜中,还是在大多数企业应用的广泛程度来看,Java一直都是当之无愧的榜首.Java语言有着独特的魅力吸引着广大的年轻人去学习,每个人学习的方式方法不一样. 第一步:首先要做好学习前 ...

  4. 第八章 Hibernate数据操作技巧

    第八章   Hibernate数据操作技巧8.1 分组统计数据    语法:[select]... from ...[where] [group by...[having...]] [order by ...

  5. Hibernate SQL优化技巧dynamic-insert="true" dynamic-update="true"

    最近正在拜读Hibernate之父大作<Java Persistence with Hibernate>,颇有收获.在我们熟悉的Hibernate映射文件中也大有乾坤,很多值得我注意的地方 ...

  6. hibernate设置mysql的timestamp默认值技巧

    首先,要想使用数据库中配置的默认值就必须不让hibernate覆盖了默认值,需要配置property insert="false" update="false" ...

  7. Hibernate的使用技巧②

    1.Hibernate统计记录的数量 Criteria c = session.createCriteria(User.class.getName());        c.setProjection ...

  8. hibernate.cfg.xml配置文件对关联关系的书写技巧!

    以Department(部门类)和User(用户类)作为例子: 类图如下: 一般hibernate.cfg.xml的配置文件开头都是如下: <?xml version="1.0&quo ...

  9. Hibernate 的*.hbm.xml文件的填写技巧

    ================================================================================= 模板: <!-- ?属性,本类 ...

随机推荐

  1. Method for Estimating the Number of Concurrent Users

    1. Formula for Estimating the Average Number of Concurrent users We begin by defining what the numbe ...

  2. 常州模拟赛d2t3 小X的佛光

    平日里最喜欢做的事就是蒸发学水.[题目描述]小 X 所在的城市 X 城是一个含有 N 个节点的无向图,同时,由于 X 国是一个发展中国家,为了节约城市建设的经费,X 国首相在建造 X 城时只建造 N ...

  3. *hdu5632Rikka with Array

    $n \leq 10^300$,问所有$i<j$且$f_i>f_j$的$(i,j),1 \leq i \leq n,1 \leq j \leq n$数量.对某个数取模. $f(a,b,0/ ...

  4. HDU - 5572 An Easy Physics Problem (计算几何模板)

    [题目概述] On an infinite smooth table, there's a big round fixed cylinder and a little ball whose volum ...

  5. css3的一些新属性及部分用法

    CSS3是CSS(层叠样式表)技术的升级版本,增加了很多新属性,我们在web开发中采用css3技术可以提高程序的性能以及用户体验.而且一般面试中会问到知道哪些新增加的属性,我们不可能将所有东西一一复述 ...

  6. HSSF生成excel文件损坏

    一开始我的代码是这样的: 然后打开创建的好的excel文件出现下面的问题:,, 这里改下代码就行,其实也不用改,添加下sheet就行,就是一开始是空的,没sheet,所以可能打不开,现在至少要创建一个 ...

  7. Java8 本地DateTime API

    原文:http://www.yiibai.com/java8/java8_localdateapi.html 使用Java8,新的日期时间API引入覆盖旧的日期时间API的以下缺点. 非线程安全 - ...

  8. Oracle SQL Developer Chanage UI to US Lanaguage

    \sqldeveloper-4.1.3.20.78-x64\sqldeveloper\sqldeveloper\bin Add content: AddVMOption -Duser.country= ...

  9. android 查看手机运行的进程列表

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools=&q ...

  10. BIM

    BIM进入中国已经有十来个年头,随着对BIM概念的深入了解.当前国内BIM应用逐渐由三维模型的可视化应用升级为基于BIM模型的信息进行项目精细化动态管理. 传统粗放的项目管理方法是工程项目难以进行精细 ...