在经历自己的不良自定义类型解决方案后 这次就老老实实的实现了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>