在此前的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=”jdoc” classname=”kodo.ant.jdoenhancertask” />
<target name=”jdo.enhance”>
<jdoc>
<fileset dir=”${src.dir}”>
<include name=”**/*.jdo” />
</fileset>
</jdoc>
</target>
<?xml version="1.0" encoding="utf-8"?>
<jdo>
<package name="com.springbook">
<class name="bike">
<extension vendor-name="kodo" key="detachable" value="true"/>
<field name="reservations">
<collection element-type="reservation"/>
<extension vendor-name="kodo" key="inverse-owner" value="bike"/>
<extension vendor-name="kodo" key="element-dependent" value="true"/>
</field>
</class>
<class name="customer">
<extension vendor-name="kodo" key="detachable" value="true"/>
<field name="reservations">
<collection element-type="com.springbook.reservation"/>
<extension vendor-name="kodo" key="inverse-owner" value="customer"/>
<extension vendor-name="kodo" key="element-dependent" value="true"/>
</field>
</class>
<class name="reservation">
<extension vendor-name="kodo" key="detachable" value="true"/>
</class>
</package>
</jdo>
<?xml version="1.0" encoding="utf-8"?>
<mapping>
<package name="com.springbook">
<class name="bike">
<jdbc-class-map type="base" pk-column="bikeid" table="bikes"/>
<field name="bikeid">
<jdbc-field-map type="value" column="bikeid"/>
</field>
<field name="frame">
<jdbc-field-map type="value" column="frame"/>
</field>
<field name="manufacturer">
<jdbc-field-map type="value" column="manufacturer"/>
</field>
<field name="model">
<jdbc-field-map type="value" column="model"/>
</field>
<field name="reservations" default-fetch-group="true">
<jdbc-field-map type="one-many" ref-column.bikeid="bikeid"
table="reservations"/>
</field>
<field name="serialno">
<jdbc-field-map type="value" column="serialno"/>
</field>
<field name="status">
<jdbc-field-map type="value" column="status"/>
</field>
<field name="weight">
<jdbc-field-map type="value" column="weight"/>
</field>
</class>
<class name="customer">
<jdbc-class-map type="base" pk-column="custid" table="customers"/>
<field name="custid">
<jdbc-field-map type="value" column="custid"/>
</field>
<field name="firstname">
<jdbc-field-map type="value" column="firstname"/>
</field>
<field name="lastname">
<jdbc-field-map type="value" column="lastname"/>
</field>
<field name="reservations" default-fetch-group="true">
<jdbc-field-map type="one-many" ref-column.custid="custid"
table="reservations"/>
</field>
</class>
<class name="reservation">
<jdbc-class-map type="base" pk-column="resid" table="reservations"/>
<field name="bike">
<jdbc-field-map type="one-one" column.bikeid="bikeid"/>
</field>
<field name="customer">
<jdbc-field-map type="one-one" column.custid="custid"/>
</field>
<field name="reservationdate">
<jdbc-field-map type="value" column="resdate"/>
</field>
<field name="reservationid">
<jdbc-field-map type="value" column="resid"/>
</field>
</class>
</package>
</mapping>
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, "serialno == '" + serialno + "'");
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.# 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
<bean id="jdofactory" class="org.springframework.orm.jdo.localpersistencemanagerfactorybean">
<property name="configlocation">
<value>e:\rentabikeapp\war\web-inf\kodo.properties</value>
</property>
</bean>
<bean id="transactionmanager" class="org.springframework.orm.jdo.jdotransactionmanager">
<property name="persistencemanagerfactory">
<ref local="jdofactory"/>
</property>
</bean>
<bean id="rentabike" class="com.springbook.kodorentabike">
<property name="storename"><value>bruce's bikes</value></property>
<property name="persistencemanagerfactory">
<ref local="jdofactory"/>
</property>
</bean>
<class name="com.springbook.bike" table="bikes">
<id name="bikeid" column="bikeid" type="java.lang.integer"
unsaved-value="-1">
<generator class="native"></generator>
</id>
<property name="manufacturer" column="manufacturer" type="string"/>
<property name="model" column="model" type="string"/>
<property name="frame" column="frame" type="int"/>
<property name="serialno" column="serialno" type="string"/>
<property name="weight" column="weight" type="java.lang.double"/>
<property name="status" column="status" type="string"/>
<set name="reservations">
<key column="bikeid"/>
<one-to-many class="com.springbook.reservation"/>
</set>
</class>
</hibernate-mapping>
<hibernate-mapping>
<class name="com.springbook.customer" table="customers">
<id name="custid" column="custid" type="java.lang.integer"
unsaved-value="-1">
<generator class="native"></generator>
</id>
<property name="firstname" column="firstname" type="string"/>
<property name="lastname" column="lastname" type="string"/>
<set name="reservations">
<key column="custid"/>
<one-to-many class="com.springbook.reservation"/>
</set>
</class>
</hibernate-mapping>
<hibernate-mapping>
<class name="com.springbook.reservation" table="reservations">
<id name="reservationid" column="resid" type="java.lang.integer"
unsaved-value="-1">
<generator class="native"></generator>
</id>
<property name="reservationdate" column="resdate" type="date"/>
<many-to-one name="bike" column="bikeid" class="com.springbook.bike"
cascade="none"/>
<many-to-one name="customer" column="custid" class="com.springbook.customer"
cascade="none"/>
</class>
</hibernate-mapping>
<bean name="rentabike" class="com.springbook.hibrentabike">
<property name="storename"><value>bruce's bikes</value></property>
<property name="sessionfactory">
<ref local="sessionfactory"/>
</property>
</bean>
<bean id="sessionfactory"
class="org.springframework.orm.hibernate.localsessionfactorybean">
<property name="datasource"><ref local="datasource"/></property>
<property name="mappingresources">
<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="hibernateproperties">
<props>
<prop key="hibernate.dialect">
.net.sf.hibernate.dialect.mysqldialect
</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
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));
}
}
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;
}public list getbikes( ) {
return gethibernatetemplate( ).find("from bike");
}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 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器