数据绑定这个名词对于大多数程序员已经不再陌生了;Java语言(面向对象)已经被证明是一种非常适合数据绑定的语言。我们再看看数据绑定的另一个端即数据媒介,通常有文本文件,XML文件,以及数据库。正如文章提及的大多数程序员理解的数据绑定是XML文档和Java程序结构的关系,其实这仅仅是这两端的一个具体应用。
几个重要概念:
编组(Marshalling)是把内存中的数据转化到存储媒介上的过程。因此在 Java 和 XML 环境中,编组就是把一些 Java 对象转化成一个(或多个) XML 文档。在数据库环境中,则是把 Java 表示的数据存入数据库。显然,编组的秘密在于把 Java 实例中的面向对象结构转化成适用于 XML 的扁平结构,或者 RDBMS 中的关系结构(使用 Java 技术转换到 OODBMS 实际上很简单)。
解组(Unmarshalling)是把数据从存储媒介转换到内存中的过程——正好与编组相反。因此需要把 XML 文档解组到 Java VM 中。这里的复杂性不是在扁平数据中,因为这不是必需的,而在于从正确的数据到正确的 Java 代码变量的映射。如果映射是错误的,就不可能正确地访问数据。当然,如果再尝试重新编组还会造成更大的问题,并且问题传播得很快。
往返(Round-tripping)可能是最重要也最容易误解的数据绑定术语。往返用于描述从存储媒介到内存然后回到存储媒介的完整循环。在 XML 和 Java 技术环境中,这就意味着从 XML 文档到 Java 实例变量,然后再回到 XML 文档。正确的往返要求,如果中间没有修改数据,XML 输入和 XML 输出应该是等同的。
几个数据绑定框架:
Castor 框架:
Castor XML 数据绑定很容易上手,甚至不需要定义 XML 文档格式。只要您的数据用类 JavaBean 的对象表示,Castor 就能自动生成表示这些数据的文档格式,然后从文档重构原始数据。
用一个例子(Castor)来说明:Jbuilder中调试
This bean was auto generated from a schema
清单 1. XmlEmployeeType信息 bean
package com.borland.samples.xml.databinding.castor;
import java.io.IOException;
import java.io.Reader;
import java.io.Serializable;
import java.io.Writer;
import org.exolab.castor.xml.MarshalException;
import org.exolab.castor.xml.Marshaller;
import org.exolab.castor.xml.Unmarshaller;
import org.exolab.castor.xml.ValidationException;
import org.xml.sax.ContentHandler;
/**
* Class XmlEmployeeType.
* @version $Revision$ $Date$
*/
public class XmlEmployeeType implements java.io.Serializable {
private java.lang.String _empNo;
private java.lang.String _firstName;
private java.lang.String _lastName;
private java.lang.String _phoneExt;
private java.lang.String _hireDate;
private java.lang.String _deptNo;
private java.lang.String _jobCode;
private java.lang.String _jobGrade;
private java.lang.String _jobCountry;
private java.lang.String _salary;
private java.lang.String _fullName;
public XmlEmployeeType() {
super();
}
public java.lang.String getDeptNo()
{
return this._deptNo;
}
public java.lang.String getEmpNo()
{
return this._empNo;
}
public java.lang.String getFirstName()
{
return this._firstName;
}
public java.lang.String getFullName()
{
return this._fullName;
}
public java.lang.String getHireDate()
{
return this._hireDate;
}
public java.lang.String getJobCode()
{
return this._jobCode;
} tJobCode()
public java.lang.String getJobCountry()
{
return this._jobCountry;
}
public java.lang.String getJobGrade()
{
return this._jobGrade;
}
public java.lang.String getLastName()
{
return this._lastName;
}
public java.lang.String getPhoneExt()
{
return this._phoneExt;
}
public java.lang.String getSalary()
{
return this._salary;
} //-- java.lang.String getSalary()
public boolean isValid()
{
try {
validate();
}
catch (org.exolab.castor.xml.ValidationException vex) {
return false;
}
return true;
}
public void marshal(java.io.Writer out)
throws org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException
{
Marshaller.marshal(this, out);
}
public void marshal(org.xml.sax.ContentHandler handler)
throwsjava.io.IOException,org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException
{
Marshaller.marshal(this, handler);
}
public void setDeptNo(java.lang.String deptNo)
{
this._deptNo = deptNo;
}
public void setEmpNo(java.lang.String empNo)
{
this._empNo = empNo;
}
public void setFirstName(java.lang.String firstName)
{
this._firstName = firstName;
} //-- void setFirstName(java.lang.String)
public void setFullName(java.lang.String fullName)
{
this._fullName = fullName;
} //-- void setFullName(java.lang.String)
public void setHireDate(java.lang.String hireDate)
{
this._hireDate = hireDate;
} //-- void setHireDate(java.lang.String)
public void setJobCode(java.lang.String jobCode)
{
this._jobCode = jobCode;
} //-- void setJobCode(java.lang.String)
public void setJobCountry(java.lang.String jobCountry)
{
this._jobCountry = jobCountry;
} //-- void setJobCountry(java.lang.String)
public void setJobGrade(java.lang.String jobGrade)
{
this._jobGrade = jobGrade;
} //-- void setJobGrade(java.lang.String)
public void setLastName(java.lang.String lastName)
{
this._lastName = lastName;
} //-- void setLastName(java.lang.String)
public void setPhoneExt(java.lang.String phoneExt)
{
this._phoneExt = phoneExt;
} //-- void setPhoneExt(java.lang.String)
public void setSalary(java.lang.String salary)
{
this._salary = salary;
} //-- void setSalary(java.lang.String)
public static java.lang.Object unmarshal(java.io.Reader reader)
throws org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException
{
Return(com.borland.samples.xml.databinding.castor.XmlEmployeeType) Unmarshaller.unmarshal(com.borland.samples.xml.databinding.castor.XmlEmployeeType.class, reader);
} //-- java.lang.Object unmarshal(java.io.Reader)
public void validate()
throws org.exolab.castor.xml.ValidationException
{
org.exolab.castor.xml.Validator validator = new org.exolab.castor.xml.Validator();
validator.validate(this);
} //-- void validate()
}
清单 2. 测试默认的数据绑定
/**
* Title: XML Tutorial
* Description: XML Tutorial for JBuilder
* Company: Borland Software Coporation
* @author
* @version 1.0
*/
import java.io.*;
import org.exolab.castor.xml.*;
public class DB_Castor {
public DB_Castor() {
}
public static void main(String[] args) {
try {
String fileName = "Employees.xml";
System.out.println("== unmarshalling \"" + fileName + "\" ==");
//Unmarshal XML file.
XmlEmployeesxmlEmployees = (XmlEmployees)XmlEmployees.unmarshal(new FileReader(fileName));
System.out.println("TotalNumber of XmlEmployees read = " + xmlEmployees.getXmlEmployeeCount());
System.out.println("FirstXmlEmployee's Full Name is " + xmlEmployees.getXmlEmployee(0).getFullName());
System.out.println("LastXmlEmployee's Full Name is " + xmlEmployees.getXmlEmployee(xmlEmployees.getXmlEmployeeCount()-1).getFullName());
// Add an XmlEmployee.
xmlEmployees.addXmlEmployee(getXmlEmployee("8000","400","Charlie","Castor","3/3/2001","VP","USA","2","1993","155000.00"));
// Modify the last XmlEmployee.
xmlEmployees.setXmlEmployee(xmlEmployees.getXmlEmployeeCount()-1, getXmlEmployee("8000","600","Peter","Castor","3/3/2001","VP","USA","3","2096","125000.00"));
// Marshal out the data to the same XML file.
xmlEmployees.marshal(new java.io.FileWriter(fileName));
}
catch (Exception ex) {
ex.printStackTrace();
}
}
private static XmlEmployee getXmlEmployee(String XmlEmployeeNumber,String departmentNumber,String firstName,String lastName,String hireDate,String jobCode,String jobCountry,String jobGrade,String phoneExt,String salary){
XmlEmployee xmlEmployee = new XmlEmployee();
xmlEmployee.setEmpNo(XmlEmployeeNumber);
xmlEmployee.setDeptNo(departmentNumber);
xmlEmployee.setFirstName(firstName);
xmlEmployee.setLastName(lastName);
xmlEmployee.setFullName(lastName+", "+firstName);
xmlEmployee.setHireDate(hireDate);
xmlEmployee.setJobCode(jobCode);
xmlEmployee.setJobCountry(jobCountry);
xmlEmployee.setJobGrade(jobGrade);
xmlEmployee.setPhoneExt(phoneExt);
xmlEmployee.setSalary(salary);
return xmlEmployee;
}
}
最后,看看运行的效果;XML是不是变化了;此篇仅仅描述了一个Castor框架,还有JAXB(Sun的框架);以及其他开源的框架需要不断的去学习。
参考资料:http://www-900.ibm.com/developerWorks/cn/xml/theme/x-pracdb.shtml