根据 SpaceTrucker 关于 Hibernate UserType 的建议,这里是提供 Hibernate 自定义 UserType 所需的完整代码(非常感谢Kunaal A Trehan的博客文章中提供了此类所基于的代码):
package org.mypackage;
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.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.tool.hbm2ddl.SchemaExport.Type;
import org.hibernate.usertype.UserType;
import org.springframework.util.ObjectUtils;
/**
* An Hibernate {@link UserType} that allows persisting a list of integers in one single column in the table.
* Based in code from http://javadata.blogspot.com.ar/2011/07/hibernate-and-user-types.html.
*
* In order to use this as the mapper for a column, use the following in the field of your entity:
* @Type(type=IntegerListUserType.NAME)
* List<Integer> tracks;
*
* @author dds
* */
public class IntegerListUserType implements UserType {
public static final String NAME = "org.mypackage.IntegerListUserType"; //WARNING this must match class name!
@Override
public int[] sqlTypes() {
return new int[] { Types.VARCHAR };
}
@SuppressWarnings("rawtypes")
@Override
public Class returnedClass() {
return List.class;
}
@Override
public boolean equals(Object x, Object y) throws HibernateException {
return ObjectUtils.nullSafeEquals(x, y);
}
@Override
public int hashCode(Object x) throws HibernateException {
if (x != null)
return x.hashCode();
else
return 0;
}
@Override
public Object nullSafeGet(ResultSet rs, String[] names,
SessionImplementor session, Object owner)
throws HibernateException, SQLException {
List<Integer> list = null;
String nameVal = rs.getString(names[0]);
if (nameVal != null) {
list = new ArrayList<Integer>();
StringTokenizer tokenizer = new StringTokenizer(nameVal, ",");
while (tokenizer.hasMoreElements()) {
String number = (String) tokenizer.nextElement();
list.add(Integer.valueOf(number));
}
}
return list;
}
@SuppressWarnings("unchecked")
@Override
public void nullSafeSet(PreparedStatement st, Object value, int index,
SessionImplementor session) throws HibernateException, SQLException {
if (value == null) {
st.setNull(index, Types.VARCHAR);
} else {
st.setString(index, serialize((List<Integer>) value));
}
}
private String serialize(List<Integer> list) {
StringBuilder strbul = new StringBuilder();
Iterator<Integer> iter = list.iterator();
while (iter.hasNext()) {
strbul.append(iter.next());
if (iter.hasNext()) {
strbul.append(",");
}
}
return strbul.toString();
}
@SuppressWarnings("unchecked")
@Override
public Object deepCopy(Object value) throws HibernateException {
if (value == null)
return null;
else {
List<Integer> newObj = new ArrayList<Integer>();
List<Integer> existObj = (List<Integer>) value;
newObj.addAll(existObj);
return newObj;
}
}
@Override
public boolean isMutable() {
return false;
}
@Override
public Serializable disassemble(Object value) throws HibernateException {
Object deepCopy = deepCopy(value);
if (!(deepCopy instanceof Serializable))
return (Serializable) deepCopy;
return null;
}
@Override
public Object assemble(Serializable cached, Object owner)
throws HibernateException {
return deepCopy(cached);
}
@Override
public Object replace(Object original, Object target, Object owner)
throws HibernateException {
return deepCopy(original);
}
}
请注意,为了简单起见,我将 String 转换为 List < Integer > 而不是 int[] 。