http://www.hibernate.org/282.html
在该文最下面的有一小段文字,其中写道:
With UserType s, also specify the sql-type. In xdoclet , we map user types this way
@hibernate.property type = "com.pfn.wirepower.srv.persistence.userTypes.OurCustomUserType"
@hibernate.column name = "CustomObjectCol" sql-type="VARCHAR(50)"
/** 缩略图列表,按fileName1.xxx;fileName2.xxx;fileName3.xxx;... */
private Map<String, String> fileNames;
/**
* @hibernate.property type="com.sunsci.material.ext.hibernate.MapType"
* @hibernate.column name="fileNames" sql-type="text"
* @return
*/
public Map<String, String> getFileNames() {
return fileNames;
}
public void setFileNames(Map<String, String> fileNames) {
this.fileNames = fileNames;
}
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 org.apache.commons.lang.StringUtils;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;
public class ListType implements UserType {
private static final String SPLITTER = ";";
private static final int[] TYPES = new int[] { Types.VARCHAR };
public Object assemble(Serializable serializable, Object object)
throws HibernateException {
return deepCopy(serializable);
}
public Object deepCopy(Object object) throws HibernateException {
List sourceSet = (List) object;
List targetSet = new ArrayList();
if (sourceSet != null) {
targetSet.addAll(sourceSet);
}
return targetSet;
}
public Serializable disassemble(Object object) throws HibernateException {
return (Serializable) deepCopy(object);
}
public boolean equals(Object one, Object other) throws HibernateException {
if (one == other) {// 如果两个对象的指针是指向同一位置。
return true;
}
if (one != null && other != null) {
List set0 = (List) one;
List set1 = (List) other;
if (set0.size() != set1.size()) {// 如果列表的长度不相等
return false;
}
Object[] s0 = set0.toArray();
Object[] s1 = set1.toArray();
if (s0.length != s1.length) {// 如果列表的长度不相等
return false;
}
for (int i = 0; i < s0.length; i++) {
Object id0 = s0[i];
Object id1 = s1[i];
if (!id0.equals(id1)) {// 如果在列表中相同位置上的对象不相等
return false;
}
}
return true;
}
return false;
}
public int hashCode(Object object) throws HibernateException {
List s = (List) object;
return s.hashCode();
}
public boolean isMutable() {
return false;
}
public Object nullSafeGet(ResultSet resultSet, String[] stringArray,
Object object) throws HibernateException, SQLException {
String value = (String) Hibernate.STRING.nullSafeGet(resultSet,
stringArray[0]);
if (value != null) {
return parse(value);
} else {
return new ArrayList();
}
}
private List parse(String value) {
String[] strs = StringUtils.split(value, SPLITTER);
List set = new ArrayList();
for (int i = 0; i < strs.length; i++) {
if (StringUtils.isNotBlank(strs[i])) {
set.add(strs[i]);
// set.add(new Long(Long.parseLong(strs[i])));
}
}
return set;
}
public void nullSafeSet(PreparedStatement preparedStatement, Object object,
int _int) throws HibernateException, SQLException {
if (object != null) {
String str = assemble((List) object);
Hibernate.STRING.nullSafeSet(preparedStatement, str, _int);
} else {
Hibernate.STRING.nullSafeSet(preparedStatement, "", _int);
}
}
private String assemble(List set) {
StringBuffer sb = new StringBuffer();
Iterator it = set.iterator();
while (it.hasNext()) {
sb.append(it.next());
sb.append(SPLITTER);
}
String fs = sb.toString();
if (fs != null && fs.length() > 0 && fs.endsWith(SPLITTER)) {
fs = fs.substring(0, fs.length() - 1);
}
return fs;
}
public Object replace(Object object, Object object1, Object object2)
throws HibernateException {
return object;
}
public Class returnedClass() {
return List.class;
}
public int[] sqlTypes() {
return TYPES;
}
}
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.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.collections.map.LinkedMap;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;
/**
* @author linzq
*
*/
public class MapType implements UserType, Serializable {
private static final long serialVersionUID = -8041009346154850427L;
public MapType() {
super();
}
public MapType(Map attributeMap) {
super();
this.attributeMap = attributeMap;
}
private Map attributeMap;
public static final String SPLITTER = ";";
public static final String SEPARATOR = ":";
public static final String VALUE_BREAK = ",";
public static final char BRACKET_LEFT = '{';
public static final char BRACKET_RIGHT = '}';
public static final int[] SQLTYPES = new int[] { Types.VARCHAR};
public boolean isMutable() {
return false;
}
public int[] sqlTypes() {
return SQLTYPES;
}
public Object assemble(Serializable id, Object obj) throws HibernateException {
return null;
}
/**
* 将Map类型的属性拼接成字符串
*
* @param attributeList
* @return
* @throws HibernateException
*/
public Object assemble(Map attributeMap) throws HibernateException {
if (attributeMap == null) {
return null;
}
StringBuffer asbl = new StringBuffer();
Iterator itr = attributeMap.keySet().iterator();
String _key = null;
while (itr.hasNext()) {
_key = (String) itr.next();
asbl.append(SPLITTER).append(BRACKET_LEFT).append(_key).append(SEPARATOR).append(attributeMap.get(_key)).append(BRACKET_RIGHT);
}
return asbl.toString().replaceFirst(SPLITTER, "");
}
/**
* 自定义类型的完全复制方法,返回一个和原自定义数据相同的新对象
*
* @param value
* the object to be cloned, which may be null
* @return Object a copy
* @see org.hibernate.usertype.UserType#deepCopy(java.lang.Object)
*/
public Object deepCopy(Object value) throws HibernateException {
if (value == null) {
return null;
}
Map sourceMap = (Map) value;
Map targetMap = new HashMap();
targetMap.putAll(sourceMap);
return targetMap;
}
/**
* 自定义数据类型的比较方法
*
* @param x
* @param y
* @return boolean
* @see org.hibernate.usertype.UserType#equals(java.lang.Object,
* java.lang.Object)
*/
public boolean equals(Object x, Object y) throws HibernateException {
if (x == y) {
return true;
}
if (x != null && y != null) {
Map xMap = (Map) x;
Map yMap = (Map) y;
if (xMap.size() != yMap.size()) {
return false;
}
List<String> _xList = new ArrayList(xMap.keySet());
List<String> _yList = new ArrayList(xMap.keySet());
Collections.sort(_xList);
Collections.sort(_yList);
for (int i = 0; i < xMap.size(); i++) {
if (!_xList.get(i).equals(_yList.get(i))) {
return false;
}
if (!xMap.get(_xList.get(i)).equals(yMap.get(_yList.get(i)))) {
return false;
}
}
return true;
}
return false;
}
public int hashCode(Object arg0) throws HibernateException {
return attributeMap.hashCode();
}
/**
* 将以格式为{key:value};{key:value1,value2}的字符串数组解析成一个Map
*
* @param value
* @return
*/
public Map parse(String value) {
if (value == null) {
return null;
}
String[] strs = org.apache.commons.lang.StringUtils.split(value.trim(), SPLITTER);
Map attributeMap = new LinkedMap();
String _temp = null;
for (int i = 0; i < strs.length; i++) {
_temp = strs[i].substring(1, strs[i].length() - 1);
attributeMap.put(_temp.split(SEPARATOR, 2)[0], _temp.split(SEPARATOR, 2)[1]);
}
return attributeMap;
}
/**
* 从JDBC的ResultSet中读取数据,并将其转换为自定义类型后返回。 此方法要求对可能出现null的情况做处理。
* names中包含了当前自定义类型的映射字段名称。
*
* @param rs
* a JDBC result set
* @param names
* the column names
* @param owner
* the containing entity
* @return Object
* @throws HibernateException
* @throws SQLException
* @see org.hibernate.usertype.UserType#nullSafeGet(java.sql.ResultSet,
* java.lang.String[], java.lang.Object)
*/
public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
String value = (String) Hibernate.STRING.nullSafeGet(rs, names[0]);
if (value != null) {
attributeMap = parse(value);
return attributeMap;
}
return null;
}
/**
* 在Hibernate进行数据保存时被调用 可以通过PreparedStatement将自定义数据写入对应的数据库字段中
* names中包含了当前自定义类型的映射字段名称。
*
* @param st
* a JDBC prepared statement
* @param value
* the object to write
* @param index
* statement parameter index
* @throws HibernateException
* @throws SQLException
* @see org.hibernate.usertype.UserType#nullSafeGet(java.sql.ResultSet,
* java.lang.String[], java.lang.Object)
*/
public void nullSafeSet(PreparedStatement pst, Object value, int index) throws HibernateException, SQLException {
if (value != null) {
Hibernate.STRING.nullSafeSet(pst, assemble((Map) value), index);
} else {
Hibernate.STRING.nullSafeSet(pst, value, index);
}
}
public Class returnedClass() {
return MapType.class;
}
public Object replace(Object arg0, Object arg1, Object arg2) throws HibernateException {
return null;
}
public Serializable disassemble(Object arg0) throws HibernateException {
return null;
}
public Map getAttributeMap() {
return attributeMap;
}
public void setAttributeMap(Map attributeMap) {
this.attributeMap = attributeMap;
}
}