Java 数据对象(JDO)介绍
介绍
Java 数据对象 (JDO) is 是一个存储Java对象的规范.  它已经被JCP组织定义成JSR12规范。JDO的第一个版本在2000年6月6日提交并在2002年4月30日正式发布1.0版本规范。规范的两个主要目的是提供数据处理和访问机制的API以及允许规范的实现作为应用服务器的一部分。
JDO 和 JDBC
JDBC和JDO都是Java调用数据库的APIs。区别在于,他们访问数据存储的具体方法不同。JDBC提供了一种非常好的机制,它可以使应用程序代码与具体的数据库厂商和数据库位置无关。在大多数情况下数据存储使用的是关系数据库。但是当使用JDBC驱动运行在一个非关系数据库时就不是很好了。而对于JDO来说,运行在它之下的数据库就可以是一个关系数据库,面向对象的数据库或者其他完全不同的数据库。在JDO运行于关系数据库之上时,它可以通过JDBC很好的完成数据存储。而这一切对于开发人员来说都是透明的,所有实现都有JDO本身来完成。
JDBC不支持面向对象的数据库表示。JDBC数据库表示完全围绕关系数据库模型。这常常导致书写代码时在应用程序和数据库之间存在一个中间层。这个层的作用也许是分解Java对象。分解Java对象的过程会对
使用的对象稍作改变,这样对象才能存储到关系数据库之中。同样的必须存在一种机制来把数据库中的记录转换成适当的Java对象。JDO与JDBC刚好相反,他的数据库标示完全面向对象。这种机制并不新奇,在一些面向对象数据库中已经使用了这种机制。
JDBC的查询语言一般都是用SQL。JDO的查询语言看起来与Java更接近。使用JDO无需再专门学习一种查询语言比如SQL。如果你会用Java那么你就能够使用JDO的查询语言。
执行
JDO规范定义了JDO实现的接口已经JDO实现的内容。SUN提供了一个JDO规范的参考实现,但是在2002年5月份发布的版本中它并没有完全实现规范中所要求的内容。还有众多的厂商提供的JDO实现可以使用。在下面的表格中列出了一部分。
厂商
产品
SolarMetric
Kodo JDO
PrismTech
OpenFusion Java Data Objects
Signsoft
intelliBO
Poet
FastObjects
API
javax.jdo.spi.PersistenceCapable
任何被JDO实现控制的类都必须扩展PersistenceCapable接口。任何扩展PersistenceCapable接口的类的实例都可以看作是一个“JDO实例”。这个接口定义了JDO实现使用的方法来控制类的实例。    public abstract javax.jdo.PersistenceManager jdoGetPersistenceManager();
public abstract void jdoReplaceStateManager(javax.jdo.spi.StateManager)
throws SecurityException;
public abstract void jdoProvideField(int);
public abstract void jdoProvideFields(int[]);
public abstract void jdoReplaceField(int);
pub
lic abstract void jdoReplaceFields(int[]);
public abstract void jdoReplaceFlags();
public abstract void jdoCopyFields(Object, int[]);
public abstract void jdoMakeDirty(String);
public abstract Object jdoGetObjectId();
public abstract Object jdoGetTransactionalObjectId();
public abstract boolean jdoIsDirty();
public abstract boolean jdoIsTransactional();
public abstract boolean jdoIsPersistent();
public abstract boolean jdoIsNew();
public abstract boolean jdoIsDeleted();
public abstract javax.jdo.spi.PersistenceCapable
jdoNewInstance(javax.jdo.spi.StateManager);
public abstract javax.jdo.spi.PersistenceCapable
jdoNewInstance(javax.jdo.spi.StateManager, Object);
public abstract Object jdoNewObjectIdInstance();
public abstract Object jdoNewObjectIdInstance(String);
public abstract void jdoCopyKeyFieldsToObjectId(Object);
public abstract void jdoCopyKeyFieldsToObjectId(
javax.jdo.spi.PersistenceCapable.ObjectIdFieldSupplier, Object);
public abstract void jdoCopyKeyFieldsFromObjectId(
javax.jdo.spi.PersistenceCapable.ObjectIdFieldConsumer, Object);
通常会有一个由JDO实现厂商提供的工具来完成普通的Java类到“JDO实例”类的转化。这个工具可能通过不同的方法来实现。第一种方法是通过字节码增强器来实现。一个JDO字节码增强器把普通的Java类转换成“JDO实例”类的过程就是把扩展PersistenceCapable接口的方法的代码加到类中。第二种方法是使用一个代码生成器,它解析现有的普通Java代码然后输出一个扩展了PersistenceCapable接口的新版本的代码。如果通过手工方式来扩展这个接口是没有好处的。
javax.jdo.PersistenceManagerFactory
PersistenceManagerFactory接口 被用来获得一个PersistenceManager 实例。这个接口中定义两个工厂方法(有关工厂方法的内容可以参考Java设计模式)。    public PersistenceManager getPersistenceManager()
public PersistenceManager getPersistenceManager(String userid,
String password)
Because PersistenceManagerFactory is an interface, some vendor specific class, which implements this interface, must be used as a bootstrap mechanism. This should turn out to be the only vendor specific code that a JDO application uses. Because of this, the JDO specification suggests that an application level factory class be implemented which returns the appropriate instance of the PersistenceManagerFactory so that implementations may be swapped out with minimal impact on application code. Only the application's factory would need to be modified in this case.
因为PersistenceManagerFactory 是一个接口,一些实现该接口的厂商特定的类必须通过一种“自举”机制来使用。   
// SolarMetric's 实现PersistenceManagerFactory 接口的例子...
PersistenceManagerFactory man
agerFactory =
new com.solarmetric.kodo.impl.jdbc.JDBCPersistenceManagerFactory();
// 获得一个控制器
PersistenceManager manager = PersistenceManager();
javax.jdo.PersistenceManager
The PersistenceManager interface is the primary point of contact between a Java application and the JDO implementation. Application code uses a PersistenceManager to retrieve Java objects from the data store and to add Java objects to the data store. The PersistenceManager interface also serves as a factory for several other JDO components discussed below.
PersistenceManager 接口是连接Java应用程序和JDO实现的要点。应用程序使用PersistenceManager 从数据存储中获得对象或者把一个Java对象放到数据存储中。PersistenceManager 接口也为下面将要讨论的几个JDO组件提供服务。
PersistenceManager 接口中定义了几个方法来把JDO实例对象添加到数据存储中。   
public abstract void makePersistent(Object);
public abstract void makePersistentAll(Object[]);
public abstract void makePersistentAll(java.util.Collection);
通过下面几个方法实现把JDO实例对象添加到数据存储中的过程:   
// 获得一个
PersistenceManager manager = PersistenceManager();
// 下面的 Employee 必须扩展了
Employee newEmployee = new Employee(...);
manager.makePersistent(newEmployee);
javax.jdo.Extent
Extent (范围)对象表示所有的在当前数据库中实际的类对象。在PersistenceManager 中的一个工厂方法负责获得一个Extent (范围)对象。    public Extent getExtent(Class persistenceCapableClass, boolean subclasses)
Class参数标明了接收的对象类型。boolean 参数标明是否包含第一个参数指定的类的子类。
Extent 接口定义了一个iterator()方法,它返回一个 java.util.Iterator来遍历所有由Extent 描述的实例。   
//获得一个
PersistenceManager manager = PersistenceManager();
// the Employee class must
Extent employeesExtent = Extent(Employee.class, false);
java.util.Iterator iterator = employeesExtent.iterator();
javax.jdo.Query
Query 接口允许从数据存储中获得符合某些条件的实例。Query 实例可以重载自PersistenceManager 接口中的newQuery()方法获得。
Query 接口定义了几个不同版本的重载execute() 的方法,这些方法将执行查询(Query) 并返回匹配的结果。   
// 获得一个
PersistenceManager manager = PersistenceManager();
// Employee 类必须实现 PersistenceCapable接口...
Extent employeesExtent = Extent(Employee.class, false);
// 一个Query 获得所有在公司工作五年以上的
Query
query = wQuery(Employee.class, employeesExtent,
"yearsOfEmployement > 5");
// 执行查询
Collection employees = (Collection) ute();
// 处理结果...
Iterator iterator = employees.iterator();
while (iterator.hasNext()) {
Employee employee = (Employee) ();
(...)
}
注意newQuery()方法的第三个参数"yearsOfEmployement > 5"。它标明了返回结果的条件。上面的实现要求Employee 类中必须有一个属性字段叫yearsOfEmployment 。
试例简介
下面的例子示范了JDO的基础应用。代码示范了如何向数据库添加数据和取回数据。所有的代码使用的都是
SolarMetric's Kodo JDO
实现。包括创建数据库的机制,使域对象类扩展PersistenceCapable接口的增强和厂商特定的PersistenceManagerFactory实现使用的都是Kodo JDO实现。其他的部分使用的是标准的JDO实现。
域对象
The samples will work with a small set of classes, which represent a Fleet of Vehicle objects. The two specific types of Vehicles defined are Bicycle and MotorVehicle. MotorVehicle objects have an Engine attribute.
例子是用了一个很小的类,这个类描述了一个Vehicle(交通工具) 对象的Fleet(车队)。Vehicle 定义了两个特定的对象Bicycle 和MotorVehicle 。MotorVehicle对象有一个Engine 属性。
域对象源代码   
/**
* Fleet.java
*/
iweb.jdodemo;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
public class Fleet {
private List vehicles = new Vector();
public void addVehicle(Vehicle vehicle) {
vehicles.add(vehicle);
}
public Iterator getVehicles() {
return vehicles.iterator();
}
public String toString() {
StringBuffer buffer = new StringBuffer("Fleet:\n");
Iterator iter = getVehicles();
while (iter.hasNext()) {
buffer.append("\t" + () + "\n");
}
String();
}
}
/**
* Vehicle.java
*/
iweb.jdodemo;
public class Vehicle {
private int numberOfWheels;
public Vehicle(int numberOfWheels) {
this.numberOfWheels = numberOfWheels;
}
public int getNumberOfWheels() {
return numberOfWheels;
}
}
/**
* Bicycle.java
*/
iweb.jdodemo;
public class Bicycle extends Vehicle {
private String model;
public Bicycle(String model) {
super(2);
}
public String toString() {
return "Bike: Model " + model;
}
}
/**
* MotorVehicle.java
*/
iweb.jdodemo;
public class MotorVehicle extends Vehicle {
private Engine engine;
public MotorVehicle(int numberOfWheels, Engine engine) {
super(numberOfWheels);
}
public String toString() {
return "MotorVehicle With " + getNumberOfWheels()
+ " Wheels.  " + engine;
}
}
/**
* Engine.java
*/
iweb.jdodemo;
public class Engine {
private int numberOfCylinders;
public Engine(int numberOfCylinders) {
this.numberOfCylinders = numberOfCylinders;
}
public int getNumberOfCylinders() {
return numberOfCylinders;
}
public String toString() {
return numberOfCylinders + " Cylinder Engine.";
}    } 
Kodo JDO 规范
Kodo JDO包含自己的类来创建数据库模型和增强类。
模型生成工具被用于揣安数据库模型,这个模型将被用于存储JDO对象实例。工具正式支持的数据库包括:
DB2
InstantDB
java库SQLServer
MySQL
Oracle
PostgreSQL
其他数据库的JDBC驱动可以通过扩展代码被加入。详细内容参考Kodo JDO的文档。
模型创建工具要依赖于一个package.jdo文件,这个文件被用于定义JDO实例类的一些细节。下面的文件被用于这个例子。可以查看Kodo JDO的文档来获得文件格式和概念的详细信息。
schematool.bat文件被用来运行模型创建工具。.jdo文件必须作为一个参数放到命令行中。    schematool.bat package.jdo
一旦模型被创建,域对象的类文件必须被增强以实现PersistenceCapable 接口。jdoc.bat文件被用于运行类增强器。jdoc.bat批处理文件也需要package.jdo文件作为参数方到命令行中。    jdoc.bat package.jdo
上面演示的模型创建和类增强是Kodo JDO实现特有的,它并不是JDO规范的一部分。其他的厂商也许有他们自己的方法来完成以上部分,具体实现要参考厂商的文档。
向数据库增加数据
由于数据库已经配置完成并且我们的域对象也已经设计好了,代码也通过增强实现了PersistenceCapable接口,现在那些类的可以被实例化并添加到数据库中了。
下面的类将实例化一个Fleet,给他添加几条数据然后把它存储到数据库中。   
/**
* SeedDatabase.java
*/
iweb.jdodemo;
// 厂商实现的PersistenceManagerFactory
import com.solarmetric.kodo.impl.jdbc.JDBCPersistenceManagerFactory;
import javax.jdo.PersistenceManager;
import javax.jdo.Transaction;
public class SeedDatabase {
public static void main(String[] args) {

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。