Hibernate的高级特性.ppt

上传人:公**** 文档编号:569812773 上传时间:2024-07-31 格式:PPT 页数:19 大小:774.05KB
返回 下载 相关 举报
Hibernate的高级特性.ppt_第1页
第1页 / 共19页
Hibernate的高级特性.ppt_第2页
第2页 / 共19页
Hibernate的高级特性.ppt_第3页
第3页 / 共19页
Hibernate的高级特性.ppt_第4页
第4页 / 共19页
Hibernate的高级特性.ppt_第5页
第5页 / 共19页
点击查看更多>>
资源描述

《Hibernate的高级特性.ppt》由会员分享,可在线阅读,更多相关《Hibernate的高级特性.ppt(19页珍藏版)》请在金锄头文库上搜索。

1、Java EE实用教程第第11章章 Hibernate的高级特性的高级特性11.1 Hibernate的事务管理的事务管理11.2 Hibernate的并发的并发11.3 Hibernate的拦截器的拦截器Java EE实用教程11.1 Hibernate的事务管理的事务管理11.1.1 事务的概念事务的概念事务有4个重要特性:原子性:即作为一个事务,它是一个不可分割的整体,只有全部操作都完成了,才算结束;其中任何一个操作执行失败,整个事务都要撤销。一致性:即事务不能破坏数据库的完整性和业务逻辑的一致性。事务不管成功还是失败,事务结束时,整个数据库内部数据都是正确的。隔离性:即在并发的数据库操

2、作时,不同的事务操作相同的数据时,每个事务都有自己的完整的数据空间。一个事务不会看到或拿到另一个事务正修改到一半的数据,这些数据要么是另一个事务修改前的,要么是另一个事务修改后提交的。拥有这个特性,是为了在数据库并发操作过程中,保证所有并发操作的正确性。持久性:即事务成功提交后,数据就被永久地保存到数据库,重新启动数据库系统后,数据仍然保存在数据库系统中。Java EE实用教程11.1.2 Hibernate的事务的事务将事务管理委托给JDBC进行处理是最简单的实现方式,Hibernate对于JDBC事务的封装也比较简单。例如下面的代码:Sessionsession=sessionFactor

3、y.openSession();Transactiontx=session.beginTransaction();mit();从JDBC层面而言,上面的代码实际上对应着:Connectioncn=getConnection;cn.setAutoCommit(false);/JDBC调用相关的SQL语句mit();Java EE实用教程11.1.2 Hibernate的事务的事务在sessionFactory.openSession()语句中,Hibernate会初始化数据库连接。与此同时,将其AutoCommit设为关闭状态(false),即一开始从SessionFactory获得的sessi

4、on,其自动提交属性已经被关闭。下面的代码不会对数据库产生任何效果:sessionsession=session.Factory.openSession();session.save(user);session.close();这实际上相当于JDBCConnection的AutoCommit属性被设为false,执行了若干JDBC操作之后,没有调用commit操作。如果要使代码真正作用到数据库,必须显示地调用Transaction指令,例如下面的代码:Sessionsession=sessionFactory.openSession();Transactiontx=sessio.beginTr

5、ansaction();session.save(user);mit();session.close();Java EE实用教程11.1.2 Hibernate的事务的事务Hibernate的事务应用一般分为下面几个步骤:(1)通过SessionFactoy获得Session对象,例如下面的代码:Sessionsession=sessionFactory.openSession();(2)通过Session对象开始一个事务,例如下面的代码:Transactiont=session.beginTransaction();(3)进行相关的数据操作。(4)事务提交,例如下面的代码:mit();(5)

6、如果事务处理出现异常,则撤销事务(通常叫做事务回滚),例如下面的代码:t.rollback();(6)关闭Session,结束操作,例如下面的代码:session.close();一个完整的应用Hibernate事务的实例。Java EE实用教程11.1.2 Hibernate的事务的事务h2基于基于JTA的事务管理概念的事务管理概念JTA(JavaTransactionAPI)是由JavaEETransactionManager管理的事务,其最大的特点是调用UserTransaction接口的begin()、commit()和rollback()方法来完成事务范围的界定、事务的提交和回滚。J

7、TA可以实现同一事务对应不同的数据库。JTA主要用于分布式的多个数据源的两阶段提交的事务,而JDBC的Connection提供单个数据源的事务,后者因为只涉及一个数据源,所以其事务可以由数据库自己单独实现,而JTA事务因为其分布式和多数据源的特性,不可能由任何一个数据源实现事务。因此,JTA中的事务是由“事务管理器”来实现的,它会在多个数据源之间统筹事务,具体使用的技术就是所谓的“两阶段提交”。JTA事务管理由JTA容器实现,JTA容器对当前加入事务的众多Connection进行调度,实现事务性要求。JTA的事务周期可横跨多个JDBCConnection生命周期。同样,对于基于JTA事务的Hi

