选择显示字体大小

在spring中使用jdo

在此前的spring: a developer's notebook摘录中,作者bruce tate和justin gehtland讨论了在spring中使用ibatis or持久化框架的内容。出于其他的原因,此选择要求深入sql底层。在这篇第五章的摘录中,他们转向那些更加彻底地把sql从你的spring应用中独立的持久化框架

jdo是基于接口标准的持久化,或如tate 和gehtland所言,“在java应用中非ejb标准的持久化”。一经提及jdo,他们不是卷入那场“众说纷纭”的辩论之中,而是着眼于如何把一顶级的实现,kodo,引入到你的spring应用中。接着转去讨论最流行的,且可能是与spring集成最好的or框架hibernate。正如他们所指出的,“尽管是非标准的,但你可以说在ejb之后,hibernate是世界上最流行的持久化框架了。”本章中,作者们不仅为你演示设置每个框架的具体细节,而且还清晰地表明了各种框架的使用方法之差异。

就象developer's notebook 系列中所有的书一样,你将由直接的且实用的方式获得信息,这些信息包含了完成你工作所需的细节。换言之:“一切来自实战,没有讲义。”

版权声明:任何获得matrix授权的网站,转载时请务必保留以下作者信息和链接
作者:czyczy(作者的blog:http://blog.matrix.org.cn/page/czyczy)
原文:http://www.matrix.org.cn/resource/article/44/44313_spring+jdo.html
关键字:spring;jdo

spring中使用jdo

jdo是java 应用中非ejb标准的一种持久化方式。在这部分中,我们将使用我们喜欢的jdo实现,kodo,来实现我们应用中的透明持久化。虽然我们不会试着教给你jdo的知识,但会说明怎样使用jdo来为我们的应用提供持久化的功能。

无论你从事jdo多长时间,可能都会使你想起众说纷纭的辩论。直到最近,大多数人都避免使用jdo。随着jdo2.0 版本和许多可靠的商业化及开源的jdo实现的暂停发布,这个持久化标准看起来就象是一个强壮的运动员在orm舞台上蓄势待发(译注:在翻译本文时获悉,jdo2.0已投票通过)。实际上,我所钟爱的orm是solar metric的kodo, 它或许称得上jdo实现中的矫矫者了。当kodo达到商业化实现时,它看起来比其它可供选择的实现更加强壮,且已获得更灵活的映射支持、更易于管理,来自持久化企业核心越来越丰富的支持,考虑以下这些优势:
        若你正寻找某些免费的或能对源代码更好地控制的jdo实现,你可在众多的开源的jdo实现中选择。
        你可选择一价格合理的商业化产品,而且能得到支持和维护。
        若选择了那些一流的商业化厂商,从较佳管理到灵活映射,你都可能得到难以置信的功能和性能。
        在获得所有的这些优势的同时,你还能获得开源标准提供的保护和安全

我该怎么办?

你将使用jdo来创建一个持久化模型,随后在façade层中使用那个模型。尽管应用程序中已创建了业务域模型,但仍未被持久化。你业已获得façade层的接口,那么只需完成下述的操作步骤,便可在你的应用中使用jdo了:
1.通过字节码增强器(byte code enhancer)让域模型持久化。
2.简单修改spring的配置文件,你就可在你的应用中使用kodo。
3.通过jdo模板,建构使用持久化模型的façade。

就这些了。spring会管理由persistencemanagerfactory和persistencemanager组成的jdo之核心资源。把这些特殊的选项当作是jdo的数据源与连接。你还可以让spring来管理事务。上述三个步骤就是你所要完成的工作。

首先,你需要下载和安装kodo。从试用的版本开始,你可在这里找到http://www.solarmetric.com。本书中使用3.2.1版本。再次提醒,你得把/kodo-jdo-3.2.1/lib中的包放入我们的/lib目录下。

为持久化模型,你得修改ant任务以添加jdo字节码增强的步骤:象示例5-8所示的那样,添加ant任务来完成这一动作。

示例5-8.

<taskdef name=&rdquo;jdoc&rdquo; classname=&rdquo;kodo.ant.jdoenhancertask&rdquo; />

<target name=&rdquo;jdo.enhance&rdquo;>
        <jdoc>
                <fileset dir=&rdquo;${src.dir}&rdquo;>
                        <include name=&rdquo;**/*.jdo&rdquo; />
                </fileset>
        </jdoc>
</target>


你也需要在ant 建构文件中给kodo-jdo.jar, jdo-1.0.1.jar, and jakarta-commons-lang-1.0.1.jar增加路径元素。

下一步,建构持久化映射。最简便的办法就是通过kodo向导。运行workbench(在你所安装的kodo的\bin目录下),并从菜单中选择metadata&agrave;create metadate。反之,你可使用/kodo-jdo-3.2.1/bin目录下的metadatatool 和mappingtool两个脚本,它们分别被kodo.jdbc.meta.mappingto-ol和kodo.meta.jdometadatatool的运行文件所使用。

为了与其它jdo版本保持一致,因此你打算用xml从头建构映射文件。用类的元数据和.mapping 文件生成.jdo文件。此两文件都在/war/web-inf/classes/com/springbook目录下。

示例5-9声明元数据文件。

示例5-9  package.jdo
<?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?>
<jdo>
     <package name=&quot;com.springbook&quot;>
         <class name=&quot;bike&quot;>
               <extension vendor-name=&quot;kodo&quot; key=&quot;detachable&quot; value=&quot;true&quot;/>
               <field name=&quot;reservations&quot;>
                     <collection element-type=&quot;reservation&quot;/>
                     <extension vendor-name=&quot;kodo&quot; key=&quot;inverse-owner&quot; value=&quot;bike&quot;/>
                     <extension vendor-name=&quot;kodo&quot; key=&quot;element-dependent&quot; value=&quot;true&quot;/>
               </field>
         </class>
        <class name=&quot;customer&quot;>
              <extension vendor-name=&quot;kodo&quot; key=&quot;detachable&quot; value=&quot;true&quot;/>
              <field name=&quot;reservations&quot;>
                  <collection element-type=&quot;com.springbook.reservation&quot;/>
                  <extension vendor-name=&quot;kodo&quot; key=&quot;inverse-owner&quot; value=&quot;customer&quot;/>
                 <extension vendor-name=&quot;kodo&quot; key=&quot;element-dependent&quot; value=&quot;true&quot;/>
              </field>
        </class>
        <class name=&quot;reservation&quot;>
             <extension vendor-name=&quot;kodo&quot; key=&quot;detachable&quot; value=&quot;true&quot;/>
        </class>
    </package>
</jdo>


示例5-10描述了映射文件。

示例5-10. package.mapping
<?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?>
<mapping>
       <package name=&quot;com.springbook&quot;>
              <class name=&quot;bike&quot;>
                   <jdbc-class-map type=&quot;base&quot; pk-column=&quot;bikeid&quot; table=&quot;bikes&quot;/>
                   <field name=&quot;bikeid&quot;>
                        <jdbc-field-map type=&quot;value&quot; column=&quot;bikeid&quot;/>
                    </field>
                    <field name=&quot;frame&quot;>
                         <jdbc-field-map type=&quot;value&quot; column=&quot;frame&quot;/>
                    </field>
                    <field name=&quot;manufacturer&quot;>
                         <jdbc-field-map type=&quot;value&quot; column=&quot;manufacturer&quot;/>
                     </field>
                     <field name=&quot;model&quot;>
                          <jdbc-field-map type=&quot;value&quot; column=&quot;model&quot;/>
                     </field>
                     <field name=&quot;reservations&quot; default-fetch-group=&quot;true&quot;>
                          <jdbc-field-map type=&quot;one-many&quot; ref-column.bikeid=&quot;bikeid&quot;
                                 table=&quot;reservations&quot;/>
                      </field>
                      <field name=&quot;serialno&quot;>
                           <jdbc-field-map type=&quot;value&quot; column=&quot;serialno&quot;/>
                       </field>
                       <field name=&quot;status&quot;>
                            <jdbc-field-map type=&quot;value&quot; column=&quot;status&quot;/>
                        </field>
                        <field name=&quot;weight&quot;>
                             <jdbc-field-map type=&quot;value&quot; column=&quot;weight&quot;/>
                        </field>
                   </class>
                   <class name=&quot;customer&quot;>
                         <jdbc-class-map type=&quot;base&quot; pk-column=&quot;custid&quot; table=&quot;customers&quot;/>
                         <field name=&quot;custid&quot;>
                               <jdbc-field-map type=&quot;value&quot; column=&quot;custid&quot;/>
                         </field>
                         <field name=&quot;firstname&quot;>
                               <jdbc-field-map type=&quot;value&quot; column=&quot;firstname&quot;/>
                          </field>
                          <field name=&quot;lastname&quot;>
                               <jdbc-field-map type=&quot;value&quot; column=&quot;lastname&quot;/>
                          </field>
                          <field name=&quot;reservations&quot; default-fetch-group=&quot;true&quot;>
                               <jdbc-field-map type=&quot;one-many&quot; ref-column.custid=&quot;custid&quot;
                                       table=&quot;reservations&quot;/>
                          </field>
                     </class>
                     <class name=&quot;reservation&quot;>
                           <jdbc-class-map type=&quot;base&quot; pk-column=&quot;resid&quot; table=&quot;reservations&quot;/>
                           <field name=&quot;bike&quot;>
                                 <jdbc-field-map type=&quot;one-one&quot; column.bikeid=&quot;bikeid&quot;/>
                           </field>
                           <field name=&quot;customer&quot;>
                                 <jdbc-field-map type=&quot;one-one&quot; column.custid=&quot;custid&quot;/>
                           </field>
                           <field name=&quot;reservationdate&quot;>
                                <jdbc-field-map type=&quot;value&quot; column=&quot;resdate&quot;/>
                           </field>
                           <field name=&quot;reservationid&quot;>
                                <jdbc-field-map type=&quot;value&quot; column=&quot;resid&quot;/>
                           </field>
                      </class>
                </package>
     </mapping>



几乎太容易了。模型本身没有被持久化,那就是我们使用or技术的原因。尽管你仍需在你的应用程序中有一层代码,也就是我们所说的fa&ccedil;ade层,来调用那个持久化模型。因此你将看到一系列的模板调用。查询器(finder)声明了jdo查询语句,及持久化删除、更新、新增的对象。你已经有了一个接口,但还需要实现fa&ccedil;ade(如示例5-11)。

示例 5-11. kodorentabike.java

这不是完全的jdo查询语言的查询;它只不过是个过滤器而已。jdo 2.0将会增加一个便利的查询字符串,因而你可以以单一的字符串来添加完全的jdo查询,而毋须建构完全的查询。

public class kodorentabike extends jdodaosupport implements rentabike {
private string storename;

public list getbikes( ) {
return (list)getjdotemplate( ).find(bike.class);
}

public bike getbike(string serialno) {
collection c = getjdotemplate( ).find(bike.class, &quot;serialno == '&quot; + serialno + &quot;'&quot;);
bike b = null;
if(c.size( ) > 0) {
b = (bike)c.iterator().next( );
}
return b;
}

public bike getbike(int bikeid) {
return (bike)getjdotemplate( ).getobjectbyid(bike.class, new long(bikeid));
}

public void savebike(bike bike) {
getjdotemplate( ).makepersistent(bike);
}

public void deletebike(bike bike) {
getjdotemplate( ).deletepersistent(bike);
}

//etc.


最后,你需要设定一些配置来把这些都组装在一起。示例5-12先说明了jdo的配置。
示例 5-12. package.properties

# to evaluate or purchase a license key, visit http://www.solarmetric.com
kodo.licensekey: your_license_key_here
javax.jdo.persistencemanagerfactoryclass: kodo.jdbc.runtime.
jdbcpersistencemanagerfactory
javax.jdo.option.connectiondrivername: com.mysql.jdbc.driver
javax.jdo.option.connectionusername: bikestore
javax.jdo.option.connectionpassword:
javax.jdo.option.connectionurl: jdbc:mysql://localhost/bikestore
javax.jdo.option.optimistic: true
javax.jdo.option.retainvalues: true
javax.jdo.option.nontransactionalread: true
javax.jdo.option.restorevalues: true
kodo.log: defaultlevel=warn, runtime=info, tool=info
kodo.persistencemanagerimpl: detachonclose=true


注意detachonclose 选项。它确保了jdo在关闭连接时的延迟加载,因而你应用程序的其它部分 ,象视图(view),只能访问已加载的bean。

spring上下文需把jdo持久化管理器,持久化管理工厂,fa&ccedil;ade,以及任何在fa&ccedil;ade上的服务组合在一起。这些都在context中完成(示例5-13)。

example 5-13. rentabikeapp-servlet.xml
<bean id=&quot;jdofactory&quot; class=&quot;org.springframework.orm.jdo.localpersistencemanagerfactorybean&quot;>
<property name=&quot;configlocation&quot;>
<value>e:\rentabikeapp\war\web-inf\kodo.properties</value>
</property>
</bean>
<bean id=&quot;transactionmanager&quot; class=&quot;org.springframework.orm.jdo.jdotransactionmanager&quot;>
<property name=&quot;persistencemanagerfactory&quot;>
<ref local=&quot;jdofactory&quot;/>
</property>
</bean>
<bean id=&quot;rentabike&quot; class=&quot;com.springbook.kodorentabike&quot;>
<property name=&quot;storename&quot;><value>bruce's bikes</value></property>
<property name=&quot;persistencemanagerfactory&quot;>
<ref local=&quot;jdofactory&quot;/>
</property>
</bean>



记得你已经有了一个使用fa&ccedil;ade的测试用例,因此你可以建构并让它运行起来。

发生了什么事?

这是个展示spring功能的非常好的例子。尽管你已从根本上颠覆了持久化层的实现,但这并没有影响到应用程序的其它部分。以下就是它怎样工作的说明。

spring首先使用依赖注入来解决所有的依赖。加载的上下文配置了含有你所提供数据源的jdo,随之在fa&ccedil;ade的jdo实现中设定持久化管理器工厂。接着,当你在fa&ccedil;ade上调用方法时,spring给了你持久化管理器并使用它来处理你所提供的查询。你可以这样来看:spring提供一普通的(generic)jdo
fa&ccedil;ade方法,称之为模板。你插入(plug in)细节,并把控制权交给spring

当你在骑自行车或编写代码时,一个最重要的衡量标准是效率。每当脚踏板转一圈,或每写一行代码,你可完成多少的工作?想想jdo版本的应用程序,spring编程模型最迫切的事是效率。为了看明白我说的意思,想一下你没见到的:
&#61623;        没有异常管理,而&#61623;        往往就是这些异常管理混乱了你应用程序的较底层。利用spring未捕捉异常(unchecked exception)的机制,&#61623;        你可以在得到异常的地方适当地做些事情。
&#61623;        没有资源管理。只要有jdbc连接的地方,&#61623;        就有jdo持久化的管理器。spring配置了持久化管理器工厂,&#61623;        并且在模板内为你管理持久化管理器。
&#61623;        你没有被强制管理事务及facade的安全spring让你很容易地来配置这些东西,&#61623;        因此你可以从你的fa&ccedil;ade层中将丑陋的细节束之高阁,&#61623;        让它专注于使用持久化模型。

spring的模板中这些都为你完成了,这些模板放在与spring框架一起的代码中,这些让你读起来更加容易理解,或在必要时debug之。简而言之,你可以在每一行的代码中得到平衡,更象你在高速地踏自行车。那就是所有最成功的框架和程序设计语言的底线。

spring中使用hibernate

spring开发人员选择hibernate作为持久化框架已经有很长的一段时间了。尽管spring团队在持续致力于改善与其它持久化框架的集成,但在所有与spring集成的持久化框架中, hibermate保持了最为广泛使用的地位。确切地说,这两个轻量级的解决方案在相互促进中获得成功,他们一起茁壮成长。在这此例中,我们将表明如何将springhibernate集成起来一同工作。

hibernate是个优秀的持久化框架。她深受欢迎,运行速度相当快,并且是免费的。除此之外,它还拥有丰富的映射支持,且是一个便利的使用模型,使得它在全球的开发者中流行起来。hibernate已经在小型和中型的项目中经受住了非常好的考验。实际上,尽管它还未被确认为标准,但可以说在ejb之后,hibernate是世界上最流行的持久化框架

我该怎么办?

既然你已用持久化域模型和fa&ccedil;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<hibernate-mapping>
<class name=&quot;com.springbook.bike&quot; table=&quot;bikes&quot;>
<id name=&quot;bikeid&quot; column=&quot;bikeid&quot; type=&quot;java.lang.integer&quot;
unsaved-value=&quot;-1&quot;>
<generator class=&quot;native&quot;></generator>
</id>
<property name=&quot;manufacturer&quot; column=&quot;manufacturer&quot; type=&quot;string&quot;/>
<property name=&quot;model&quot; column=&quot;model&quot; type=&quot;string&quot;/>
<property name=&quot;frame&quot; column=&quot;frame&quot; type=&quot;int&quot;/>
<property name=&quot;serialno&quot; column=&quot;serialno&quot; type=&quot;string&quot;/>
<property name=&quot;weight&quot; column=&quot;weight&quot; type=&quot;java.lang.double&quot;/>
<property name=&quot;status&quot; column=&quot;status&quot; type=&quot;string&quot;/>
<set name=&quot;reservations&quot;>
<key column=&quot;bikeid&quot;/>
<one-to-many class=&quot;com.springbook.reservation&quot;/>
</set>
</class>
</hibernate-mapping>


hibernate版的这个映射较之jdo版的相应代码更为雅致。它有着更加丰富的识别码(identification)生成库。

example 5-15. customer.hbm.xml
<hibernate-mapping>
<class name=&quot;com.springbook.customer&quot; table=&quot;customers&quot;>
<id name=&quot;custid&quot; column=&quot;custid&quot; type=&quot;java.lang.integer&quot;
unsaved-value=&quot;-1&quot;>
<generator class=&quot;native&quot;></generator>
</id>
<property name=&quot;firstname&quot; column=&quot;firstname&quot; type=&quot;string&quot;/>
<property name=&quot;lastname&quot; column=&quot;lastname&quot; type=&quot;string&quot;/>
<set name=&quot;reservations&quot;>
<key column=&quot;custid&quot;/>
<one-to-many class=&quot;com.springbook.reservation&quot;/>
</set>
</class>
</hibernate-mapping>


example 5-16. reservation.hbm.xml

<hibernate-mapping>
<class name=&quot;com.springbook.reservation&quot; table=&quot;reservations&quot;>
<id name=&quot;reservationid&quot; column=&quot;resid&quot; type=&quot;java.lang.integer&quot;
unsaved-value=&quot;-1&quot;>
<generator class=&quot;native&quot;></generator>
</id>
<property name=&quot;reservationdate&quot; column=&quot;resdate&quot; type=&quot;date&quot;/>
<many-to-one name=&quot;bike&quot; column=&quot;bikeid&quot; class=&quot;com.springbook.bike&quot;
cascade=&quot;none&quot;/>
<many-to-one name=&quot;customer&quot; column=&quot;custid&quot; class=&quot;com.springbook.customer&quot;
cascade=&quot;none&quot;/>
</class>
</hibernate-mapping>


在上下文中,你需要配置hibernate属性,配置session factory, 并把session factory插入到fa&ccedil;ade中。使用jdo 上下文、ibatis上下文及hibernate上下文的事务策略都是一样的,就想他们本该那样似的。那就是依赖注入正为你所做的一部分。示例5-17表明了对上下文的变动。

example 5-17. rentabikeapp-servlet.xml
<bean name=&quot;rentabike&quot; class=&quot;com.springbook.hibrentabike&quot;>
<property name=&quot;storename&quot;><value>bruce's bikes</value></property>
<property name=&quot;sessionfactory&quot;>
<ref local=&quot;sessionfactory&quot;/>
</property>
</bean>
<bean id=&quot;sessionfactory&quot;
class=&quot;org.springframework.orm.hibernate.localsessionfactorybean&quot;>
<property name=&quot;datasource&quot;><ref local=&quot;datasource&quot;/></property>
<property name=&quot;mappingresources&quot;>
<list>
<value>com/springbook/bike.hbm.xml</value>
<value>com/springbook/customer.hbm.xml</value>
<value>com/springbook/reservation.hbm.xml</value>
</list>
</property>
<property name=&quot;hibernateproperties&quot;>
<props>
<prop key=&quot;hibernate.dialect&quot;>
.net.sf.hibernate.dialect.mysqldialect
</prop>
<prop key=&quot;hibernate.show_sql&quot;>true</prop>
</props>
</property>
</bean>


不象jdo那样,hibernate用户经常把所有的映射类放入独立定的多个文件中。这不是必需的,仅是hibernate用户特别喜欢管理事前的一种方式而已。

既然已有了一个fa&ccedil;ade接口,你只需一个hibernate实现即可。你可以使用模板,就象jdo那样。至于查询器(finder),你所要做的就是指定一个hibernate 查询语言(hql)语句。至于更新(update)部分,你所要做的就是指明将被存储的新对象。示例5-18就是个非常薄的fa&ccedil;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(&quot;from bike&quot;);
}

public bike getbike(string serialno) {
bike b = null;
list bikes = gethibernatetemplate( ).
find(&quot;from bike where serialno = ?&quot;, 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(&quot;from customer&quot;);
}

public customer getcustomer(int custid) {
return (customer)gethibernatetemplate( ).
load(customer.class, new integer(custid));
}

public list getreservations( ) {
return gethibernatetemplate( ).find(&quot;from reservation&quot;);
}

public list getreservations(customer customer) {
return gethibernatetemplate( ).
find(&quot;from reservation where custid = ?&quot;, customer.getcustid( ));
}


public list getreservations(bike bike) {
return gethibernatetemplate( ).
find(&quot;from reservation where bikeid = ?&quot;, bike.getbikeid( ));
}

public list getreservations(date date) {
return gethibernatetemplate( ).
find(&quot;from reservation where resdate = ?&quot;, 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(&quot;from bike&quot;);
}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(&quot;from bike&quot;);
}


新手需要特别注意本文代码中的黑体字部分,应用程序的每一代码块必须尽力完成好一个功能,且只能一个。

关于&hellip;
&hellip;hibernate的替代品?hibernate确实是免费的、运行速度快的、有效且是流行的。它已经受住了考验,且有着极其优秀的性能和灵活性。大部分的工具中有着很好的hibernate支持,并且hibernate支持所有相关的数据库。但我仍只推荐在小型和大型的应用中使用hibernate

到目前为止,h作为一开源框架,持久化社区不能过多地赞扬hibernate或声讨其替代者。如此盲目的拥趸导致了礼教崇拜式的决策。hibernate的竞争者们在某些方面比她做得更好。若你的应用程序有以下的特征,不妨试一试其他的解决方案:

标准
jdo和jdbc解决方案已然成为标准。尽管hibernate开源的,但她还未被确认为标准。在过去的十年中,你得信赖jboss 组织和基金会的动机来做正确的事情,且对任何的框架而言,至今已证明那是不可靠的地位。

管理
其他的解决方案易于管理,如kodo jdo和top link就有管理面板,用他们很容易地来监控缓存状态,及主动(eager)加载或延迟加载的状态。

映射
其他的框架有着功能更强大的和更加灵活的映射支持。若你不想对你的数据库schema进行控制,你最好选用其他的解决方案。你可能也喜欢用gui工具来映射你的schema ,那么,象jdo genie 或cayenne可能就最适合你的应用。

总而言之,使用主流的框架或许最终可能是正确的选择,但通常情况下,只要稍微深入的探究,你就可以找到更加合适的解决方案。hibernate确实值得考虑,但别忘了还有其他好的选择。

运行一个测试用例

运行测试用例是很容易的事,你已经学会了。它就是你在fa&ccedil;ade 上运行的那个测试用例。

我该怎么办?

由于测试用例已存在,因此你可以运行现有的fa&ccedil;ade测试。你仅要确保正确设置测试数据即可。且你可以使用未被变更过的应用上下文。那就是spring的强大之处,可测试性。

发生了什么事?

你使用过已存在的测试用例,这很好,因为你只需要管理数据库增长的细节,在下章中,你将开始深入学习可在spring aop的应用程序中添加的服务的相关知识。


 


关键字 本文所属关键字

相关 与本文相关文章

分类 所有文章关键字导航

源码编程相关

Java   Asp   PHP   .Net   XML   C/C++   CGI   VB   Jsp   J2ee   J2se   J2me   EJB   Servlet   Tomcat   Resin   Struts   Weblogic   Eclipse   ANT   GUI   JMS   Web servise   IDEA   Webphere   Hibernate   Spring   Jboss   Applet   Swing   Socket   Javamail   Perl   Ajax   P2P   安全   模式   框架   测试   开源   游戏

SQL数据库相关

My-SQL   Ms-SQL   Access   DB2   Oracle   Sybase   SQLserver   索引   存储过程   加密   数据库   分页   视图  

手机无线相关

3G   Wap   CDMA   GRPS   GSM   IVR   彩信   短信   无线   增值业务

网页设计制作相关

HTML   CSS   网页配色   网页特效   Javascript   VBscript   Dreamweaver   Frontpage   JS   Web   网站设计

网站建设推广相关

建站经验   网站优化   网站排名   推广   Alexa

操作系统/服务器相关

Windows XP   Windows 2000   Windows 2003   Windows Me   Windows 9.x   Linux   UNIX   注册表   操作系统   服务器   应用服务器

图形图像多媒体相关

Photoshop   Fireworks   Flash   Coreldraw   Illustrator   Freehand   Photoimpact   多媒体   图形图像

标准 网站致力的规范

Valid CSS!

无不良内容,无不良广告,无恶意代码

Valid XHTML 1.0 Transitional

creativecommons