CASTOR JDO 指南 (转)

CASTOR JDO 指南 (转)[@more@]

CASTOR  JDO 指南
  现在,越来越多的企业级开发项目中需要一种在众多关系数据库
上进行对象关系映射的技术。遗憾的是,个体组织内部的解决方案很
难构建,而对其进行长期维护和扩展就更难了。虽然有了EJB技术,
但是我发现在某些情况下使用EJB技术往往过于重量级了,这时候适合
的解决方式应该是轻量级的为好。本文中,我将向您介绍了使用 Cast
or JDO 的基础知识, Castor JDO(Java 数据对象 (Java Data Obje
cts))是一种开放源码的、百分之百 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 
  source class-name="com.sybase.JDBC2.jdbc.SybDataSource">
  word="secret"  port-number="4100"
  server-name="host" />
 
 
Oracle Thin driver 

    url="jdbc:oracle:thin:@host:post:SID">
  SCOtt" />
 
 

 
InstantDB 
    url="jdbc:idb:C:castor-0.8.8db est est.prp">
 
 
 
 
sql-server

 
 


   url="jdbc:microsoft:sqlserver://localhost:1433">
 
 
 
  ping href="mapping.xml"/>

 
 


第二部分:第一个例子

 
 

在这一部分里我将从一个简单的数据模型开始,并让你初步了解如何使用
Castor。

 
 

首先我定义一个简单的数据模型,不包含任何的关系。
 2003-5-151247520.bmp" align=baseline border=0>

 
 

她的代码如下:
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

 
 

BR>  "http://castor.exolab.org/mapping.dtd">

identity="id">
 
  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
 
 
 
 
 
 
 

 
 

    collection="vector">
 
 
 

 
 


 
  OrderItem
 

 
 
 
 
 
 
 
 
 
 
   
 
 

 
 


需要注意的是如下的配置代码:

 
 

Order引用了一个外部类型OrderItem,外部字段名称是ORDER_ID ,orderItems属
性返回一个collection结构的对象集合。
collection="vector">

 
 

同样的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 "";
  }
}

 
 


<!--  Mapping for Product  --&gt
 
  Product definition
 
 
 
 
 
 
 
 
 
 

 
 

  <!-- Product has reference to Category with
  many-many relationship --&gt
    collection="vector">
    many-table="category_prod" many-key="prod_id" />
 
 

 
 


 
  A product category, any number of products can belong to
  the same category, a product can belong to any number of
  categories
 
 
 
 
 
 
 
 
    collection="vector">
    many-table="category_prod" many-key="category_id" />
 
 

 
 


Product含有一个 Category引用,附加一个中间表category_prod,字段名称为
category_id;同样 Category也有一个 Product引用,附加一个中间表categor
y_prod,字段名称为prod_id。

 
 

  collection="vector">
    many-table="category_prod" many-key="prod_id" />
 

 
 

  collection="vector">
    many-table="category_prod" many-key="category_id" />
 

 
 

 

 
 

在本文中,我们讨论了使用 Castor 将关系数据模型映射到 Java 对象模型的基
础知识。同过这些简单的示例肯定不能涵盖 Castor 的全部能力。实际上,Cast
or 支持许多其它特性,包括键生成、延迟装入、LRU 高速缓存、不同的锁定/访
问方式以及更多。我将在下一部分介绍更多的知识。

 
 


参考资料

 
 

 

 
 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10752019/viewspace-956657/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/10752019/viewspace-956657/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值