分享
 
 
 

SUN的JDO标准

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

JDO允许我们使用Java对象,支持事务和多用户。与ODBC不同的是,它使我们无需考虑SQL和与数据库有关的其他东西。它与串行化也有所区别,因为它支持多个用户和事务。JDO允许Java开发人员将他们的数据模型用作数据模型,无需在“数据端”、“对象端”之间的转移方面花费大量的时间。

包括CocoBase、WebGain TOPLink和Castor JDO在内的多种产品都可以实现了JDO标准。既然有一种标准的方法,我们就可以只学习其中的一种,就象有了ODBC,我们就可以使用任何提供了驱动程序的数据库那样。

在本篇文章中,我们将使用Prism技术公司的OpenFusion JDO。读者在后面会发现,只有很小一部分代码使用了PrismTech API,其他部分都使用了标准的JDO标准。

创建Person对象

我们将首先创建一个Person对象,该对象遵循了JavaBean的惯例,可以对其属性执行get和set操作。需要注意的是,尽管我们是在创建这个类,但它并没有什么特别的,它没有继承或实现任何基本类。对一个可保持类的要求是:

1、所有域必须能够被JDO类访问(public或set*方法)

2、域的数据类型必须符合JDO规格。

3、不能支持一些类型的字段(例如Thread、File、Socket等不能串行化的字段)。

下面是符合上述要求的Person.java:

public class Person {

private String name;

private String address;

private String ssn;

private String email;

private String homePhone;

private String workPhone;

// 允许我们使用构造器创建Person对象

public Person(String name, String address, String ssn,

String email, String homePhone, String workPhone) {

this.name = name;

this.address = address;

this.ssn = ssn;

this.email = email;

this.homePhone = homePhone;

this.workPhone = workPhone;

}

// 方法

public String getName() { return name; }

public String getAddress() { return address; }

public String getSsn() { return ssn; }

public String getEmail() { return email; }

public String getHomePhone() { return homePhone; }

public String getWorkPhone() { return workPhone; }

public void setName(String name) { this.name = name; }

public void setAddress(String address) {

this.address = address;

}

public void setSsn(String ssn) { this.ssn = ssn; }

public void setEmail(String email) { this.email = email; }

public void setHomePhone(String homePhone) {

this.homePhone = homePhone;

}

public void setWorkPhone(String workPhone) {

this.workPhone = workPhone;

}

}

创建PersonPersist对象管理可保持性

现在已经有了Person对象,我们需要创建一些代码来管理这种可保持性。下面我们将详细讨论这些代码,并学习如何:

1、初始化JDO可保持性管理器。

2、向数据库中输入三个人的资料。

3、从数据库中显示人的资料。

4、修改其中一个人的名字。

5、从数据库中删除一个人的资料。

6、在main()方法中进行相关的处理。

第一步:初始化JDO可保持性管理器

我们从OpenFusion实现中导入了标准的JDO类和ManagedConnectionFactory,当然了我们也可以将它们抽象成一个独立的类。构造器使用javax.jdo.PersistenceManagerFactoryClass属性设置连接代理,这一点与在JDBC中设置数据库驱动程序的属性很相似。

package addressbook;

import java.util.*;

import javax.jdo.*;

import

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

public class PersonPersist

