Hibernate中使用枚举Enum自定义字段,hibernateenum,Enum类型的字段进行h
分享于 点击 38472 次 点评:226
Hibernate中使用枚举Enum自定义字段,hibernateenum,Enum类型的字段进行h
Enum类型的字段进行hibernate持久化时,常见的是使用@Enumerated(EnumType.ORDINAL)或EnumType.STRING方式,这里不再描述。当你的Enum中有自定义字段,并且你希望用该字段作为hibernate持久化的值的时候,就需要用到hibernate的自定义映射类型UserType。
持久化枚举接口
import java.util.Map;/** * 需要持久化的enum类,都需要实现的接口 * * @author weichao * */public interface PersistEnum<E extends Enum<?>> { /** * 获取被持久化字段的值 * * @return 被持久化字段的值 */ String getPersistedValue(); /** * 由被持久化的字段的值获取枚举类型 * * @param persistedValue * @return */ E returnEnum(String persistedValue); /** * 获取枚举的所有枚举项 * * @return map */ Map<String, E> getAllValueMap();}
自定义hibernate映射类型
import java.io.Serializable;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Types;import java.util.Properties;import org.hibernate.HibernateException;import org.hibernate.usertype.ParameterizedType;import org.hibernate.usertype.UserType;import org.springframework.util.ObjectUtils;/** * 用户持久化枚举类型的用户自定义hibernate映射类型 * * <p> * 使用此类型来进行映射的枚举类,必须实现{@link com.lwei.common.PersistEnum} 接口 * @author weichao * */public class TopEnumType implements UserType, ParameterizedType { private Method returnEnum; private Method getPersistedValue; private Class<Enum<?>> enumClass; private Object enumObject; /** * This method uses the parameter values passed during enum mapping * definition and sets corresponding properties defined */ @SuppressWarnings("unchecked") public void setParameterValues(Properties parameters) { if (parameters != null) { try { enumClass = (Class<Enum<?>>) Class.forName(parameters.get("enumClass").toString()); enumObject = enumClass.getEnumConstants()[0]; getPersistedValue = enumClass.getMethod("getPersistedValue"); returnEnum = enumClass.getMethod("returnEnum", new Class[] { String.class }); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } } /** * This method maps the database mapping */ public int[] sqlTypes() { return new int[] { Types.VARCHAR }; } /** * This method maps the class for which user type is created */ public Class<?> returnedClass() { return enumClass; } public boolean equals(Object x, Object y) throws HibernateException { return ObjectUtils.nullSafeEquals(x, y); } /** * Fetch the hash code */ public int hashCode(Object x) throws HibernateException { return x.hashCode(); } /** * Recreate the enum from the resultset */ public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException { String value = rs.getString(names[0]); Object returnVal = null; if (value == null) return null; else { try { returnVal = returnEnum .invoke(enumObject, new Object[] { value }); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } return returnVal; } /** * Fetch the data from enum and set it in prepared statement */ public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException { String prepStmtVal = null; if (value == null) { st.setObject(index, null); } else { try { prepStmtVal = getPersistedValue.invoke(value).toString(); st.setString(index, prepStmtVal); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } } /** * Deep copy method */ public Object deepCopy(Object value) throws HibernateException { return value; } public boolean isMutable() { return false; } public Serializable disassemble(Object value) throws HibernateException { Object deepCopy = deepCopy(value); if (!(deepCopy instanceof Serializable)) return (Serializable) deepCopy; return null; } public Object assemble(Serializable cached, Object owner) throws HibernateException { return deepCopy(cached); } public Object replace(Object original, Object target, Object owner) throws HibernateException { return deepCopy(original); }}
一个实现了持久化枚举接口的枚举类
import java.util.Map;import java.util.TreeMap;import com.lwei.common.TopEnum;public enum OrganType implements PersistEnum<OrganType>{ // 利用构造函数传参 ORGANTYPE_DEPARTMENT("D"), // 部门 ORGANTYPE_ORGANMANAGER("M"), // 管理机构 ORGANTYPE_NONE("N"); //普通机构 无特殊含意的机构,类似企业中的总公司和分支机构,只有上下级关系。 private static final Map<String, OrganType> map = new TreeMap<String, OrganType>(); static { map.put(ORGANTYPE_DEPARTMENT.getOrgType(), ORGANTYPE_DEPARTMENT); map.put(ORGANTYPE_ORGANMANAGER.getOrgType(), ORGANTYPE_ORGANMANAGER); map.put(ORGANTYPE_NONE.getOrgType(), ORGANTYPE_NONE); } // 定义私有变量 private String orgType ; // 构造函数,枚举类型只能为私有 private OrganType(String _orgType) { this . orgType = _orgType; } public String getOrgType() { return orgType; } @Override public String getPersistedValue() { return getOrgType(); } @Override public OrganType returnEnum(String persistedValue) { return map.get(persistedValue); } @Override public Map<String, OrganType> getAllValueMap() { return map; } }
在持久化对象中定义枚举字段映射
@Column(name = "organType", nullable = false, length = 1) @Type(type="com.lwei.persistence.TopEnumType", parameters={@Parameter(name="enumClass",value="com.lwei.org.domain.entities.OrganType")}) private OrganType organType;
用户点评