选择显示字体大小

java数据对象技术jdo(1)

作为异军突起的新型语言,java定义了一个标准的运行环境,用户定义的类在其中得到执行。这些用户自定义类的实例代表了真实环境中的数据,包括储存在数据库、文件或某些大型事务处理系统中的数据,而小型系统通常也需要一种在本地负责控制数据存储的机制。 

由于数据访问技术在不同的数据源类型中是不一样的,因此对数据进行访问成了给程序开发人员的一种挑战,程序员需要对每一种类型的数据源使用特定的编程接口(api),即必须至少知道两种语言来基于这些数据源开发业务应用:java语言和由数据源所决定的数据访问语言。这种数据访问语言一般根据数据源的不同而不同,这使得学习使用某种数据源的开发成本相应提升。

java数据对象技术(jdo)发布之前,通常有三种方式用于存储java数据:串行化(即serialization,也称序列化)、jdbc和ejb中的cmp(容控存储)方式。串行化用于将某个对象的状态,以及它所指向的其它对象结构图全部写到一个输出流中(比如文件、网络等等),它保证了被写入的对象之间的关系,这样一来,在另一时刻,这个对象结构图可以完整地重新构造出来。但串行化不支持事务处理、查询或者向不同的用户共享数据。它只允许在最初串行化时的粒度(指访问对象的接口精细程度)基础上进行访问,并且当应用中需要处理多种或多次串行化时很难维护。串行化只适用于最简单的应用,或者在某些无法有效地支持数据库的嵌入式系统中。

jdbc要求你明确地处理数据字段,并且将它们映射到关系数据库的表中。开发人员被迫与两种区别非常大的数据模型、语言和数据访问手段打交道:java,以及sql中的关系数据模型。在开发中实现从关系数据模型到java对象模型的映射是如此的复杂,以致于多数开发人员从不为数据定义对象模型;他们只是简单地编写过程化的java代码来对底层的关系数据库中的数据表进行操纵。最终结果是:他们根本不能从面向对象的开发中得到任何好处。

ejb组件体系是被设计为支持分布式对象计算的。它也包括对容器管理持续性container managed persistence(参见术语表)的支持来实现持续性。主要由于它们的分布式特性,ejb应用比起jdo来复杂得多,对资源的消耗也大得多。不过,jdo被设计成具有一定的灵活性,这样一来,jdo产品都可以用来在底层实现ejb的存储处理,从而与ejb容器结合起来。如果你的应用需要对象存储,但不需要分布式的特性,你可以使用jdo来代替ejb组件。在ejb环境中最典型的jdo使用方案就是让ejb中的对话组件(session bean)直接访问jdo对象,避免使用实体组件(entity bean)。ejb组件必须运行在一个受控(managed,参见术语表)的应用服务环境。但jdo应用可以运行在受控环境中,也可以运行在不受控的独立环境中,这些使你可以灵活地选择最合适的应用运行环境。

如果你将精力集中在设计java对象模型上,然后用jdo来进行存储你的数据类的实例,你将大大提高生产力和开发效率。你只需要处理一种信息模型。而jdbc则要求你理解关系模型和sql语言(译者注:jdo并不是要取代jdbc,而是建立在jdbc基础上的一个抽象的中间层,提供更简单的数据存储接口)。即使是在使用ejb cmp(即容控存储,参见术语表)的时候,你也不得不学习与ejb体系相关的许多其它方面的内容,并且在建模方面还有一些jdo中不存在的局限性。

jdo规范了jdo运行环境和你的可存储对象类之间的约定。jdo被设计成支持多种数据源,包括一般情况下考虑不到的数据库之类的数据源。从现在开始,我们使用数据库(参见术语表)这一概念来表示任何你通过jdo来访问的底层数据源。

定义数据对象模型

