站内搜索: 请输入搜索关键词

当前页面: 开发资料首页Java 专题CASTOR JDO 指南

CASTOR JDO 指南

摘要: CASTOR JDO 指南

CASTOR JDO 指南 现在,越来越多的企业级开发项目中需要一种在众多关系数据库上进行对象关系映射的技术。遗憾的是,个体组织内部的解决方案很难构建,而对其进行长期维护和扩展就更难了。虽然有了EJB技术,但是我发现在某些情况下使用EJB技术往往过于重量级了,这时候适合的解决方式应该是轻量级的为好。本文中,我将向您介绍了使用 Castor JDO 的基础知识, Castor JDO(Java 数据对象 (Java Data Objects))是一种开放源码的、百分之百 Java 关系对象映射框架,Castor同许多其它技术结合使用,已经将 Java 对象模型绑定到关系数据库、XML 文档以及 LDAP 目录上。
在本文中,您将了解使用 Castor JDO 的基本知识。我们将从配置 JDO开始;然后是关系数据模型和 Java 对象模型,接下来讨论在 二者之间进行映射的基础知识;最后我们将讨论 Castor JDO 的一 些特性。您将了解一些基本内容,如(关系的和面向对象的)继承、 从属与相关关系、对象查询语言(Object Query Language)实现以 及短事务和长事务的比较。 第一部分:J DO 配置数据库配置意味着从数据库服务器中获得一个连接,和在java类和数据表间映射,以及提供数据库服务与客户间的会话。Castor支持目前所有主流的数据库产品,需要注意的是,它不支持JDBC-ODBC桥接方式。不同的数据库服务有着不同的配置语法,通过配置数据库服务器对客户提供服务。 Castor支持的数据库系统列表如下: 1:oracle Oracle 7 and Oracle 8 2:sybase Sybase 11 3:sql-server Microsoft SQL Server 4:db2 DB/2 5:informix Informix 6:postgresql PostgreSQL 7.1 7:hsql Hypersonic SQL 8:instantdb InstantDB 9:interbase Interbase 10:mysql MySQL 11:sapdb SAP DB 下面给出几种数据库系统的配置方式: Sybase jConnect Oracle Thin Driver InstantDB sql-server 第二部分:第一个例子 在这一部分里我将从一个简单的数据模型开始,并让你初步了解如何使用Castor。 首先我定义一个简单的数据模型,不包含任何的关系。 她的代码如下:Customer.java package org.user; import java.util.*; public class Customer{ private int _id; private String _last_name; private String _first_name; public int getId() { return _id; } public void setId( int id ) { _id = id; } public String getFname() { return _first_name; }public void setFname( String first_name ) { _first_name = first_name; } public String getLname() { return _last_name; } public void setLname( String last_name ) { _last_name = last_name; } public void toString() { return this.getFname()+" "+this.getLname() ","+this.getId(); } } 正如你所看到的,它可以是一个普通类,当然你也可以实现org.exolab.castor.jdo.Persistent接口,从而在持久化之前做预处理。 现在让我们来看映射配置文件 mapping.xml databases PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN" "http://castor.exolab.org/mapping.dtd"> Customer 正如你所看到的,映射文件很简单。 元素支持一些重要的属性和元素。例如,Customer映射使用 identify 属性来指示对象的哪个特性充当对象标识符。 元素还支持 元素, 该元素告诉 Castor 每个对象映射到什么关系表上。 元素也支持一些属性。请注意,所有 元素的映射都包 含 type 属性。类型属性向 Castor指示:该在内部使用什么 类型转换器来在对象 和关系数据类型之间进行转换。 现在让我们来写一个测试文件: test.java import org.user.*; public class Mytest{ public static final String DatabaseFile = "database.xml"; public static final String MappingFile = "mapping.xml"; public static final String Usage = "Usage: example jdo"; private Mapping _mapping; private JDO _jdo; public static void main( String[] args ) { try { Test test = new Ttest(); test.run(); } catch ( Exception except ) { except.printStackTrace(); } } public Test() throws Exception { // 装载实体关系映射文件 _mapping = new Mapping( getClass().getClassLoader() ); _mapping.loadMapping( getClass().getResource( MappingFile ) ); //装载数据库连接映射文件 _jdo = new JDO(); _jdo.setConfiguration( getClass().getResource( DatabaseFile ). toString() ); _jdo.setDatabaseName( "test" ); } public void run() throws Exception { Database db; Customer customer; OQLQuery customerOql; QueryResults results; db = _jdo.getDatabase(); //注意在持久化对对象包含关系引用时,必须打开这个选项才能够自动持久 化关系对象。db.setAutoStore(true); db.begin(); customer = new Customer(); customer.setId(1); customer.setFname("rain"); customer.setLname("wk"); //持久化数据 db.makePersistent(customer); //通过装载也可加载数据// customer = (Customer)db.load(Customer.class,new Integer("1"));//System.out.println( "select customer: " + customer); //通过OQL语言查询持久化数据。 customerOql = db.getOQLQuery("SELECT p FROM org.user.Customer p WHERE p.id =$1"); productOql.bind(1); results = customerOql.execute(); while ( results.hasMore()) { customer = (Customer) results.next(); System.out.println( "select customer: " + customer); } db.commit();} }
结果: select customer:rain wk ,1 在体验完第一个例子后,想必你对Castor 有了一定的认识,是不是看上去很简单,Castor帮你是现实过去需要EJB才能实现的实体持久化。这正是我们想要的,一个轻量级的可以在大多数场合替代EJB的有效技术。我将在接下来的文章中详细讲解Castor JDO 技术。
第四部分:JDO 关系 上一章我讲解了JDO的持久化,本章将讲解JDO中关于关系的问题。同样的]我将通过几个例子来详细介绍他的有关特性。 为了处理真实世界的模型,jdo必须能够管理数据模型彼此复杂的关系,在jdo中,不同种类的关系被归为5种类型:一对多单向,一对多双向,多对一单向,多对一双向,多对多。在开始之前,我们先定义一个管理接口的适配器,以方便编码。 abstract class PersistentCapable implements Persistent{private Database _db; public void jdoPersistent( Database db ) { _db = db; } public void jdoTransient() { _db = null; } public Class jdoLoad(short accessMode) { return null; } public void jdoBeforeCreate( Database db ) { } public void jdoAfterCreate() { } public void jdoStore(boolean modified) { } public void jdoBeforeRemove() { } public void jdoAfterRemove() { } public void jdoUpdate() { }} 一对多在一对多的关系下,数据模型中从表有一个指向主表的引用,模型图如下所示,Oder 和Orderitem 构成了主从表关系,order_id=id 为其关系。一对多关系是典型的数据库应用。但是从Castor中存储的时候却必须以主(Oder)对象来持久化,从(Orderitem)做为他的从属对象来对待。
首先让我们来看一下order类。需要注意的是:第一,实现Persistent接口。第二,建立与OrderItem的引用。package org.user; import java.util.*; public class Order extend PersistentCapable { private int _id; private String _name; private Vector _orderItems = new Vector(); public void setId(int id){ _id = id; } public int getId(){ return _id; } public void setName(String name){ _name = name; } public String getName(){ return _name; } public void addOrderItem(OrderItem orderItem){ _orderItems.add(orderItem); orderItem.setOrder(this); } public Vector getOrderItems(){ return _orderItems; }} 同样的OrderItem也保持一个Order的引用。 package org.user; import java.util.*; public class OrderItem{ private int _id; private String _name; private float _price; private Order _order; public void setId(int id){ _id = id; } public int getId(){ return _id; } public void setName(String name){ _name = name; } public String getName(){ return _name; } public void setPrice(float price){ _price = price; } public float getPrice(){ return _price; } public void setOrder(Order order){ _order = order; } public Order getOrder(){ return _order; }} 接下来让我们看一看配置文件的内容。 Order OrderItem 需要注意的是如下的配置代码: Order引用了一个外部类型OrderItem,外部字段名称是ORDER_ID ,orderItems属性返回一个collection结构的对象集合。 同样的OrderItem引用了一个Order类型的关系,字段名称是ORDER_ID。 上面的关系是双向的,他们可以互相观察对方,你可以通过任何一方来导航,但也可以是单向的,即通过主导航到从,你需要修改部分代码,这里我就不讲了,不过我建议你使用双向导航。多对一
在多对一的关系下,数据模型中主表有一个指向从表的引用,模型图如下所示,Customer 和Address 构成了表关系,多对一关系是典型的数据库应用。是Castor中存储的时候却必须以主(Customer)对象来持久化,从(Address)做为他的从属对象来对待。
代码如下.package org.user; import java.util.*; public class Customer extend PersistentCapable { private int _id; private String _last_name; private String _first_name; private Vector _address =new Vector(); private Address _address; public int getId() { return _id; } public void setId( int id ) { _id = id; }public String getFname() { return _first_name; }public void setFname( String first_name ) { _first_name = first_name; } public String getLname() { return _last_name; } public void setLname( String last_name ) { _last_name = last_name; } public Address getAddress() { return _address; } public void addAddress( Address address ) { _address.add( address ); address.setCustomer(this); } public void setAddress(Address address) { _address = address; } } package org.user; public class Address{ private int _id; private String _street; private String _city; private String _state; private String _zip; private Customer _customer; public int getId() { return _id; } public void setId( int id ) { _id = id; } public String getStreet() { return _street; } public void setStreet( String street ) { _street = street; } public String getCity() { return _city; } public void setCity( String city ) { _city = city; } public String getState() { return _state; } public void setState( String state ) { _state = state; } public String getZip() { return _zip; } public void setZip( String zip ) { _zip = zip; } public Customer getCustomer() { return _customer; } public void setCustomer( Customer customer ) { _customer = customer; }} Customer Address Customer引用了一个外部类型Address,字段名称是ADDRESS_ID。 多对多 在多对多的关系下,数据模型中表A,表B都有一个指向中间表的引用,模型图如下所示category 和category_prod构成了表关系,prod和category_prod构成了表关,这样category和prod构成多对多得关系,这是典型的数据库应用。 代码如下: package jdo; import java.util.Vector;import java.util.Enumeration; public class Category{ private int _id; private Vector _products = new Vector();private String _name; public int getId() { return _id; } public void setId( int id ) { _id = id; } public String getName() { return _name; } public void setName( String name ) { _name = name; } //public Enumeration getProducts() public Vector getProducts() { return _products; // return _products.elements(); } public void addProduct( Product product ) { if ( ! _products.contains( product ) ) { System.out.println( "Adding product " + product + " to category " + this ); _products.addElement( product ); product.addCategories( this ); } } public String toString() { return ""; }} package jdo; import java.util.Vector;import java.util.Enumeration;import org.exolab.castor.jdo.Database;import org.exolab.castor.jdo.Persistent; public class Product //implements Persistent{ private int _id; private String _name; private float _price; private Database _db; private Vector _categories = new Vector(); public int getId() { return _id; } public void setId( int id ) { _id = id; } public String getName() { return _name; } public void setName( String name ) { _name = name; } public float getPrice() { return _price; } public void setPrice( float price ) { _price = price; } public Vector getCategories() { return _categories; } public void addCategories( Category category ) { if ( ! _categories.contains( category ) ) { _categories.addElement( category ); category.addProduct( this ); } } public String toString() { return ""; }} Product definition A product category, any number of products can belong to the same category, a product can belong to any number of categories Product含有一个 Category引用,附加一个中间表category_prod,字段名称为category_id;同样 Category也有一个 Product引用,附加一个中间表category_prod,字段名称为prod_id。
在本文中,我们讨论了使用 Castor 将关系数据模型映射到 Java 对象模型的基础知识。同过这些简单的示例肯定不能涵盖 Castor 的全部能力。实际上,Castor 支持许多其它特性,包括键生成、延迟装入、LRU 高速缓存、不同的锁定/访问方式以及更多。我将在下一部分介绍更多的知识。
↑返回目录
前一篇: Checkstyle的 使用
后一篇: C++中的文件输入/输出(5)