8、bernate而言,JTA事务横跨多个Session。Java EE实用教程11.2 Hibernate的并发的并发11.2.1 并发产生的问题并发产生的问题一般情况下,数据库并发产生的问题可以分为4种:更新丢失、脏读、不可重复读及虚读。下面分别介绍这4种问题。更新丢失。当多个事务同时操作同一数据时,由于事务之间完全没有进行隔离,撤销其中一个事务,结果覆盖了其他事务已经提交并成功更新的数据,对其他事务而言造成了数据丢失。例如,在存款和取款的情况下,如果没有采取措施,很容易出现如表11.1所示的并发问题带来的情况。阶 段取 款存 款1事务开始2查询账户余额1000元3事务开始4查询账户余额100

9、0元5取走100元,剩余900元6存入100元,账户中应为1100元7提交事务8撤销事务,账户余额回滚为事务开始时的1000元,事务结束表11.1 更新丢失Java EE实用教程11.2.1 并发产生的问题并发产生的问题脏读。当多个事务同时操作同一数据时,如果事务A读到事务B尚未提交的更新数据,且对其进行操作,当事务B撤销了更新后,事务A所操作的数据便成了无效数据(即脏数据)。同样以存款与取款问题为例,如表11.2所示。阶 段取 款存 款1事务开始2查询账户余额1000元3事务开始4取走100元,剩余900元5查询账户余额900元6存入100元,账户中应为1000元7提交事务8撤销事务,账户余

10、额回滚为事务开始时的1000元,事务结束表11.2 脏读Java EE实用教程11.2.1 并发产生的问题并发产生的问题虚读。当多个事务同时操作同一数据时,如果事务A在操作过程中进行两次查询,很有可能第二次查询的结果包含了第一次查询中未出现的数据(这里并不要求两次查询的SQL语句相同)。这是因为,在两次查询过程中由事务B插入了新数据造成的,如表11.3所示。阶 段存 款查 询1事务开始2事务开始3查询账户余额1000元4存入100元,账户中应为1100元5提交事务6再次查询,账户余额为1100元7不知到底是1100元还是1000元表11.3 虚读Java EE实用教程11.2.1 并发产生的问

11、题并发产生的问题不可重复读。当多个事务同时操作同一数据时,如果事务A对同一行数据重复读取两次,却得到了不同的结果,有可能在事务A两次读取的过程中,由事务B对该行数据进行了修改,并成功提交,如表11.4所示。阶 段取 款存 款1事务开始2查询账户余额1000元3事务开始4查询账户余额1000元5存入100元,余额应为1100元6存入100元,账户中应为1100元7提交事务,账户余额为1100元8提交事务,账户余额为1100元表11.4 不可重复读Java EE实用教程11.2.2 解决方案解决方案h1设置隔离级别设置隔离级别标准SQL规范中提供了4种事务隔离级别,可以通过Hibernate的配置

12、文件来设置隔离级别。串行化(Serializable):提供严格的事务隔离。它要求各事务串行化执行,事务只能一个接着一个地串行执行,不能并发执行。当数据库采用此隔离级别时,只要有一个事务在操作某个数据,其他欲操作此数据的事务必须停下来等待,直至那个事务结束,有效地防止了所有可能出现的并发问题,但并发性能较低。可重复读取(RepeatableRead):当数据库采用此隔离级别时,一个事务在执行过程中可以访问其他事务成功提交的新插入的数据,但不能访问成功修改的数据,因而有效地防止了不可重复读取和脏读两类并发问题的发生。读已提交数据(ReadCommitted):当数据库采用此隔离级别时,一个事务在

13、执行过程中既可以访问其他事务成功提交的新插入的数据,又可以访问成功修改的数据,因而有效地防止了脏读。读未提交数据(ReadUncommitted):当数据库采用此隔离级别时,一个事务在执行过程中既可以访问其他事务未提交的新插入的数据,又可以访问未提交的修改数据,因而仅仅防止了更新丢失的发生。Java EE实用教程11.2.2 解决方案解决方案h2锁锁Hibernate支持两种锁机制,悲观锁(PessimisticLocking)和乐观锁(OptimisticLocking)。悲观锁是指对数据被外界修改持保守态度。假定任何时刻存取数据时,都可能有一个客户也正在存取同一数据,为了保持数据被操作的移

14、植性,于是对数据采取了数据库层次的锁定状态,依靠数据库提供的锁机制来实现。乐观锁则乐观地认为数据很少发生同时存取的问题,因而不做数据库层次上的锁定。为了维护正确的数据,乐观锁采用应用程序上的逻辑实现版本控制的方法。Hibernate中以通过版本号检索来实现更新为主,这也是Hibernate推荐的方式。在数据库中假如有一个Version记录,在读取数据时连带版本号一同读取,并在更新数据时递增版本号,然后比较此版本号和数据库中的版本号,如果大于数据库中的版本号,则给予更新,否则就报错误。Java EE实用教程11.3 Hibernate的拦截器的拦截器11.3.1 Interceptor接口接口下

