`

Java数据对象(JDO)的应用

 
阅读更多

在本篇文章中,我们将详细地讨论Sun公司的Java数据对象(JDO)标准。JDO允许我们使用Java对象,支持事务和多用户。与ODBC不同的是,它使我们无需考虑SQL和与数据库有关的其他东西。它与串行化也有所区别,因为它支持多个用户和事务。JDO允许Java开发人员将他们的数据模型用作数据模型,无需在“数据端”、“对象端”之间的转移方面花费大量的时间。
包括CocoBase、WebGainTOPLink和CastorJDO在内的多种产品都可以实现了JDO标准。既然有一种标准的方法,我们就可以只学习其中的一种,就象有了ODBC,我们就可以使用任何提供了驱动程序的数据库那样。
在本篇文章中,我们将使用Prism技术公司的OpenFusionJDO。读者在后面会发现,只有很小一部分代码使用了PrismTechAPI,其他部分都使用了标准的JDO标准。
创建Person对象
我们将首先创建一个Person对象,该对象遵循了JavaBean的惯例,可以对其属性执行get和set操作。需要注意的是,尽管我们是在创建这个类,但它并没有什么特别的,它没有继承或实现任何基本类。对一个可保持类的要求是:
1、所有域必须能够被JDO类访问(public或set*方法)
2、域的数据类型必须符合JDO规格。
3、不能支持一些类型的字段(例如Thread、File、Socket等不能串行化的字段)。
下面是符合上述要求的Person.java:

publicclassPerson{
privateStringname;
privateStringaddress;
privateStringssn;
privateStringemail;
privateStringhomePhone;
privateStringworkPhone;

//允许我们使用构造器创建Person对象
publicPerson(Stringname,Stringaddress,Stringssn,
Stringemail,StringhomePhone,StringworkPhone){
this.name=name;
this.address=address;
this.ssn=ssn;
this.email=email;
this.homePhone=homePhone;
this.workPhone=workPhone;
}


//方法
publicStringgetName(){returnname;}

publicStringgetAddress(){returnaddress;}

publicStringgetSsn(){returnssn;}

publicStringgetEmail(){returnemail;}

publicStringgetHomePhone(){returnhomePhone;}

publicStringgetWorkPhone(){returnworkPhone;}

publicvoidsetName(Stringname){this.name=name;}

publicvoidsetAddress(Stringaddress){
this.address=address;
}

publicvoidsetSsn(Stringssn){this.ssn=ssn;}

publicvoidsetEmail(Stringemail){this.email=email;}

publicvoidsetHomePhone(StringhomePhone){
this.homePhone=homePhone;
}
publicvoidsetWorkPhone(StringworkPhone){
this.workPhone=workPhone;
}
}
创建PersonPersist对象管理可保持性
现在已经有了Person对象,我们需要创建一些代码来管理这种可保持性。下面我们将详细讨论这些代码,并学习如何:
1、初始化JDO可保持性管理器。
2、向数据库中输入三个人的资料。
3、从数据库中显示人的资料。
4、修改其中一个人的名字。
5、从数据库中删除一个人的资料。
6、在main()方法中进行相关的处理。
第一步:初始化JDO可保持性管理器
我们从OpenFusion实现中导入了标准的JDO类和ManagedConnectionFactory,当然了我们也可以将它们抽象成一个独立的类。构造器使用javax.jdo.PersistenceManagerFactoryClass属性设置连接代理,这一点与在JDBC中设置数据库驱动程序的属性很相似。
packageaddressbook;

importjava.util.*;
importjavax.jdo.*;

import
com.prismt.j2ee.connector.jdbc.ManagedConnectionFactoryImpl;

publicclassPersonPersist
{
privatefinalstaticintSIZE=3;
privatePersistenceManagerFactorypmf=null;
privatePersistenceManagerpm=null;
privateTransactiontransaction=null;

//需要保持的人的数组
privatePerson[]people;
//现有对象标识符的向量
privateVectorid=newVector(SIZE);

publicPersonPersist(){
try{
Propertiesprops=newProperties();

props.setProperty("javax.jdo.PersistenceManagerFactoryClass",
"com.prismt.j2ee.jdo.PersistenceManagerFactoryImpl");
pmf=JDOHelper.getPersistenceManagerFactory(props);
pmf.setConnectionFactory(createConnectionFactory());
}catch(Exceptionex){
ex.printStackTrace();
System.exit(1);
}
}
连接代理是在名字为createConnectionFactory()的静态方法中创建的,该代理需要JDBCURL、JDBC驱动程序、用户名和口令。
publicstaticObjectcreateConnectionFactory(){
ManagedConnectionFactoryImplmcfi=new
ManagedConnectionFactoryImpl();
ObjectconnectionFactory=null;

try{
mcfi.setUserName("scott");
mcfi.setPassword("tiger");
mcfi.setConnectionURL(
"jdbc:oracle:thin:@localhost:1521:thedb");

mcfi.setDBDriver("oracle.jdbc.driver.OracleDriver");

connectionFactory=mcfi.createConnectionFactory();
}catch(Exceptione){
e.printStackTrace();
System.exit(1);
}
returnconnectionFactory;
}


第二步:在数据库中输入三个人的资料

PersistPeople()使用Person.java文件中的构造器创建了3个人的资料。。我们要作的第一件事是通过
getPersistenceManager()获得一个可保持性管理器,然后创建一个执行我们的任务的事务。为了保持这一对象结构图,我们简单地调用makePersistentAll(Object[])方法即可。代码底部的for()循环获得每个保持对象的唯一的ID,并保存起来供以后使用。
publicvoidpersistPeople(){
//创建人的资料的数组
people=newPerson[SIZE];

//创建3个人的资料
people[0]=newPerson("GarySegal","123FoobarLane",
"123-123-1234","gary@segal.com",
"(608)294-0192","(608)029-4059");
people[1]=newPerson("MichaelOwen",
"222BazzaLane,Liverpool,MN",
"111-222-3333","michael@owen.com",
"(720)111-2222","(303)222-3333");
people[2]=newPerson("RoyKeane",
"222TraffordAve,Manchester,MN",
"234-235-3830","roy@keane.com",
"(720)940-9049","(303)309-7599)");

//保持这3个人的资料
pm=pmf.getPersistenceManager();
transaction=pm.currentTransaction();
pm.makePersistentAll(people);
transaction.commit();

//获取被保持对象的对象ID
for(inti=0;i<people.length;i++){
id.add(pm.getObjectId(people[i]));
}

//关闭现有的保持性管理器,保证对象是从数据库而不是从保持性管理器的缓存中读取的
pm.close();
}
下面是一些可以针对保持性管理器的其他方法:
使实例成为可保持的:获得一个临时对象,并保持它。
删除可保持实例:从数据存储库中删除信息。
使实例临时化:使实例与可保持性管理器分离,而不删除在数据存储库中的信息。
使实例处于保持状态删除保持的实例使实例处于临时状态
makePersistent(Objecto)deletePersistent(Objecto)makeTransient(Objecto)
makePersistentAll(Object[]os)deletePersistentAll(Object[]os)makeTransientAll(Object[]os)
makePersistentAll(Collectionos)deletePersistentAll(Collectionos)makeTransientAll(Collectionos)
(这里是一个4X3的表格,可以参阅原稿中的英文表格)

第三步:显示数据库中人的信息
显示信息代码以获得可保持性管理器开始。我们使用上面代码中用persistPeople()方法保存的对象ID获得对象,调用对象的方法━━在本例中是gets,来得到我们输入的信息。我们可以发现,要保持我们的对象,并不需要编写大量的代码。
publicvoiddisplay(intend){
Personperson;
intmax=end<=SIZE?end:SIZE;

//获得一个新的可保持性管理器
pm=pmf.getPersistenceManager();
//从数据库中获取对象并进行显示
for(inti=0;i<max;i++){

person=(Person)pm.getObjectById(id.elementAt(i),
false);
System.out.println("Name:"+person.getName());
System.out.println("Address:"+
person.getAddress());
System.out.println("SSN:"+person.getSsn());
System.out.println("Email:"+person.getEmail());
System.out.println("HomePhone:"+
person.getHomePhone());
System.out.println("WorkPhone:"+
person.getWorkPhone());
}
pm.close();
}
第四步:改变其中一个人的名字
改变存储在数据库中的一个人的信息的代码也十分简单,它与显示数据库中人的信息的代码非常类似。在这里,我们需要创建一个事务(因为要修改其中的记录),使用定义的setName()方法修改一个人的名字,最终提交该事务,保存所作的修改。这种操作与处理临时对象之间真正的差别是,我们考虑是事务。
publicvoidchange(){
Personperson;

//从数据存储库中获取对象
pm=pmf.getPersistenceManager();
transaction=pm.currentTransaction();
//修改第二个保持记录的DataString字段
person=(Person)pm.getObjectById(id.elementAt(1),
false);
person.setName("SteveGerrard");
//提交事务并关闭可保持性管理器
transaction.commit();
pm.close();
}
第五步:删除一个人的资料
你自己能够想象出从数据库中删除第二个人资料的代码吗?因为我们已经了解了所有编写这一代码所需要的知识。仔细地研究一下下面的代码就会发现,我们使用了第二步中的可保持性管理器方法中提到的deletePersistent()方法。
publicvoiddelete(){
//从数据库中获取对象
pm=pmf.getPersistenceManager();
transaction=pm.currentTransaction();
//从数据库中删除第二个人的信息,并从ID向量中删除其ID
pm.deletePersistent(pm.getObjectById(id.remove(1),
false));
//提交事务并关闭可保持性管理器
transaction.commit();
pm.close();
}
第六步:在main()方法中运行上面的代码
最后,整个代码需要有一个main()串起来,在数据库中输入人的信息、改变其中一个人的名字,然后删除该人的资料。如果运行这一程序,就会看到程序运行到每一步时的地址簿。
publicstaticvoidmain(String[]args){
System.out.println("CreatePersonPersist");
PersonPersistpersonPersist=newPersonPersist();

System.out.println("Setupandpersistagroupofpeople");
personPersist.persistPeople();

System.out.println("Displaythepersistedpeople");
personPersist.display(SIZE);

System.out.println("Changeaname");
personPersist.change();
personPersist.display(SIZE);

System.out.println("Deleteaperson");
personPersist.delete();
personPersist.display(SIZE-1);
}
JDOEnhancer:创建JDOEnhancer的JDO描述符

现在,我们已经编写好了整个应用程序的源代码,下一步需要作的就是创建一个JDOEnhancer将要使用的
JDO描述符。读者一定会问,JDOEnhancer是什么?JDO架构是基于下面的理念的:一个JDO实现能够获取类的字节码,对它们进行处理,添加一些必要的功能。例如,JDOEnhancer将使类实现PersistanceCapable接口(因此我们不用自己编程实现这一接口),而且能够实现该接口中的一些方法。因此在对代码编译后我们就会发现,我们必须运行JDOEnhancer对字节码进行适当的处理。我们需要创建一个给出我们需要保持的类的信息的描述符文件,这一文件如下所示:

<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEjdoSYSTEM
"file:/D:/Apps/OpenFusionJDO/xml/schema/jdo.dtd">
<jdo>
<packagename="addressbook">
<classname="Person"identity-type="datastore">
</class>
</package>
</jdo>
这只是一个最基本的文件,但能够满足我们的要求。当然了,还有许多更复杂的映射。下面是OpenFusion例子中一个稍微复杂一些的映射:
<classname="Department"identity-type="datastore">
<fieldname="name"/>
<fieldname="employees">
<collectionelement-
type="com.prismt.j2ee.jdo.examples.appKeyDepartment.Employee">
</collection>
</field>
<fieldname="manager"/>
</class>
</package>
</jdo>
现在我们已经编写好了代码和JDO描述符文件,我们将对它们进行整合,并讨论如何建立整个系统。要建立整个系统,我们只需要简单的几步工作即可:
1、编译代码。
2、运行JDOEnhancer。
3、使用JDOEnhancer的输出建立数据库。
4、运行应用程序。
第一步:编译代码
我想广大的读者想必已经知道如何运行javac了吧。在运行javac之前,我们只要保证正确地设置CLASSPATH就可以了。下面是一个在Windows平台上运行javac的例子:
%setOPENFUSION_DIR=D:/Apps/OpenFusionJDO
%set
CLASSPATH=%OPENFUSION_DIR%/lib/connector.jar;%OPENFUSION_DIR%/
lib/jndi.jar;%OPENFUSION_DIR%/lib/log4j.jar;%OPENFUSION_DIR%/l
ib/xerces.jar;%OPENFUSION_DIR%/lib/classes12.zip;%OPENFUSION_D
IR%/lib/jdo.jar;%OPENFUSION_DIR%/lib/jta-
spec1_0_1.jar;%OPENFUSION_DIR%/lib/ofjdo.jar;.

%javac?d.Person*.java
第二步:运行JDOEnhancer
JDOEnhancer需要使用在上一步编译中得到的字节码和我们先前建立的JDO描述符文件。下面是OpenFusionJDOEnhancer的完整语法:
javacom.prismt.j2ee.jdo.enhancer.JDOEnhancer

命令选项:
-cp开始搜索需要强化的类的基本路径,与CLASSPATH不同,它是编译后的可保持类所在的目录
-oc存储强化后的类的目录
-pdJDO描述符文件

可选项:
-db指定目标数据库[oracle、sybase等]
-od生成SQL脚本的目录

下面是为建立我们的应用程序而运行JDOEnhancer的一个例子:
%javacom.prismt.j2ee.jdo.enhancer.JDOEnhancer-oc.-pd
person.jdo-dboracle-oddb-cp.
第三步:使用JDOEnhancer的输出建立数据库
,只要使用?db和-od可选项,JDOEnhancer就能够创建建立数据库的数据库脚本。它能够创建许多脚本,但其中有一个的名字叫load_all.sql,打开该文件并将它加载到一个SQL提示符中。(例如sqlplusforOracle)

CREATESEQUENCEinstid_seqINCREMENTBY1
;

CREATETABLEJDO_addressbook_Person_SCO
(
inst_idINTEGERNOTNULL,
classINTEGERNOTNULL,
JDO_addressVARCHAR2(255),
JDO_emailVARCHAR2(255),
JDO_homePhoneVARCHAR2(255),
JDO_nameVARCHAR2(255),
JDO_ssnVARCHAR2(255),
JDO_workPhoneVARCHAR2(255)
)
;
CREATETABLEJDO_addressbook_Person
(
inst_idINTEGERNOTNULL,
classINTEGERNOTNULL,
JDO_addressVARCHAR2(255),
JDO_emailVARCHAR2(255),
JDO_homePhoneVARCHAR2(255),
JDO_nameVARCHAR2(255),
JDO_ssnVARCHAR2(255),
JDO_workPhoneVARCHAR2(255)
)
;
CREATETABLEprismjdoProp
(
nameVARCHAR2(255)PRIMARYKEY,
valueVARCHAR2(255)
)
;
CREATETABLEprismjdoExtents
(
class_idNUMBER(38,0)PRIMARYKEY,
class_nameVARCHAR2(255)UNIQUE,
app_keyVARCHAR2(255)
)
;
ALTERTABLEJDO_addressbook_Person_SCOADDPRIMARYKEY
(inst_id,class)
;
ALTERTABLEJDO_addressbook_PersonADDPRIMARYKEY(inst_id,
class)
;

INSERTINTOprismjdoExtentsVALUES(0,'addressbook.Person',
'com.prismt.j2ee.jdo.spi.DBKey')
;
COMMITWORK
;

INSERTINTOprismjdoPropVALUES('USE.RDBMS.TRIGGERS','true')
;
COMMITWORK
;
第四步:运行应用程序
现在已经建立了数据库,我们就可以运行应用程序了。怎么样,分享一下自己的劳动成果吧!
%javaaddressbook.PersonPersist
结束语
我们已经讨论了如何使用OpenFusionJDO实现来处理JDO标准。这是一个全新的领域,开发人员可以集中精力处理业务需求和对象,而无需对SQL十分精通。



分享到:
评论

相关推荐

    jdo-java数据对象

    Java数据对象(Java Data Objects,JDO)是一个应用程序接口(API),它是Java程序员能够间接地访问数据库,也就是说,不需使用直接的结构化查询语言(SQL)语句。JDO是作为Java数据库连接(JDBC)的一个补充来介绍的,而...

    Java数据对象(JDO)的应用.rar_JDO

    详细地讨论Sun公司的Java数据对象(JDO)标准。JDO允许我们使用Java对象,支持事务和多用户。与ODBC不同的是,它使我们无需考虑SQL和与数据库有关的其他东西。它与串行化也有所区别,因为它支持多个用户和事务。JDO...

    全面了解JDO数据库编程 多文档打包

    JDO提供了透明的对象存储,因此对开发人员来说,存储数据对象完全不需要额外的代码(如JDBC API的使用)。这些繁琐的例行工作已经转移到JDO产品提供商身上,使开发人员解脱出来,从而集中时间和精力在业务逻辑上。...

    Java数据编程指南

    J2EE通信 通信概述 JMS的详细情况 消息驱动EJB 小结 第24章 Java数据对象(JDO) 概述 JDO对象模型 JDO API JDO实例的生命周期 JDO和EJB 开发可持久类 范例应用程序 配置FFJ...

    Java数据对象(JDO)的前世今生

    1Java与数据库应用,JDBCJava发明以来,在短短的几年之间,迅速占领了从桌面应用(J2SE)到服务器(J2EE),再到小型设备嵌入式系统(J2ME)的应用开发市场,其语言吸取了SmallTalk的一切皆对象的理念,摆脱了C++的...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

    第1章 Java应用分层架构及软件模型  1.1 应用程序的分层体系结构  1.1.1 区分物理层和逻辑层  1.1.2 软件层的特征  1.1.3 软件分层的优点  1.1.4 软件分层的缺点  1.1.5 Java应用的持久化层  1.2 软件的模型 ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part4

    第1章 Java应用分层架构及软件模型  1.1 应用程序的分层体系结构  1.1.1 区分物理层和逻辑层  1.1.2 软件层的特征  1.1.3 软件分层的优点  1.1.4 软件分层的缺点  1.1.5 Java应用的持久化层  1.2 软件的模型 ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part3

    第1章 Java应用分层架构及软件模型  1.1 应用程序的分层体系结构  1.1.1 区分物理层和逻辑层  1.1.2 软件层的特征  1.1.3 软件分层的优点  1.1.4 软件分层的缺点  1.1.5 Java应用的持久化层  1.2 软件的模型 ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part1.rar

    第1章 Java应用分层架构及软件模型  1.1 应用程序的分层体系结构  1.1.1 区分物理层和逻辑层  1.1.2 软件层的特征  1.1.3 软件分层的优点  1.1.4 软件分层的缺点  1.1.5 Java应用的持久化层  1.2 软件的模型 ...

    超级有影响力霸气的Java面试题大全文档

     GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收...

    Java数据库编程宝典3

    1.5.1 Java数据对象 1.5.2 两层模型 1.5.3 三层模型 1.6 小结 第2章 设计数据库 2.1 数据库设计应考虑的事项 2.1.1 项目规范 2.1.2 设计表 2.1.3 生成发票 2.2 引用完整性 2.2.1 通用完整性规则 2.2.2...

    maven-gwt-appengine-jdo-seed-project:开始使用 GWT、Google App Engine、JDO 和 Java 的种子应用程序,只使用 Maven

    #Plaid-Suit:面向 Google-Stack 开发人员的常规种子项目; 不需要任何 IDE 配置 ##About 是一个功能齐全的 CRUD 应用程序。 这是一种利用 Java 的强大功能开始构建跨浏览器工作的 HTML 应用程序的方法...Java 数据对象

    精通Hibernate:对象持久化技术第二版part3

    本章通过简单的helloapp应用例子,演示如何利用Hibernate来持久化Java对象。 3.1 创建Hibernate的配置文件 47 3.2 创建持久化类 48 3.3 创建数据库Schema 51 3.4 创建对象-关系映射文件 52 3.4.1 映射文件的...

    精通hibernate:对象持久化技术孙卫琴第二版part2

    本章通过简单的helloapp应用例子,演示如何利用Hibernate来持久化Java对象。 3.1 创建Hibernate的配置文件 47 3.2 创建持久化类 48 3.3 创建数据库Schema 51 3.4 创建对象-关系映射文件 52 3.4.1 映射文件的...

    java 面试题 总结

     GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收...

    Java数据库编程宝典2

    1.5.1 Java数据对象 1.5.2 两层模型 1.5.3 三层模型 1.6 小结 第2章 设计数据库 2.1 数据库设计应考虑的事项 2.1.1 项目规范 2.1.2 设计表 2.1.3 生成发票 2.2 引用完整性 2.2.1 通用完整性规则 2.2.2...

    Web开发+java+ssh框架

    这一空白,它为Java应用提供了一个易用的、高效率的对象关系映射框架。hibernate是个轻量级的持久性框架,功能却非常丰富。 优点: a.Hibernate 使用 Java 反射机制而不是字节码增强程序来实现透明性。 b....

    Java数据库编程宝典4

    1.5.1 Java数据对象 1.5.2 两层模型 1.5.3 三层模型 1.6 小结 第2章 设计数据库 2.1 数据库设计应考虑的事项 2.1.1 项目规范 2.1.2 设计表 2.1.3 生成发票 2.2 引用完整性 2.2.1 通用完整性规则 2.2.2...

Global site tag (gtag.js) - Google Analytics