转自 :http://www.iteye.com/topic/182797
仔细看看hibernate的DOC发现不少惊奇的东东,后悔自己的旁门助道是多么的无用. 本次主要实现目的. 数据库表:EchoMessageEmail,其中有三个字段id(自动编号)\name\Email(varchar) 实现目的:数据库字段中Email的值是类似于[email protected];www.1718zx.cn的.所以要求以List表达.也就是生成的DataModel当中是有一个List对象的.hbm.xml
xml 代码
<?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 - Hibernate Tools --> <hibernate-mapping> <class name="com.travelsky.hibernate.po.EchoMessageEmail" table="echo_message_email"> <id name="id" type="java.lang.Integer"> <column name="ID" /> <generator class="native"></generator> </id> <property name="name" type="java.lang.String"> <column name="NAME" length="50" not-null="true" /> </property> <property name="email" type="com.travelsky.hibernate.po.EmailList" lazy="true"> <column name="EMAIL"/> </property> </class> </hibernate-mapping>
package com.travelsky.hibernate.po; import java.util.List; /** * EchoMessageEmail generated by MyEclipse Persistence Tools */ public class EchoMessageEmail implements java.io.Serializable { private Integer id; private String name; private List email; /** default constructor */ public EchoMessageEmail() { } /** minimal constructor */ public EchoMessageEmail(String name) { this.name = name; } /** full constructor */ public EchoMessageEmail(String name, List email) { this.name = name; this.email = email; } // Property accessors public Integer getId() { return this.id; } public void setId(Integer id) { this.id = id; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } public List getEmail() { return email; } public void setEmail(List email) { this.email = email; } }
import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import net.sf.hibernate.HibernateException; /** * @author hy-he * */ public interface UserType { /** * 返回UserType所映射字段的SQL类型(java.sql.Types) * 返回类型为int[],其中包含了映射个字段的SQL类型代码 * (UserType可以映射到一个或者多个字段) * @return */ public int[]sqlTypes(); /** * UserType.nullSafeGet()所返回的自定义数据类型 * @return */ public Class returnedClass(); /** * 自定义数据类型的比对方法 * 此方法将用作脏数据检查,参数x、y分别为数据的两个副本 * 如果equals方法返回false,则Hibernate将认为数据发生变化,并将变化更新到数据库表中 * @param x * @param y * @return * @throws HibernateException */ public boolean equals(Object x,Object y)throws HibernateException; /** * 从JDBC ResultSet读取数据,将其转换为自定义类型后返回 * (此方法要求对克能出现null值进行处理) * names中包含了当前自定义类型的映射字段名称 * @param rs * @param names * @param owner * @return * @throws HibernateException * @throws SQLException */ public Object nullSafeGet(ResultSet rs,String[] names,Object owner)throws HibernateException,SQLException; /** * 本方法将在Hibernate进行数据保存时被调用 * 我们可以通过PreparedStateme将自定义数据写入到对应的数据库表字段 * @param st * @param value * @param index * @throws HibernateException * @throws SQLException */ public void nullSafeSet(PreparedStatement st,Object value,int index)throws HibernateException,SQLException; /** * 提供自定义类型的完全复制方法 * 本方法将用构造返回对象 * 当nullSafeGet方法调用之后,我们获得了自定义数据对象,在向用户返回自定义数据之前, * deepCopy方法将被调用,它将根据自定义数据对象构造一个完全拷贝,并将此拷贝返回给用户 * 此时我们就得到了自定义数据对象的两个版本,第一个是从数据库读出的原始版本,其二是我们通过 * deepCopy方法构造的复制版本,原始的版本将有Hibernate维护,复制版由用户使用。原始版本用作 * 稍后的脏数据检查依据;Hibernate将在脏数据检查过程中将两个版本的数据进行对比(通过调用 * equals方法),如果数据发生了变化(equals方法返回false),则执行对应的持久化操作 * * @param value * @return * @throws HibernateException */ public Object deppCopy(Object value)throws HibernateException; /** * 本类型实例是否可变 * @return */ public boolean isMutable(); }
package com.travelsky.hibernate.po; import java.io.Serializable; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; import java.util.ArrayList; import java.util.List; import org.apache.commons.lang.StringUtils; import org.hibernate.HibernateException; import org.hibernate.Hibernate; /** * 必须得引用java.io.Serializable,UserType是反序列化 * 另外,我使用的hibernate版本是3.2,UserType从2.0到3.2有很大的差异,应该多多看看官方的doc * * @author @家军.严重注意org.hibernate.usertype.UserType,不要自己造车呀. * */ public class EmailList implements java.io.Serializable,org.hibernate.usertype.UserType{ private List emails; private static final String SPLITTER = ";"; private static final int[] TYPES = new int[] { Types.VARCHAR }; public int[] sqlTypes() { return TYPES; } public Class returnedClass() { // TODO Auto-generated method stub return List.class; } public boolean equals(Object x, Object y) throws HibernateException { if (x == y) return true; if (x != null && y != null) { List xList = (List) x; List yList = (List) y; if (xList.size() != yList.size()) return false; for (int i = 0; i < xList.size(); i++) { String str1 = (String) xList.get(i); String str2 = (String) yList.get(i); if (!str1.equals(str2)) return false; } return true; } return false; } public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException { String value = (String) Hibernate.STRING.nullSafeGet(rs, names[0]); if (value != null) { return parse(value); } else { return null; } } public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException { System.out.println("Set method excecuted"); if (value != null) { String str = assemble((List) value); Hibernate.STRING.nullSafeSet(st, str, index); } else { Hibernate.STRING.nullSafeSet(st, value, index); } } public Object deepCopy(Object value) throws HibernateException { List sourcelist = (List) value; List targetlist = new ArrayList(); targetlist.addAll(sourcelist); return targetlist; } public boolean isMutable() { return false; } private String assemble(List emailList) { StringBuffer strBuf = new StringBuffer(); for (int i = 0; i < emailList.size() - 1; i++) { strBuf.append(emailList.get(i)).append(SPLITTER); } strBuf.append(emailList.get(emailList.size() - 1)); return strBuf.toString(); } private List parse(String value) { String[] strs = StringUtils.split(value, SPLITTER); List emailList = new ArrayList(); for (int i = 0; i < strs.length; i++) { emailList.add(strs[i]); } return emailList; } public Object assemble(Serializable arg0, Object arg1) throws HibernateException { // TODO Auto-generated method stub return null; } public Serializable disassemble(Object arg0) throws HibernateException { // TODO Auto-generated method stub return null; } public int hashCode(Object arg0) throws HibernateException { // TODO Auto-generated method stub return 0; } public Object replace(Object arg0, Object arg1, Object arg2) throws HibernateException { // TODO Auto-generated method stub return null; } }