读书人

扩张Hibernate对Enum的支持

发布时间: 2012-11-17 11:14:16 作者: rapoo

扩展Hibernate对Enum的支持
最近项目中,用实体与枚举关联,一直觉得这种方式比较不错,有幸在项目中用到并扩展。

1.持久化枚举接口

package org.lop.modules.orm.hibernate.type;import java.util.Map;/** * 自定义Hibernate持久化枚举接口.<br> * 实体需要用枚举关联, 枚举必须实现该接口. *  * <pre> * 实体映射eg. * <code>@Column( name = "COLUMN_NAME" )</code> * <code>@Type( type = CustomEnumType.ENUM_TYPE,</code> * <code>  parameters = { @Parameter( name = "enumClass", value = "xxx.xxx.WorkDayType" ) } )</code> * </pre> *  * @author 丁当 * @date 2012-11-02 */public interface PersistentEnum<E extends Enum<?>, T> {T getValue();String getDisplayName();E getEnum( T value );Map<T, E> getAllValueMap();}


2.扩展Hibernate对Enumd 支持
package org.lop.modules.orm.hibernate.type;import java.io.Serializable;import java.lang.reflect.InvocationTargetException;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Types;import java.util.Properties;import org.apache.commons.beanutils.MethodUtils;import org.hibernate.HibernateException;import org.hibernate.engine.spi.SessionImplementor;import org.hibernate.internal.CoreMessageLogger;import org.hibernate.internal.util.ReflectHelper;import org.hibernate.internal.util.compare.EqualsHelper;import org.hibernate.type.EnumType;import org.hibernate.usertype.ParameterizedType;import org.hibernate.usertype.UserType;import org.jboss.logging.Logger;import com.ylink.ylpay.common.project.mp.constant.WorkDayType;/** * 自定义Hibernate对Enum的持久化.<br> * 支持Enum的value为Number或String, 但Enum必须实现PersistentEnum接口. *  * @author 丁当 * @date 2012-11-02 */@SuppressWarnings( "serial" )public class CustomEnumType implements UserType, ParameterizedType, Serializable {private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, CustomEnumType.class.getName() );public static final String ENUM_TYPE = "org.lop.modules.orm.hibernate.type.CustomEnumType";private static final String GETENUM_METHOD_NAME = "getEnum";private static final String GETVALUE_METHOD_NAME = "getValue";private Class<Enum<?>> enumClass;private Object enumObject;private int sqlType = Types.VARCHAR;@Override@SuppressWarnings( "unchecked" )public void setParameterValues( Properties parameters ) {if ( null != parameters ) {String enumClassName = parameters.getProperty( EnumType.ENUM );try {enumClass = ReflectHelper.classForName( enumClassName, this.getClass() ).asSubclass( Enum.class );enumObject = enumClass.getEnumConstants()[ 0 ];} catch ( ClassNotFoundException exception ) {throw new HibernateException( "Enum class not found", exception );}}}@Overridepublic Object nullSafeGet( ResultSet rs, String[] names, SessionImplementor session, Object owner ) throws HibernateException,SQLException {Object param = rs.getObject( names[ 0 ] );Object returnVal = null;if ( rs.wasNull() ) {if ( LOG.isTraceEnabled() )LOG.tracev( "Returning null as column {0}", names[ 0 ] );return null;}try {/* 转换参数类型. */if ( param instanceof Number ) {returnVal = MethodUtils.invokeMethod( enumObject, GETENUM_METHOD_NAME, ( ( Number ) param ).intValue() );} else {returnVal = MethodUtils.invokeMethod( enumObject, GETENUM_METHOD_NAME, param );}} catch ( NoSuchMethodException e ) {e.printStackTrace();} catch ( IllegalAccessException e ) {throw new IllegalArgumentException( "Unknown name value for enum " + enumClass + ": " + param, e );} catch ( InvocationTargetException e ) {e.printStackTrace();}return returnVal;}@Overridepublic void nullSafeSet( PreparedStatement st, Object value, int index, SessionImplementor session ) throws HibernateException,SQLException {if ( value == null ) {if ( LOG.isTraceEnabled() )LOG.tracev( "Binding null to parameter: {0}", index );st.setNull( index, sqlType );}Object enumVal = null;try {enumVal = MethodUtils.invokeMethod( value, GETVALUE_METHOD_NAME, null );if ( enumVal instanceof Number ) {sqlType = Types.INTEGER;}st.setObject( index, enumVal, sqlType );} catch ( NoSuchMethodException e ) {e.printStackTrace();} catch ( IllegalAccessException e ) {e.printStackTrace();} catch ( InvocationTargetException e ) {e.printStackTrace();}}@Overridepublic int[] sqlTypes() {return new int[] { sqlType };}@Override@SuppressWarnings( "rawtypes" )public Class returnedClass() {return enumClass;}@Overridepublic boolean equals( Object x, Object y ) throws HibernateException {return EqualsHelper.equals( x, y );}@Overridepublic int hashCode( Object x ) throws HibernateException {return x.hashCode();}@Overridepublic Object deepCopy( Object value ) throws HibernateException {return value;}@Overridepublic boolean isMutable() {return false;}@Overridepublic Serializable disassemble( Object value ) throws HibernateException {return ( Serializable ) value;}@Overridepublic Object assemble( Serializable cached, Object owner ) throws HibernateException {return cached;}@Overridepublic Object replace( Object original, Object target, Object owner ) throws HibernateException {return original;}}


3.eg.Enum
package org.lop.xxx.xxx;import java.util.HashMap;import java.util.Map;import org.lop.modules.orm.hibernate.type.PersistentEnum;/** * 商户类型. *  * @author 丁当 * @date 2012-11-01 */public enum CustType implements PersistentEnum<CustType, String> {FUND( "FUND", "基金" ),WINE( "WINE", "白酒" ),MALL( "MALL", "商城" ),OTHER( "OTHER", "其它" );private String value;private final String displayName;private static Map<String, CustType> valueMap = new HashMap<String, CustType>();static {for ( CustType _enum : CustType.values() ) {valueMap.put( _enum.value, _enum );}}CustType( String value, String displayName ) {this.value = value;this.displayName = displayName;}public String getValue() {return value;}public String getDisplayName() {return displayName;}@Overridepublic CustType getEnum( String value ) {return valueMap.get( value );}@Overridepublic Map<String, CustType> getAllValueMap() {return valueMap;}@Overridepublic String toString() {return this.getDisplayName();}}


4.eg.Entity
/** 类型. */@Column( name = "TYPE" )@Type( type = CustomEnumType.ENUM_TYPE, parameters = { @Parameter( name = "enumClass", value = "org.lop.xxx.CustType" ) } )private CustType type;




欢迎各位指教!望出差一趟,家里平安,想家了!!!

读书人网 >软件架构设计

热点推荐