扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
作者:中国IT实验室 来源:中国IT实验室 2007年9月30日
关键字:
在本页阅读全文(共4页)
发生了什么事?
这是个展示Spring功能的非常好的例子。尽管你已从根本上颠覆了持久化层的实现,但这并没有影响到应用程序的其它部分。以下就是它怎样工作的说明。
Spring首先使用依赖注入来解决所有的依赖。加载的上下文配置了含有你所提供数据源的JDO,随之在fa?ade的JDO实现中设定持久化管理器工厂。接着,当你在fa?ade上调用方法时,Spring给了你持久化管理器并使用它来处理你所提供的查询。你可以这样来看:Spring提供一普通的(generic)JDO fa?ade方法,称之为模板。你插入(plug in)细节,并把控制权交给Spring.
当你在骑自行车或编写代码时,一个最重要的衡量标准是效率。每当脚踏板转一圈,或每写一行代码,你可完成多少的工作?想想JDO版本的应用程序,Spring编程模型最迫切的事是效率。为了看明白我说的意思,想一下你没见到的:? 没有异常管理,而? 往往就是这些异常管理混乱了你应用程序的较底层。利用Spring未捕捉异常(Unchecked Exception)的机制,? 你可以在得到异常的地方适当地做些事情。? 没有资源管理。只要有JDBC连接的地方,? 就有JDO持久化的管理器。Spring配置了持久化管理器工厂,? 并且在模板内为你管理持久化管理器。? 你没有被强制管理事务及facade的安全。Spring让你很容易地来配置这些东西,? 因此你可以从你的fa?ade层中将丑陋的细节束之高阁,? 让它专注于使用持久化模型。
在Spring的模板中这些都为你完成了,这些模板放在与Spring框架一起的代码中,这些让你读起来更加容易理解,或在必要时debug之。简而言之,你可以在每一行的代码中得到平衡,更象你在高速地踏自行车。那就是所有最成功的框架和程序设计语言的底线。
在Spring中使用Hibernate
Spring开发人员选择Hibernate作为持久化框架已经有很长的一段时间了。尽管Spring团队在持续致力于改善与其它持久化框架的集成,但在所有与Spring集成的持久化框架中, Hibermate保持了最为广泛使用的地位。确切地说,这两个轻量级的解决方案在相互促进中获得成功,他们一起茁壮成长。在这此例中,我们将表明如何将Spring与Hibernate集成起来一同工作。
Hibernate是个优秀的持久化框架。她深受欢迎,运行速度相当快,并且是免费的。除此之外,它还拥有丰富的映射支持,且是一个便利的使用模型,使得它在全球的开发者中流行起来。Hibernate已经在小型和中型的项目中经受住了非常好的考验。实际上,尽管它还未被确认为标准,但可以说在EJB之后,Hibernate是世界上最流行的持久化框架。
我该怎么办?
既然你已用持久化域模型和fa?ade 的ORM配置了Spring,你就了解了基本的流程。由于Spring 被设计成与Hibernate 独立,你只需从Spring的/dist 目录中复制hibernate2.jar, aopalliance.jar, cglig-full-2.0.2.jar, dom4j.jar, ehcache-1.1.jar, 及admg.jar到你项目的/lib目录下。
由于Hibernate使用了反射机制, 因此就没有字节加强步骤。所有你已尝试过让模型持久化的做法,就是来创建映射,并且在上下文中引用他们。示例5-14,5-15及5-16表明了创建映射的过程。
Example 5-14. Bike.hbm.xml
unsaved-value="-1">
Hibernate版的这个映射较之JDO版的相应代码更为雅致。它有着更加丰富的识别码(Identification)生成库。
Example 5-15. Customer.hbm.xml
unsaved-value="-1"> Example 5-16. Reservation.hbm.xml unsaved-value="-1">cascade="none"/>cascade="none"/>
在上下文中,你需要配置Hibernate属性,配置session factory, 并把session factory插入到fa?ade中。使用JDO 上下文、iBATIS上下文及Hibernate上下文的事务策略都是一样的,就想他们本该那样似的。那就是依赖注入正为你所做的一部分。示例5-17表明了对上下文的变动。
Example 5-17. RentABikeApp-servlet.xml
Bruce's Bikesclass="org.springframework.orm.hibernate.LocalSessionFactoryBean">
com/springbook/Bike.hbm.xmlcom/springbook/Customer.hbm.xmlcom/
springbook/Reservation.hbm.xmlnet.sf.hibernate.dialect.MySQLDialecttrue
不象JDO那样,Hibernate用户经常把所有的映射类放入独立定的多个文件中。这不是必需的,仅是Hibernate用户特别喜欢管理事前的一种方式而已。
既然已有了一个fa?ade接口,你只需一个Hibernate实现即可。你可以使用模板,就象JDO那样。至于查询器(Finder),你所要做的就是指定一个Hibernate 查询语言(HQL)语句。至于更新(update)部分,你所要做的就是指明将被存储的新对象。示例5-18就是个非常薄的fa?ade的例子。
Example 5-18. HibRentABike.java
package com.springbook;import org.springframework.orm.hibernate.support.HibernateDaoSupport;import java.util.List;import java.util.Date;import java.util.Set;import net.sf.hibernate.Query;public class HibRentABike extends HibernateDaoSupport implements RentABike {private String name;public List getBikes( ) {return getHibernateTemplate( )。find("from Bike");}public Bike getBike(String serialNo) {Bike b = null;List bikes = getHibernateTemplate( )。find("from Bike where serialNo = ?", serialNo);if(bikes.size( ) > 0) {b = (Bike)bikes.get(0);}return b;}public Bike getBike(int bikeId) {return (Bike)getHibernateTemplate( )。load(Bike.class, new Integer(bikeId));}public void saveBike(Bike bike) {getHibernateTemplate( )。saveOrUpdate(bike);}public void deleteBike(Bike bike) {getHibernateTemplate( )。delete(bike);}public void setStoreName(String name) {this.name = name;}public String getStoreName( ) {return this.name;}public List getCustomers( ) {return getHibernateTemplate( )。find("from Customer");}public Customer getCustomer(int custId) {return (Customer)getHibernateTemplate( )。load(Customer.class, new Integer(custId));}public List getReservations( ) {return getHibernateTemplate( )。find("from Reservation");}public List getReservations(Customer customer) {return getHibernateTemplate( )。find("from Reservation where custId = ?", customer.getCustId( ));}public List getReservations(Bike bike) {return getHibernateTemplate( )。find("from Reservation where bikeId = ?", bike.getBikeId( ));}public List getReservations(Date date) {return getHibernateTemplate( )。find("from Reservation where resdate = ?", date);}public Reservation getReservation(int resId) {return (Reservation)getHibernateTemplate( )。load(Reservation.class, new Integer(resId));}}发生了什么事?Hiberante的做法与JDO极其相似。Spring的JDO模板代表着一套默认的DAO方法。你所要做的就是来定制他们,通常是HQL查询语句,及任何HQL参数化查询中参数的可能取值。接着Spring拿到控制权,获得session,发动查询并且处理任何的异常。再次重申,你看到独特的平衡。示例5-19给了在不使用Spring时,你不得不编写的典型的Hibernate之方法。Example 5-19. HibRentABike.java public List getBikesOldWay( ) throws Exception {// Relies on other static code for configuration// and generation of SessionFactory. Might look like:// Configuration config = new Configuration( );// config.addClass(Bike.class)。addClass(Customer.class)。// addClass(Reservation.class);// SessionFactory mySessionFactory = Configuration.// buildSessionFactory( );List bikes = null;Session s = null;try {s = mySessionFactory.openSession( );bikes = s.find("from Bike");}catch (Exception ex) {//handle exception gracefully}finally {s.close( );}return bikes;}示例5-20再次表明了在Spring中实现查找的相应代码。Example 5-20. HibRentABike.java public List getBikes( ) {return getHibernateTemplate( )。find("from Bike");}
新手需要特别注意本文代码中的黑体字部分,应用程序的每一代码块必须尽力完成好一个功能,且只能一个。
濡傛灉鎮ㄩ潪甯歌揩鍒囩殑鎯充簡瑙T棰嗗煙鏈€鏂颁骇鍝佷笌鎶€鏈俊鎭紝閭d箞璁㈤槄鑷抽《缃戞妧鏈偖浠跺皢鏄偍鐨勬渶浣抽€斿緞涔嬩竴銆