• 沒有找到結果。

Persistence Using Castor

在文檔中 WILEY advantage (頁 140-144)

The Castor project provides data-binding from Java objects to SQL tables, XML docu-ments, and a number of other sources. This chapter looks only at the SQL mapping functionality, which is implemented in the org.exolab.castor.jdopackage. An object using Castor for persistence must implement the Persistentinterface. This standard interface has the callback methods for persistence events. In addition to the notification methods described earlier, this includes a method to give the object a reference to the Castor Databaseobject. The Databaseobject represents the con-nection to the database and is used to add Java objects to the persistence engine for a given transaction. It has methods to create, update, and remove Persistentobjects.

Existing objects are located using the OQLQueryclass. This class is used to implement a subset of the object query language as defined by the Object Management Group (OMG) 3.0 Object Query Language (OQL) Specification. OQL is used to select objects from the database. The basic structure of OQL is similar to SQL, except that OQL refers to objects and properties rather than tables and columns. For a full description of these classes, please refer to the production documentation available on the OMG Web site.

Because persistent objects must implement a Castor-specific interface, a version of the business object base class, called CastorBaseBusinessObject, is created specifically for the Castor implementation. This base class, as well as all of the founda-tion classes related to Castor, is put in the blf.castor package of the reference architecture. The application business objects now implement both the Business-Object interface and Castor’s Persistentinterface. A basic outline of the base class,CastorBaseBusinessObject, is shown here:

package blf.castor;

import org.exolab.castor.jdo.Database;

import org.exolab.castor.jdo.Persistent;

import blf.*;

public class CastorBaseBusinessObject implements Persistent, BusinessObject { protected HashMap attributeMetadata;

protected BusinessObjectMetadata bom;

protected ErrorList errorList;

protected String objectName;

private Database _db;

116 J2EE Best Practices: Java Design Patterns, Automation, and Performance

public CastorBaseBusinessObject(String objectName) { try {

bom =

MetadataManager.getBusinessObject(objectName);

attributeMetadata = bom.getPropertyMap();

this.objectName = objectName;

} catch (BlfException be) { be.printStackTrace();

} }

public CastorBaseBusinessObject(String objectName,

ValueObject valueObject) { try {

bom =

MetadataManager.getBusinessObject(objectName);

attributeMetadata = bom.getPropertyMap();

setProperties(valueObject);

this.objectName = objectName;

} catch (Exception e) { e.printStackTrace();

} } //

// Implementation of business object methods to follow, // that is, standard property management methods, and so on //

//

// Castor JDO callbacks //

public void jdoPersistent( Database db ) { _db = db;

}

public void jdoTransient() { _db = null;

}

public Database getDatabase() { return _db;

}

public Class jdoLoad(short accessMode) { return null;

}

public void jdoBeforeCreate( Database db ) { }

TE AM FL Y

Team-Fly

®

public void jdoAfterCreate() { }

public void jdoStore(boolean modified){

} //

// Rest of JDO callbacks to follow...

//

}

In this code snippet, you see that no real work is being done in the persistence callbacks. One reason for this is that the create methods cannot be overloaded as is the case with ejbCreatemethods on Entity Beans. In the next section on object creation and instantiation, you will see that some of these lifecycle events for Castor business objects are handled by the business object factory mechanism. This pattern will be used to abstract the persistence mecha-nism and simplify its integration into the Business Object Architecture. Once the Entity Bean implementation is discussed, you will see the persistence callbacks being used to implement business logic template methods.

TheAccountbusiness object using Castor as an object-relational mapping tool then extendsCastorBaseBusinessObjectand implements the JavaBeans convention for properties. The basic code for theAccountobject is shown here:

package bank.castor;

import blf.*;

import org.exolab.castor.jdo.Database;

import org.exolab.castor.jdo.Persistent;

import java.math.BigDecimal;

import java.util.Date;

public class Account extends CastorBaseBusinessObject

implements java.io.Serializable, Persistent, BusinessObject {

private String id;

private String number;

private String type;

private BigDecimal currentBalance;

private Date lastModifiedDate;

public Account() { super("Account");

}

N OT E

118 J2EE Best Practices: Java Design Patterns, Automation, and Performance

public Account(ValueObject values) { super("Account",values);

}

public String getId() { return id;

}

public void setId(String value) { id = value;

}

public String getNumber() { return number;

}

public void setNumber(String value) { number = value;

}

public String getType() { return type;

}

public void setType(String value) { type = value;

}

public BigDecimal getCurrentBalance() { return currentBalance;

}

public void setCurrentBalance(BigDecimal value) { currentBalance = value;

}

public Date getLastModifiedDate() { return lastModifiedDate;

}

public void setLastModifiedDate(Date value) { lastModifiedDate = value;

}

//

// Business methods to follow...

//

}

The deployment configuration to map the account’s properties to the database is shown here. In this case, it maps all of the properties to a single table named ‘account.’

Note that the ‘field’ and ‘sql’ types have different values in some cases to properly map

between SQL data types and Java data types. The mapping.xmlfile for the example is as follows:

<!DOCTYPE databases PUBLIC

"-//EXOLAB/Castor Mapping DTD Version 1.0//EN"

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

<mapping>

<class name="bank.castor.Account"

identity="id">

<description>Account</description>

<map-to table="account" />

<field name="id" type="string" >

<sql name="id" type="varchar"/>

</field>

<field name="type" type="string">

<sql name="type" type="char" dirty="check" />

</field>

<field name="number" type="string">

<sql name="number" type="char" dirty="check" />

</field>

<field name="currentBalance" type="big-decimal">

<sql name="balance" type="decimal" dirty="check" />

</field>

<field name="lastModifiedDate" type="date">

<sql name="last_modified_date" type="date"

dirty="check" />

</field>

</class>

</mapping>

Entity Bean Container-Managed

在文檔中 WILEY advantage (頁 140-144)