扩展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 );
}
}
}

@Override
public 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;
}

@Override
public 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();
}
}

@Override
public int[] sqlTypes() {
return new int[] { sqlType };
}

@Override
@SuppressWarnings( "rawtypes" )
public Class returnedClass() {
return enumClass;
}

@Override
public boolean equals( Object x, Object y ) throws HibernateException {
return EqualsHelper.equals( x, y );
}

@Override
public int hashCode( Object x ) throws HibernateException {
return x.hashCode();
}

@Override
public Object deepCopy( Object value ) throws HibernateException {
return value;
}

@Override
public boolean isMutable() {
return false;
}

@Override
public Serializable disassemble( Object value ) throws HibernateException {
return ( Serializable ) value;
}

@Override
public Object assemble( Serializable cached, Object owner ) throws HibernateException {
return cached;
}

@Override
public 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;
}

@Override
public CustType getEnum( String value ) {
return valueMap.get( value );
}

@Override
public Map<String, CustType> getAllValueMap() {
return valueMap;
}

@Override
public 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;



欢迎各位指教!望出差一趟,家里平安,想家了!!!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值