Hibernate是数据持久化工具。也是一个开放源代码的ORM解决方案。Hibernate内部封装了通过JDBC访问数据库的操作,向上层应用提供面向对象的数据访问API
基于ORM、Hibernate在对象模型和关系数据库的表之间建立了一座桥梁,通过Hibernate,程序员就不需要再使用SQL语句操作数据库中的表,使用API直接操作 JavaBean 对象就可以实现数据的存储,查询。更改和删除等操作。显著降低了由于对象与关系数据库在数据表现方面的范例不匹配导致的开发成本。
用JDBC 查询返回的是ResultSet对象,ResultSet往往不能直接使用,还需要转换成List,并且通过JDBC查询不能直接得到具体的业务对象,这样在整个查询的过程中,就需要做很多重复性的转换工作。
使用Hibernate 完成持久化操作,只需要编写如下代码:
Session session = HibernateUtil.currentSession();
Query query = session.createQuery(“from User”);
List
HibernateUtil 是一个自定义的工具类,用于获取Hibernate的Session对象,Session是Hibernate执行持久化操作的核心API。Hibernate 处理数据库查询时,编写的代码非常简洁,作为查询结果,可以直接获得一个存储着User实例的List集合实例,能够直接使用,避免了繁琐的重复性的数据转换过程。
2.Hibernate框架的缺点
(1)不适合以数据为中心大量使用存储过程的应用。
(2)大规模的批量插入、修改和删除不适合用Hibernate。
Hibernate与MuBatis都属于ORM框架,为数据层提供持久化操作的支持。下面从几个方面对Hibernate和MyBatis做一下比较,也为选择框架提供一些参考价值。
当应用通过调用Hibernate API与框架进行交互时,需要从持久化的角度关注应用对象的生命期,持久化生命周期是Hibernate中的一个关键概念,正确的理解生命周期,可以更好得了解Hibernate的实现原理,掌握Hibernate的正确用法,Hibernate框架通过Session来管理Java对象的状态,在持久化生命周期中,Java对象存在着如下三种状态。
1.瞬时状态(Transient)
瞬时状态又称临时状态,如果java对象与数据库中的数据没有任何的关联,即此Java对象在数据库中没有相关联的记录,此时Java对象的状态为瞬时状态,Session对于瞬时状态的Java对象是一无所知,当对象不再被其他对象引用时,它的所有数据也就丢失了,对象将会被Java虚拟机按照垃圾回收机制处理。
当对象与Session关联,被Session管理时,它就处于持久状态,处于持久状态的对象拥有数据库标识(数据库中的主键值)。那么,对象是什么时候与Session发生关联的呢?
第一种情况,通过Session的查询接口,或者get()方法,或者load()方法从数据库中加载对象的时候,加载的对象是与数据库表中的一条记录关联的,此时对象与加载它的Session发生关联的。
第二种情况,对瞬时状态的对象调用Session的save()、savaOrUpdate()等方法时,在保存对象数据的同时,java对象也会与Session发生关联。对于处于持久状态的对象,Session会持续跟踪和管理它们,如果对象的内部状态发生了任何变更,Hibernate会选择合适的时机(如事务提交时)将变更同步到数据库中,
游离状态又称脱管状态,处于持久状态的对象,脱离与其关联的Session的管理后,对象就处于游离状态,处于游离状态的对象,Hibernate无法保证对象所包含的数据与数据库中的记录一致,因为Hibernate已经无法感知对该对象的任何操作,Session提供了update()、
savaOrUpdate()等方法,将处于游离状态的对象的数据以更新的方式同步到数据库中,并将该对象与当前的Session关联,这时,对象的状态就从游离状态重新转换为持久状态。
(1).瞬时状态转为持久状态
使用Session的Sava()、savaOrUpdate()等方法保存对象后,该对象的状态由瞬时状态转换为持久状态。
使用Session的get()或load()方法获取对象,该对象的状态是持久状态。
(2).持久状态转为瞬时状态
执行Session的delete()方法后,对象由原来的持久状态变为瞬时状态,因为此时该对象没有与任何的数据库数据关联。
(3).持久状态转为游离状态
执行Session的evict()、chear()或close()方法,对象由原来的持久状态转为游离状态。
执行Session的update()或savaOrUpdate()方法,对象由游离状态转为持久状态,该对象再次与当前Session相关联
执行Session的Delete()方法,对象由游离状态转为瞬时状态。
提示:
处于瞬时状态或游离状态的对象不再被其他对象引用时,会被Java虚拟机按照垃圾回收机制处理。
Session是Hibernate向应用程序提供的持久化操纵的主要接口,它提供了基本的保存、更新、删除和加载Java对象的方法。Session具有一个缓存,可以管理和跟踪所有持久化对象,在某些时间点,Session会根据缓存中对象的变化来执行相关SQL语句,将对象发生的变化同步到数据库中,换句话说就是将数据库同步为与Session缓存一致。这一过程称为刷新缓存!
4.4.1脏检查
在Hibernate中,数据前后发生变化的对象,称为藏对象,如一下代码所示:
Tx = session.beginTransaction();
//获取部门对象,dept对象处于持久状态
Dept dept = (Dept) session.load(Dept.class,new Byte(“11”));
//修改后,部门信息和之前不同,此时dept对象成为所谓的“脏对象”
Dept.setDname(“质管部”);
//提交事务
Tx.commit();
以上代码中,dept对象处于持久状态,当dept对象被加入Session缓存中时,Session会为dept对象的值类型的属性复制一份快照。操作中,dname属性发生改变,dept对象即成为脏对象,在事务提交时,Hibernate会对Session中持久状态的对象进行检测,即比较dept对象的当前属性与它的快照。以判断dept对象的属性是否发生了变化。这种判断称为脏检查,如果对象发生了改变,Session会根据脏对象的最新属性值来执行相关的SQL语句,将变化更新到数据库中,以确保内存中的对象数据与数据库中的数据一致!
4.4.2 刷新缓存机制
需要注意的是,当Session缓存中对象的属性发生变化时,Session并不会立即执行脏检查和执行相关的SQL语句,而是在特定的时间点。即刷新缓存时才执行。这使得Session能够把多次变化合并为一条或者一批SQL语句,减少了访问数据库的次数,从而提高应用程序的数据访问性能。
在默认情况下,Session会在以下时间点刷新缓存。
Session的flush()方法进行刷新缓存的操作,会触发脏检查,视情况执行相关的SQL语句。
Commit()方法会先调用Session的刷新缓存方法flush(),然后向数据库提交事务。
在提交事务时执行刷新缓存的动作,可以减少访问数据库的频率,尽可能缩短当前事务对数据库中相关资源的锁定时间。
Hibernate中的Session提供了多种更新数据的方法,如update()、savaOrUpdate()、merge()方法:
(3)merge()方法,能够把作为参数传入的游离状态对象的属性复制到一个拥有相同OID的持久状态对象中,通过对持久状态对象的脏检查实现更新操作,并返回该持久状态对象,如果无法从Session缓存或数据库中加载到相应的持久状态对象,即传入的时瞬时对象,则创建其副本执行插入操作。并返回这一新的持久状态对象,无论何种情况,传入的东西状态都不受影响。