实战演练:Hibernate映射Oracle的XmlType到Document(xml)对象
先请参看 上一篇文章
[1]POJO
package com.csc.poimanager.dao;
import org.dom4j.Document;
public class XmlTest implements java.io.Serializable {
private Long itemId;
private Long poiId;
private String itemName;
private Document itemValue;
public XmlTest() {
}
public XmlTest(String itemName) {
this.itemName = itemName;
}
public Long getItemId() {
return this.itemId;
}
public void setItemId(Long itemId) {
this.itemId = itemId;
}
public Long getPoiId() {
return this.poiId;
}
public void setPoiId(Long poiId) {
this.poiId = poiId;
}
public String getItemName() {
return this.itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public Document getItemValue() {
return this.itemValue;
}
public void setItemValue(Document itemValue) {
this.itemValue = itemValue;
}
}
[2]自定义映射类型
package com.csc.poimanager.dao.type;
import java.io.Serializable;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import oracle.jdbc.OraclePreparedStatement;
import oracle.jdbc.OracleTypes;
import oracle.jdbc.driver.OracleResultSet;
import oracle.sql.OPAQUE;
import oracle.xdb.XMLType;
import org.dom4j.Document;
import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;
import com.csc.poimanager.util.XmlUtil;
public class PoiAdditionalXmlType implements UserType, Serializable {
private static final Class returnedClass = String.class; // 属性的java类型
private static final int[] SQL_TYPES = new int[] { oracle.xdb.XMLType._SQL_TYPECODE }; // 数据中类型
public int[] sqlTypes() {
return SQL_TYPES;
}
public Class returnedClass() {
return returnedClass;
}
public boolean equals(Object arg0, Object arg1) throws HibernateException {
if (arg0 == null || arg1 == null) {
throw new HibernateException("None of the arguments can be null.");
}
if (arg0 instanceof oracle.xdb.XMLType
&& arg1 instanceof oracle.xdb.XMLType) {
return arg0.equals(arg1);
}
return false;
}
public int hashCode(Object arg0) throws HibernateException {
return 0;
}
public Object nullSafeGet(ResultSet rs, String[] names, Object arg2)
throws HibernateException, SQLException {
XMLType xmlType = null;
Document doc = null;
try {
OPAQUE value = null;
OracleResultSet ors = null;
if (rs instanceof OracleResultSet) {
ors = (OracleResultSet)rs;
} else {
throw new UnsupportedOperationException("ResultSet needs to be of type OracleResultSet");
}
value = ors.getOPAQUE(names[0]);
xmlType = XMLType.createXML(value);
Clob xmlClob = xmlType.getClobVal();
doc = XmlUtil.create(xmlClob.getCharacterStream());
}finally {
if (null != xmlType) {
xmlType.close();
}
}
return doc;
}
public void nullSafeSet(PreparedStatement stmt, Object value, int index)
throws HibernateException, SQLException {
XMLType xmlType = null;
try {
//If the value is null then set NULL and return
if (null == value) {
stmt.setNull(index, OracleTypes.OPAQUE, "SYS.XMLTYPE");
return;
}
if (stmt instanceof OraclePreparedStatement) {
xmlType = XMLType.createXML(stmt.getConnection(), XmlUtil.toPlanString((Document)value));
OraclePreparedStatement oracleStmt = (OraclePreparedStatement)stmt;
oracleStmt.setObject(index, xmlType);
}else {
throw new HibernateException("PreparedStatement object must be a OraclePreparedStatement");
}
}finally {
if (null != xmlType) {
xmlType.close();
}
}
}
public Object deepCopy(Object value) throws HibernateException {
return value;
}
public boolean isMutable() {
return false;
}
public Serializable disassemble(Object arg0) throws HibernateException {
return null;
}
public Object assemble(Serializable arg0, Object arg1)
throws HibernateException {
return null;
}
public Object replace(Object arg0, Object arg1, Object arg2)
throws HibernateException {
return null;
}
}
[3]映射文件
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="com.csc.poimanager.dao.XmlTest" table="XML_TEST">
<id name="itemId" type="java.lang.Long">
<column name="ITEM_ID" precision="10" scale="0" />
<generator class="increment" />
</id>
<property name="poiId" type="java.lang.Long">
<column name="POI_ID" precision="10" scale="0" />
</property>
<property name="itemName" type="java.lang.String">
<column name="ITEM_NAME" />
</property>
<property name="itemValue" type="com.csc.poimanager.dao.type.PoiAdditionalXmlType" >
<column name="ITEM_VALUE" />
</property>
</class>
</hibernate-mapping>
[4]XmlUtil定义
/**
*
*/
package com.csc.poimanager.util;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentFactory;
import org.dom4j.io.DOMWriter;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
/**
* @author zhangyi
*
*/
public class XmlUtil {
public static Document create() {
Document doc = null;
doc = DocumentFactory.getInstance().createDocument();
return doc;
}
public static Document create(String xmlString) {
StringReader source = new StringReader(xmlString);
return create(source);
}
public static Document create(Reader sourceReader) {
SAXReader reader = new SAXReader();
Document doc = null;
try {
doc = reader.read(sourceReader);
doc.setXMLEncoding("UTF-8");
} catch (DocumentException e) {
e.printStackTrace();
}
return doc;
}
/**
* get xml document text
*
* @param xmlDoc
* @return
*/
public static String toPlanString(Document xmlDoc) {
StringWriter destWriter = new StringWriter();
XMLWriter writer = new XMLWriter(destWriter,OutputFormat.createPrettyPrint());
try {
writer.write(xmlDoc);
} catch (IOException e) {
e.printStackTrace();
}
String xmlStr = destWriter.getBuffer().toString();
return xmlStr;
}
}
[5]实现insert
XmlTest xt = new XmlTest();
xt.setItemName("sfsdfsfsdfds");
xt.setItemValue(XmlUtil.create("<a><b>zhang yi ass</b></a>"));
XmlTestDAO xtdao = new XmlTestDAO();
Session sess = xtdao.getSession();
Transaction tx = sess.beginTransaction();
xtdao.save(xt);
tx.commit();
sess.close();
System.out.println("saving xmltest ok ");
执行结果:
saving xmltest ok
[6]实现查询
XmlTestDAO xtdao = new XmlTestDAO();
Session sess = xtdao.getSession();
Transaction tx = sess.beginTransaction();
XmlTest xt =xtdao.findById((long)9);
System.out.println("xt item_value : " + xt.getItemName());
System.out.println("xt item_value : " + xt.getItemValue());
System.out.println("xt item_value : " + xt.getItemValue().getRootElement().getName());
tx.commit();
sess.close();
System.out.println("getting xmltest ok ");
结果如下:
xt item_value : sfsdfsfsdfds
xt item_value : org.dom4j.tree.DefaultDocument@4ee70b [Document: name null]
xt item_value : a
getting xmltest ok
xt.getItemValue()取得的值是一个org.dom4j.Document对象,这样,就可以用dom4j的东西去实现你要的所有的操作。所以,所有的东西就只有对象,而不需要,去考虑操作XmlType的东西了。
[7]总结
我觉得值得说的难点有两个,一个是自定义类型里面的nullSafeSet和nullSafeGet方法,另一个是映射的时候,要根据你nullSafeGet的返回值的类型来确定。
一定注意,映射的不是你的自定义类型的对象,如上面的PoiAdditionalXmlType,而是你的解析后的对象org.dom4j.Document。
|----------------------------------------------------------------------------------------|
版权声明 版权所有 @zhyiwww
引用请注明来源 http://www.blogjava.net/zhyiwww
|----------------------------------------------------------------------------------------|