在经历自己的不良自定义类型解决方案后 这次就老老实实的实现了UserType接口
参考的网上的部分实例,发现很多同志都是从一个范例的演变过来的,都还是新手写的(虽然我也是新手哈),存在一些问题,
不多说了,看看我的实现吧
实现了一个Set<String>类型
package com.heypig.db.hibernate.myType;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.HashSet;
import java.util.Set;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;
public class SetString implements UserType {
/**
*
* 在Hibernate中使用自定义类型需要实现org.hibernate.usertype.UserType接口,主要实现接口中的sqlTypes()、returnedClass()、isMutable()、equals()、deepCopy()、nullSafeGet()及nullSafeSet()方法。
*
* int[] sqlTypes()方法要求返回自定义数据所在数据库字段的类型。类型通过java.sql.Types的类型常量来取得。
*
* Class
* returnedClass()方法要求返回自定义数据在程序中的类型。如某自定义类型要将字符串转换成List,则这里返回List.class。
*
* boolean isMutable()方法要求返回一个Boolean值,说明为本类型实例是否可变。注:不明白,默认为false。
*
* Object deepCopy(Object
* obj)方法要求返回一个自定义类型的完全复制对象。说明:当nullSafeGet方法调用之后,我们获得自定义数据对象,在向用户返回自定义数据之前,deepCopy方法将被调用,它将根据自定义数据对象构造一个完全拷贝,并将此拷贝返回给用户使用。
*
* Object nullSafeGet(ResultSet rs, String[] names,Object
* owner)在从ResultSet中读取标记为自定义类型的数据时,会调用本方法。一般都是在本方法中将数据库中数据转换为自定义类型数据。注:names数组中存放着本自定义类型所代表的列的列名。(一个自定义类型可以在多个列使用,所以这里用的是数组
* 下面加以说明)
*
* nullSafeSet(PreparedStatement ps, Object value, int
* index)在PreparedStatement执行之前会调用本方法。一般都是在本方法中将自定义类型数据转换成数据库中的数据类型。
*
* nullSafeGet()和nullSafeSet()方法其实像一个拦截器,在执行java<->数据库的操作之前将操作拦截下来,并将自定义数据转换成所需类型。
* nullSafeGet()是先通过org.hibernate.Hibernate.XXXType.nullSafeGet()方法来取得数据,然后将数据转换成自定义类型并通过return将其返回。
*
* nullSafeSet()是将自定义类型转换成数据库表中规定的类型,再通过org.hibernate.Hibernate.XXXType.nullSafeSet()方法将数据传入操作流。
*
*
*
*/
private static final String SPILTTER = ",";
private static final int[] TYPES = new int[] { Types.VARCHAR };
public Object assemble(Serializable cached, Object owner)
throws HibernateException {
if (cached == null) {
return null;
} else {
return deepCopy(owner);
}
}
public Object deepCopy(Object value) throws HibernateException {
Set<String> stringSet = (Set<String>) value;
if (stringSet==null) {
return null;
}
Set<String> stringSetCopy = new HashSet<String>();
for (String string : stringSet) {
String stringCopy = new String(string);
stringSetCopy.add(stringCopy);
}
return stringSetCopy;
}
public Serializable disassemble(Object value) throws HibernateException {
return null;
}
public boolean equals(Object x, Object y) throws HibernateException {
Set<String> sx = (Set<String>) x;
Set<String> sy = (Set<String>) y;
if (sx==null) {
return false;
}
if (sx.equals(sy)) {
return true;
}
return false;
}
public int hashCode(Object x) throws HibernateException {
return ((Set<String>) x).hashCode();
}
public boolean isMutable() {
// TODO Auto-generated method stub
return false;
}
public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
throws HibernateException, SQLException {
String stringFromDb = (String) Hibernate.STRING.nullSafeGet(rs,
names[0]);
String[] strings = stringFromDb.split(SPILTTER);
Set<String> set = new HashSet<String>();
for (String s : strings) {
set.add(s);
}
return set;
}
public void nullSafeSet(PreparedStatement st, Object value, int index)
throws HibernateException, SQLException {
if (value != null) {
Set<String> setString = (Set<String>) value;
String stringToDb = "";
for (String s : setString) {
stringToDb += (s + SPILTTER);
}
Hibernate.STRING.nullSafeSet(st, stringToDb, index);
} else {
Hibernate.STRING.nullSafeSet(st, value, index);
}
}
public Object replace(Object original, Object target, Object owner)
throws HibernateException {
// TODO Auto-generated method stub
return null;
}
public Class returnedClass() {
return Set.class;
}
public int[] sqlTypes() {
return TYPES;
}
}
在xml映射里比普通类型的映射加一句type就ok了
如
<property name="newsCategorySet" type="com.heypig.db.hibernate.myType.SetString"></property>