我们将建立一个uml类图,显示一个公司的对象模型的相关类以及相互之间的关系。一个movie(电影)对象表示一部特定的电影。每个至少在一部电影中出演角色的演员由一个actor(演员)对象代表。而role(角色)类表示某个演员在某部电影中扮演的特定角色,因此role类也表示了电影和演员之间的一种关系,这种关系包含一个属性(电影中的角色名)。每部电影包含一到多个角色。每个演员可以在不同的电影中扮演不同的角色,甚至在同一部电影中扮演多个角色。

我们会将这些数据类以及操纵这些数据类实例的的程序放到com.mecdiamania.prototype包中。

需要存储的类



我们定义movie、actor和role这几个类为可持续的,表示它们的实例是可以被储存到数据库中的。首先我们看看每个类的完整的源代码。每个类中有一个package语句,因此可以很清楚地看到本例用到的每个类分别在哪个包中。

例1-1显示了movie类的源代码。jdo是定义在javax.jdo包中的,注意这个类并不一定要导入任何具体的jdo类。java中的引用和java.util包中的collection及相关子类(接口)被用来表示我们的类之间的关系,这是大多数java应用中的标准方式。

movie类中的属性使用java中的标准类型,如string、date、int等等。你可以将属性声明为private的,不需要对每一属性定义相应的get和set方法。movie类中还有一些用于访问这些私有属性的方法,尽管这些方法在程序中的其它部分会用到,但它们并不是jdo所要求的。你可以使用属性包装来提供仅仅是抽象建模所需要的方法。这个类还有一些静态属性(static的),这些属性并不存储到数据库。 

"genres"属性是一个string型的,内容是该电影所属的电影风格(动作、爱情、诡异等等)。一个set接口用来表示该电影的演员表中的角色集合。"addrole()"方法将元素加入到演员表中,而"getcast()"方法返回一个不可以更改的集合,该集合中包含演员表。这些方法并不是jdo规定的,只是为了方便应用编程而编写的。"parsereleasedate()"方法和"formatreleasedate()"方法用于将电影的发行日期标准化(格式化)。为了保持代码的简单,如果parsereleasedate()的参数格式不对,将会返回null。

 例1-1 movie.java

package com.mediamania.prototype;

import java.util.set;

import java.util.hashset;

import java.util.collections;

import java.util.date;

import java.util.calendar;

import java.text.simpledateformat;

import java.text.parseposition;

public class movie {

private static simpledateformat yearfmt = new simpledateformat("yyyy");

public static final string[] mpaaratings = {

"g", "pg", "pg-13", "r", "nc-17", "nr"};

private string title;

private date releasedate;

private int runningtime;

private string rating;

private string website;

private string genres;

private set cast; // element type: role

private movie() {}

public movie(string title, date release, int duration, string rating,

string genres) {

this.title = title;

releasedate = release;

runningtime = duration;

this.rating = rating;

this.genres = genres;

cast = new hashset();

}

public string gettitle() {

return title;

}

public date getreleasedate() {

return releasedate;

}

public string getrating() {

return rating;

}

public int getrunningtime() {

return runningtime;

}

public void setwebsite(string site) {

website = site;

}

public string getwebsite() {

return website;

}

public string getgenres() {

return genres;

}

public void addrole(role role) {

cast.add(role);

}

public set getcast() {

return collections.unmodifiableset(cast);

}

public static date parsereleasedate(string val) {

date date = null;

try {

date = yearfmt.parse(val);

} catch (java.text.parseexception exc) {}

return date;

}

public string formatreleasedate() {

return yearfmt.format(releasedate);

}

}

jdo对一个需要存储的类强加了一个要求:一个无参数的构造器。如果你在类代码中不定义任何构造器,编译器会自动产生一个无参数的构造器;而如果你定义了带参构造器,你就必须再定义一个无参构造器,可以将其声明为private以禁止外部访问。如果你不定义这个无参构造器,一些jdo产品会自动为你产生一个,但这只是具体的jdo产品提供的功能,是不可移植的。


 


关键字 本文所属关键字

相关 与本文相关文章

分类 所有文章关键字导航

源码编程相关

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