UserType and CompositeUserType为
Hibernate中提供的用户类型自定义接口。根据这个接口,可以实现自定义的数据类型。
最近看<<深入浅出
Hibernate>>,作者在书中介绍了
Hibernate 提供的用户自定义数据类型,于是效仿书中的方法,在数据库表中添加一个字段用于记录所有好友的userid,每个userid之间用";"加以分隔,同时将该字段映射为一个特殊的List集合,利用UserType interface实现String解析后将各个userid封装在List中,将List中的记录封装成以";"分隔的String。
使用UserType接口,实现了较好的设计风格,以及更好的重用性。
/*
* 用户自定义的数据类型,对应数据库中的一个字段,在该字段中,保存了
* 多个用户需要的信息,之间用";"加以分隔.
* @Author:Paul
* @Date:April 18th,2008
*/
package com.globalhands.
hibernate.userTypes;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.sql.Types;
import org.
hibernate.
Hibernate;
import org.
hibernate.HibernateException;
import org.
hibernate.usertype.UserType;
public class SpecialList implements UserType {
private List specialList;
private static final char SPLITTER = ';';
private static final int[] TYPES = new int[] { Types.VARCHAR };
public String assemble(Serializable arg0, Object arg1)
throws HibernateException {
return null;
}
/*
* 将List封装为一个String对象
*/
public String assemble(List specialList) throws HibernateException {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < specialList.size() - 1; i++) {
sb.append(specialList.get(i)).append(this.SPLITTER);
}
sb.append(specialList.get(specialList.size() - 1));
return sb.toString();
}
/*
* 创建一个新的List实例,包含原有的List实例中的所有元素.
*/
public Object deepCopy(Object value) throws HibernateException {
List sourceList = (List) value;
List targetList = new ArrayList();
targetList.addAll(sourceList);
return targetList;
}
public Serializable disassemble(Object arg0) throws HibernateException {
return null;
}
/*
* 判断specialList是否发生变化
*/
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() - 1; i++) {
String str1 = (String) xList.get(i);
String str2 = (String) yList.get(i);
if (!xList.equals(yList)) {
return false;
}
}
return true;
}
return false;
}
public int hashCode(Object arg0) throws HibernateException {
return 0;
}
public boolean isMutable() {
return false;
}
/*
* 从resultset中取出email字段,并将其解析为List类型后返回
*/
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;
}
}
/*
* 将以";"分隔的字符串解析为一个字符串数组
*/
private List parse(String value) {
String[] strs = value.split(";");
List specialList = new ArrayList();
for (int i = 0; i <= strs.length - 1; i++) {
specialList.add(strs[i]);
}
return specialList;
}
/*
* 将List型的email信息组装成字符串之后保存到email字段
*/
public void nullSafeSet(PreparedStatement st, Object value, int index)
throws HibernateException, SQLException {
if (value != null) {
String str = assemble((List) value);
Hibernate.STRING.nullSafeSet(st, str, index);
} else {
Hibernate.STRING.nullSafeSet(st, value, index);
}
}
public Object replace(Object arg0, Object arg1, Object arg2)
throws HibernateException {
return null;
}
public Class returnedClass() {
return List.class;
}
public int[] sqlTypes() {
return TYPES;
}
}
同时,修改相应的[ormapping_filename].hbm.xml中相应字段的映射信息
<property name="buddy"
type="com.globalhands.hibernate.userTypes.SpecialList">
<column name="buddy" length="2000" not-null="true" />
</property>
之后,修改POJO类中该字段的返回类型为List。
使用JUnit测试程序。
posted @
2009-05-24 19:57 lanxin1020 阅读(576) |
评论 (0) |
编辑 收藏