15、面分别介绍这些方法的含义及执行阶段。afterTransactionBegin(Transactiontx):当Hibernate事务被调用后,该方法将被调用。afterTransactionCompletion(Transactiontx):当事务被提交或回滚后,该方法被调用。beforeTransactionCompletion(Transactiontx):该方法在一个事务提交前被调用,但是回滚前不被调用。findDirty(Objectentity,Serializableid,ObjectcurrentState,ObjectpreviousState,StringpropertyN

16、ames,Typetypes):当调用flush()方法刷新缓存时会自动调用这个方法检查缓存中是否有脏数据(缓存中有数据库不一致的数据)。返回的数组是对象脏属性的索引。如果该数组不为空,说明这个对象需要被更新;如果是空的数组,说明这个对象不必被更新,默认返回null。Hibernate会自动使用默认的方式检查对象是否是脏数据。onDelete(ObjectSerializableid,Objectstate,StringpropertyName,Typetypes):在对象删除前被调用。不建议使用给“state”参数赋值来修改要被删除实体的属性值。Java EE实用教程11.3.1 Inter

17、ceptor接口接口onFlushDirty(Objectentity,Serializableid,ObjectcurrentState,ObjectpreviousState,StringpropertyNames,Typetypes):如果一个对象在flush执行时被发现是脏数据,则这个方法会被调用。可以给“currentState”参数赋值,这个赋值既会修改持久化类对象的属性值,也会修改数据库表对应的列值。不建议使用给“previousState”赋值来修改实体更新前的属性值。返回值是boolean类型,true说明在方法体中修改了对象的属性值“currentState”,false说

18、明没有修改其当前属性值。onLoad(Objectentity,Serializableid,Objectstate,StringpropertyNames,Typtypes):当一个对象从数据库中载入时被调用。修改“state”参数,就可以修改持久化类对象的属性值。返回值是boolean类型,true说明在方法体中修改了对象的属性值state,false表示没有修改。onSave(Objectentity,Serializableid,Objectstate,StringpropertyNames,Typetypes):在一个方法保存之前被调用。如果给相应的“state”赋值,这个值能够被i

19、nsert语句保存到数据库中,同时也更改持久化类对象的属性值。返回boolean类型,true代表用户在其中修改了属性值state,false表示没有修改。Java EE实用教程11.3.1 Interceptor接口接口onCollectionRecreate(Objectcollection,Serializablekey):在集合被创建或再次创建时被调用。如果一个持久化类中使用了Java集合属性,那么保存这个持久化类时,这个集合属性中的元素也被同时保存,这个onCollectionRecreate()方法会被自动调用。onCollectionRemove(Objectcollection

20、,Serializablekey):在集合被删除时被调用。onCollectionUpdate(Objectcollection,Serializablekey):在集合被更新时被调用。isTransient(Objectentity):调用这个方法可以判断一个实体是持久化态还是游离态。返回值是boolean类型,如果返回true,代表这个实体是持久化态;如果返回false,代表这个实体是游离态;如果返回null,说明Hibernate使用映射文件中的unsaved-value或者其他方法来判断,这个实体还没有被保存,是临时态。getEntity(StringentityName,Serial

21、izableid):以对象名字和id为参数,可以返回持久化对象实体。getEntityName(Objectobject):以持久态和游离态的实体类对象为参数,可以返回实体的名字。Java EE实用教程11.3.1 Interceptor接口接口instantiate(StringentityName,EntityModeentityMode,Serializableid):这个方法可以显式地让Hibernate实例化一个实体类。参数entityName是实体对象的名字,entityMode是返回的实体实例的类型,参数id将作为新实体对象的id。onPrepareStatement(Strin

22、garg0):这个方法可以返回要执行的SQL语句,参数arg0即是要执行的SQL语句。postFlush(Iteratorarg0):该方法在持久化所做修改同步完成后会执行。preFlush(Iteratorarg0):该方法在同步持久化所做修改之前会执行。Java EE实用教程11.3.2 应用举例应用举例创建Hibernate程序Hibernate_Interceptor,添加Hibernate的类库(核心类库)及数据库驱动,创建配置文件,代码。本例实现对数据库中userTable表的操作,故POJO类及映射文件如下。User.java代码为:packageorg.vo;publiccla

23、ssUserprivateintid;privateStringusername;privateStringpassword;/省略上面属性的get和set方法Java EE实用教程11.3.2 应用举例应用举例映射文件User.hbm.xml代码为:下面编写拦截器,代码。Java EE实用教程11.3.2 应用举例应用举例编写测试类Test.java,代码。运行该测试程序,结果如下:该语句在事务开始之后执行!保存持久化实例时调用该方法这里返回要执行的SQL语句Hibernate:insertintouserTable(username,password)values(?,?)在同步持久化所做修改之前调用该方法持久化所做修改同步完成后,调用该方法该语句在事务提交前被执行!回滚前不执行!该语句在事务提交或回滚后执行!

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 高等教育 > 研究生课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号