{

private final static int SIZE = 3;

private PersistenceManagerFactory pmf = null;

private PersistenceManager pm = null;

private Transaction transaction = null;

// 需要保持的人的数组

private Person[] people;

// 现有对象标识符的向量

private Vector id = new Vector(SIZE);

public PersonPersist() {

try {

Properties props = new Properties();

props.setProperty("javax.jdo.PersistenceManagerFactoryClass",

"com.prismt.j2ee.jdo.PersistenceManagerFactoryImpl");

pmf = JDOHelper.getPersistenceManagerFactory(props);

pmf.setConnectionFactory( createConnectionFactory() );

} catch(Exception ex) {

ex.printStackTrace();

System.exit(1);

}

}

连接代理是在名字为createConnectionFactory()的静态方法中创建的,该代理需要JDBC URL、JDBC驱动程序、用户名和口令。

public static Object createConnectionFactory() {

ManagedConnectionFactoryImpl mcfi = new

ManagedConnectionFactoryImpl();

Object connectionFactory = 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(Exception e) {

e.printStackTrace();

System.exit(1);

}

return connectionFactory;

}

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

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

public void persistPeople() {

// 创建人的资料的数组

people = new Person[SIZE];

// 创建3个人的资料

people[0] = new Person("Gary Segal", "123 Foobar Lane",

"123-123-1234", "gary@segal.com",

"(608) 294-0192", "(608) 029-4059");

people[1] = new Person("Michael Owen",

"222 Bazza Lane, Liverpool, MN",

"111-222-3333", "michael@owen.com",

"(720) 111-2222", "(303) 222-3333");

people[2] = new Person("Roy Keane",

"222 Trafford Ave, 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(int i = 0; i < people.length; i++) {

id.add(pm.getObjectId(people[i]));

}

// 关闭现有的保持性管理器,保证对象是从数据库而不是从保持性管理器的缓存中读取的

pm.close();

}

下面是一些可以针对保持性管理器的其他方法:

使实例成为可保持的:获得一个临时对象,并保持它。

删除可保持实例:从数据存储库中删除信息。

使实例临时化:使实例与可保持性管理器分离,而不删除在数据存储库中的信息。

使实例处于保持状态 删除保持的实例 使实例处于临时状态

makePersistent(Object o) deletePersistent(Object o) makeTransient(Object o)

makePersistentAll(Object[] os) deletePersistentAll(Object[] os) makeTransientAll(Object[] os)

makePersistentAll(Collection os) deletePersistentAll(Collection os) makeTransientAll(Collection os)

(这里是一个4X3的表格,可以参阅原稿中的英文表格)

第三步:显示数据库中人的信息

显示信息代码以获得可保持性管理器开始。我们使用上面代码中用persistPeople()方法保存的对象ID获得对象,调用对象的方法━━在本例中是gets,来得到我们输入的信息。我们可以发现,要保持我们的对象,并不需要编写大量的代码。

public void display(int end) {

Person person;

int max = end < = SIZE ? end : SIZE;

// 获得一个新的可保持性管理器

pm = pmf.getPersistenceManager();

// 从数据库中获取对象并进行显示

for(int i = 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("Home Phone: " +

person.getHomePhone());

System.out.println("Work Phone: " + person.getWorkPhone());

}

pm.close();

}

第四步:改变其中一个人的名字

改变存储在数据库中的一个人的信息的代码也十分简单,它与显示数据库中人的信息的代码非常类似。在这里,我们需要创建一个事务(因为要修改其中的记录),使用定义的setName()方法修改一个人的名字,最终提交该事务,保存所作的修改。这种操作与处理临时对象之间真正的差别是,我们考虑是事务。

public void change() {

Person person;

// 从数据存储库中获取对象

pm = pmf.getPersistenceManager();

transaction = pm.currentTransaction();

// 修改第二个保持记录的DataString字段

person = (Person) pm.getObjectById(id.elementAt(1), false);

person.setName("Steve Gerrard");

// 提交事务并关闭可保持性管理器

transaction.commit();

pm.close();

}

第五步:删除一个人的资料

你自己能够想象出从数据库中删除第二个人资料的代码吗?因为我们已经了解了所有编写这一代码所需要的知识。仔细地研究一下下面的代码就会发现,我们使用了第二步中的可保持性管理器方法中提到的deletePersistent()方法。

public void delete() {

// 从数据库中获取对象

pm = pmf.getPersistenceManager();

transaction = pm.currentTransaction();

// 从数据库中删除第二个人的信息,并从ID向量中删除其ID

pm.deletePersistent(pm.getObjectById(id.remove(1), false));

// 提交事务并关闭可保持性管理器

transaction.commit();

pm.close();

}

第六步:在main()方法中运行上面的代码

最后,整个代码需要有一个main()串起来,在数据库中输入人的信息、改变其中一个人的名字,然后删除该人的资料。如果运行这一程序,就会看到程序运行到每一步时的地址簿。

public static void main(String[] args) {

System.out.println("Create PersonPersist");

PersonPersist personPersist = new PersonPersist();

System.out.println("Setup and persist a group of people"); personPersist.persistPeople();

System.out.println("Display the persisted people"); personPersist.display(SIZE);

System.out.println("Change a name ");

personPersist.change();

personPersist.display(SIZE);

System.out.println("Delete a person ");

personPersist.delete();

personPersist.display(SIZE - 1);

}

JDOEnhancer:创建JDOEnhancer的JDO描述符

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

< ?xml version="1.0" encoding="UTF-8"? >

< !DOCTYPE jdo SYSTEM

"file:/D:/Apps/OpenFusionJDO/xml/schema/jdo.dtd" >

< jdo >

< package name="addressbook" >

< class name="Person" identity-type="datastore" >

< /class >

< /package >

< /jdo >

这只是一个最基本的文件,但能够满足我们的要求。当然了,还有许多更复杂的映射。下面是OpenFusion例子中一个稍微复杂一些的映射:

< class name="Department" identity-type="datastore" >

< field name="name"/ >

< field name="employees" >

< collection element-

type="com.prismt.j2ee.jdo.examples.appKeyDepartment.Employee >

< /collection >

< /field >

< field name="manager"/ >

< /class >

< /package >

< /jdo >

现在我们已经编写好了代码和JDO描述符文件,我们将对它们进行整合,并讨论如何建立整个系统。要建立整个系统,我们只需要简单的几步工作即可:

1、编译代码。

2、运行JDOEnhancer。

3、使用JDOEnhancer的输出建立数据库。

4、运行应用程序。

第一步:编译代码

我想广大的读者想必已经知道如何运行javac了吧。在运行javac之前,我们只要保证正确地设置CLASSPATH就可以了。下面是一个在Windows平台上运行javac的例子:

% set OPENFUSION_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_DIR%\lib\jdo.jar;%OPENFUSION_DIR%\lib\jta- spec1_0_1.jar;%OPENFUSION_DIR%\lib\ofjdo.jar;. % javac –d . Person*.java

第二步:运行JDOEnhancer

JDOEnhancer需要使用在上一步编译中得到的字节码和我们先前建立的JDO描述符文件。下面是OpenFusion JDOEnhancer的完整语法:

java com.prismt.j2ee.jdo.enhancer.JDOEnhancer

命令选项:

-cp 开始搜索需要强化的类的基本路径,与CLASSPATH不同,它是编译后的可保持类所在的目录

-oc 存储强化后的类的目录

-pd JDO描述符文件

可选项:

-db 指定目标数据库 [oracle、sybase等]

-od 生成SQL脚本的目录

下面是为建立我们的应用程序而运行JDOEnhancer的一个例子:

% java com.prismt.j2ee.jdo.enhancer.JDOEnhancer -oc . -pd

person.jdo -db oracle -od db -cp .

第三步:使用JDOEnhancer的输出建立数据库

只要使用–db和-od可选项,JDOEnhancer就能够创建建立数据库的数据库脚本。它能够创建许多脚本,但其中有一个的名字叫load_all.sql,打开该文件并将它加载到一个SQL提示符中。(例如sqlplus for Oracle)

CREATE SEQUENCE instid_seq INCREMENT BY 1

;

CREATE TABLE JDO_addressbook_Person_SCO

(

inst_id INTEGER NOT NULL,

class INTEGER NOT NULL,

JDO_address VARCHAR2(255),

JDO_email VARCHAR2(255),

JDO_homePhone VARCHAR2(255),

JDO_name VARCHAR2(255),

JDO_ssn VARCHAR2(255),

JDO_workPhone VARCHAR2(255)

)

;

CREATE TABLE JDO_addressbook_Person

(

inst_id INTEGER NOT NULL,

class INTEGER NOT NULL,

JDO_address VARCHAR2(255),

JDO_email VARCHAR2(255),

JDO_homePhone VARCHAR2(255),

JDO_name VARCHAR2(255),

JDO_ssn VARCHAR2(255),

JDO_workPhone VARCHAR2(255)

)

;

CREATE TABLE prismjdoProp

(

name VARCHAR2(255) PRIMARY KEY,

value VARCHAR2(255)

)

;

CREATE TABLE prismjdoExtents

(

class_id NUMBER(38,0) PRIMARY KEY,

class_name VARCHAR2(255) UNIQUE,

app_key VARCHAR2(255)

)

;

ALTER TABLE JDO_addressbook_Person_SCO ADD PRIMARY KEY

(inst_id, class)

;

ALTER TABLE JDO_addressbook_Person ADD PRIMARY KEY (inst_id, class)

;

INSERT INTO prismjdoExtents VALUES(0, ’addressbook.Person’,

’com.prismt.j2ee.jdo.spi.DBKey’)

;

COMMIT WORK

;

INSERT INTO prismjdoProp VALUES(’USE.RDBMS.TRIGGERS’, ’true’)

;

COMMIT WORK

;

第四步:运行应用程序

现在已经建立了数据库,我们就可以运行应用程序了。怎么样,分享一下自己的劳动成果吧!

% java addressbook.PersonPersist

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有