iBATIS似乎已远离众说纷纭的OR框架之列,通常人们对非常流行的Hibernate情有独钟。但正如Spring: A Developer's Notebook作者Bruce Tate 和Justin Gehtland所说的那样,与其他的OR框架相比,iBATIS独辟蹊径:“iBATIS不是试图从根本上掩盖SQL,实际上,它是在拥抱SQL。”
但别犯愁:SQL本身具备了一些重要的功能,并且通过模板的使用,在Spring应用中采用iBATIS显得轻而易举。在此摘录中,两位作者将和你一起安装iBATIS并将其集成进你的Spring应用中。他们也阐明了怎样取得你已编写的SQL语句及把他们映射给iBATIS使用的Bean。最后,还讨论了iBATIS的优缺点,及为什么是这样的一种方式,即所谓的“在完全OR与JDBC之间的一个幽雅的折衷。”
就象Developer's Notebook 系列中所有的书一样,你将由直接的且实用的方式获得信息,这些信息包含了完成你工作所需的细节。换言之:“一切来自实战,没有讲义。”
版权声明:任何获得Matrix授权的网站,转载时请务必保留以下作者信息和链接
作者:czyczy(作者的blog:http://blog.matrix.org.cn/page/czyczy)
原文:http://www.matrix.org.cn/resource/article/44/44304_Spring+iBATIS.html
关键字:Spring;iBATIS
对象关系持久化(OR Persistence)
本章所涉及的内容为:
· 与iBATIS的集成
· 在Spring的应用中使用JDO
· 在Spring的应用中使用Hibernate
· 运行测试用例
离我住处不远的地方,名为啤酒山的山上有一个臭名远扬的山地自行车道。我想不出它为何会得到这样的名字,因为在下山的时候你要保持完全地清醒甚至于全神贯注。据我所知,那决不是纯粹的攀爬(或不曾离开自行车步行)。大多数人认为那很荒谬,哪怕只是去尝试一下而已。这座山连绵起伏,异常陡峭,它的表面覆盖了松散的岩石和大量的岩脊。我想我一定是太厌烦我的余生了,因为两年半来我一直不断地在攀爬。在我看来,那样的一座山峰就像是一个困难的编程问题。我已多次重新启程,在到达山峰的途中,尝试过翻越许多岩脊和泥砾丛的不同途径。为了攀爬啤酒山, 我需要改良自行车,提高车技,加强训练。
对Java 开发人员而言,对象关系映射已然成为那类问题了。我们需要处理功能(processing power)、较佳设计模式及更好持久化框架的组合,从而使解决持久化设计变得更加清晰。最终,我们开始取得实质性的进展。现在,我们已逼近山峰,象Spring这样的框架就象是方程式的一部分,因为他们让对象关系映射(ORM)花较少的精力来做更多的事情。在本章中,你将看到三种框架:iBATIS, JDO及Hibernate:
·iBATIS 是一种JDBC助手类框架,它给了你一些OR映射及使用OR的好处,但不带 有太多的风险。
·JDO是一种饱受争议的持久化标准,但它有着一些独特的实现,这使得JDO在行业中也算得上是最完美的持久化框架之一。
·Hibernate 是在JBoss组织控制下的一开源持久化框架。它可能是时下最为流行的持久化框架。大量的客户采用它,而且客户的数量还在持续稳定地增长。
在本章中,我们会对所提的三个框架进行尝试,而不必对应用的其余部分的代码做任何变更。
与iBATIS集成
常言道:“树大招风”。在大肆宣扬的J2EE和.Net之争中, Sun的一示例应用程序被用来作为衡量应用服务器在运行时的各项性能的核心基准。 .Net非常好地打败了基于EJB的J2EE版本, 且方兴未艾。Clinton Begin 开发了iBATIS的持久化框架,他在iBATIS中使用PetStore的简化版,且自从那以后iBATIS就越来越流行。Spring提供非常优良的与iBATIS的集成功能, 在此章中将对其进行介绍。
并非所有的问题都非常适合持久化框架这朵盛开的花朵,中等难度的问题是最合适的环境。没有正确的技巧或不相称的问题,可能就会误入歧途。跟我一起教课的Ted Neward, 他是《Effective Enterprise Java》一书的作者,他经常把构建或采用持久化框架与美国的越南战争拿来做比较,进入这样的两场战争是很诱人的,但最终都很难赢得胜利,而且此二例中并不存在着行之有效的策略。关于这一话题,你仍可查阅http://www.neward.net上的相关内容。
然而,我不想扯得太远。尝试一下象iBATIS SqlMaps的框架给了你OR的使用模型又何尝不可呢?当然,我们不会强迫你一口吞下一只大象。具体来说,iBATIS让你:
·映射字段和SQL语句到关键字
·使用SQL的全部功能而没有乏味的JDBC
·从你的代码中剥离SQL
Spring 与iBATIS的集成给了你这些及更多的裨益, 让我们为此而忙乎起来。
我该怎么做?
首先,你需要安装iBATIS。由于iBATIS的配置会在你的Spring 应用上下文中完成,因此你不需要立即配置它。在http://www.ibatis.com/(译注:最新的网址为:http://ibatis.apache.org/,iBATIS已于2004-08-16并入Apache 软件基金会)上可以下载并安装。在本书中我们使用1.3.1版本。把iBATIS提供的jars(ibatis-sqlmap.jar, ibatis-dao.jar, and ibatis-common.jar)和Spring提供的jdom.jar(在Spring的/lib 目录下)放到你的项目目录/war/WEB-INF/lib中。
You’ve already got the interface for the façade and the model, so you need an implementation of the façade and the SQL statement. First, you can implement the façade for the application, as in Example 5-1.
你已经有了门户(façade)和模型(model)的接口,因而你需要facade和SQL语句的实现。首先,你可以象示例5-1那样,在你的应用中实现façade的接口。
示例 5-1 IBatisRentABike.java
public class IBatisRentABike extends SqlMapDaoSupport implements RentABike { private String storeName =""; public void setStoreName(String storeName) { this.storeName= storeName; } public String getStoreName( ) { return this.storeName; } public List getBikes() { return getSqlMapTemplate().executeQueryForList("getBikes", null); } public Bike getBike(String serialNo) { return (Bike) getSqlMapTemplate(). executeQueryForObject("getBikeBySerialNo", serialNo); } public Bike getBike(int bikeId) { return (Bike) getSqlMapTemplate(). executeQueryForObject("getBikeByID", new Integer(bikeId)); } public void saveBike(Bike bike) { getSqlMapTemplate().executeUpdate("saveBike", bike); } public void deleteBike(Bike bike) { getSqlMapTemplate().executeUpdate("deleteBike", bike); } public List getCustomers() { return getSqlMapTemplate().executeQueryForList("getCustomers", null); } public Customer getCustomer(int custId) { return (Customer) getSqlMapTemplate(). executeQueryForObject("getCustomer", new Integer(custId)); } public List getReservations() { return getSqlMaptemplate(). executeQueryForList("getReservations", null); } public List getReservations(Customer customer) { return getSqlMaptemplate(). executeQueryForList("getReservationsForCustomer", customer); } public List getReservations(Bike bike) { return getSqlMaptemplate(). executeQueryForList("getReservationsForBike",bike); } public List getReservations(Date date) { return getSqlMaptemplate(). executeQueryForList("getReservationsForDate", date); } public Reservation getReservation(int resId) { return getSqlMaptemplate(). executeQueryForObject("getReservation", new Integer(resId)); }}