JSP 中Hibernate实现映射枚举类型

网络编程 2021-07-05 11:23www.168986.cn编程入门
这篇文章主要介绍了JSP 中Hibernate实现映射枚举类型的相关资料,需要的朋友可以参考下

JSP 中Hibernate实现映射枚举类型

问题

Java BO类Gender是枚举类型,想在数据库中存成字符串格式,如何编写hbm.xml?

public enum Gender{  
 UNKNOWN("Unknown"),  
 MALE("Male"),  
 FEMALE("Female"); 
   
 private String key; 
 private Gender(final String key) { 
  this.key = key; 
 } 
 public getGender(String key) { 
  for (Gender gender : Gender.values()) { 
   if (key.euqals(gender.getKey())) 
    return gender;       
  } 
  throw new NoSuchElementException(key); 
 } 
} 

使用UserType

public class GenderUserType implements UserType {  
 
  private static int[] typeList = { Types.VARCHAR};  
 
 / 
   Return the SQL type codes for the columns mapped by this type. 
   The codes are defined on <tt>java.sql.Types</tt>. / 
 /设置和Gender类的sex属性对应的字段的SQL类型 /  
 public int[] sqlTypes() { 
   return typeList; 
 } 
 
 /The class returned by <tt>nullSafeGet()</tt>./ 
 / 设置GenderUserType所映射的Java类Gender类 / 
 public Class returnedClass() { 
   return Gender.class;  
 }  
 
 / 指明Gender类是不可变类 /  
 public boolean isMutable() { 
   return false; 
 } 
 
 / 
  Return a deep copy of the persistent state, sping at entities and at 
  collections. It is not necessary to copy immutable objects, or null 
  values, in which case it is safe to simply return the argument. 
 / 
 / 返回Gender对象的快照,由于Gender类是不可变类, 直接将参数代表的Gender对象返回 /  
 public Object deepCopy(Object value) {  
  return (Gender)value;  
 }  
 
 / 比较一个Gender对象是否和它的快照相同 / 
 public boolean equals(Object x, Object y) { 
  //由于内存中只可能有两个静态常量Gender实例,  
  //可以直接按内存地址比较  
  return (x == y);  
 }  
 public int hashCode(Object x){  
   return x.hashCode();  
 }  
 
 / 
  Retrieve an instance of the mapped class from a JDBC resultset. Implementors 
  should handle possibility of null values. 
 / 
 / 从JDBC ResultSet中读取key,然后返回相应的Gender实例 / 
 public Object nullSafeGet(ResultSet rs, String[] names, Object owner) 
               throws HibernateException, SQLException{  
   //从ResultSet中读取key 
   String sex = (String) Hibernate.STRING.nullSafeGet(rs, names[0]);  
   if (sex == null) { return null; }  
   //按照性别查找匹配的Gender实例  
   try {  
    return Gender.getGender(sex);  
   }catch (java.util.NoSuchElementException e) {  
    throw new HibernateException("Bad Gender value: " + sex, e);  
   }  
 } 
 
 / 
  Write an instance of the mapped class to a prepared statement. Implementors 
  should handle possibility of null values. 
  A multi-column type should be written to parameters starting from <tt>index</tt>. 
 / 
 / 把Gender对象的key属性添加到JDBC PreparedStatement中 / 
 public void nullSafeSet(PreparedStatement st, Object value, int index)  
                throws HibernateException, SQLException{  
  String sex = null;  
  if (value != null)  
    sex = ((Gender)value).getKey();  
  Hibernate.String.nullSafeSet(st, sex, index);  
 }  
 
 / 
  Reconstruct an object from the cacheable representation. At the very least this 
  method should perform a deep copy if the type is mutable. (optional operation) 
 / 
 public Object assemble(Serializable cached, Object owner){ 
   return cached; 
 }  
  
 / 
    Transform the object into its cacheable representation. At the very least this 
    method should perform a deep copy if the type is mutable. That may not be enough 
    for some implementations, however; for example, associations must be cached as 
    identifier values. (optional operation) 
  / 
  public Serializable disassemble(Object value) { 
     return (Serializable)value;  
  }  
 
 / 
  During merge, replace the existing (target) value in the entity we are merging to 
  with a new (original) value from the detached entity we are merging. For immutable 
  objects, or null values, it is safe to simply return the first parameter. For 
  mutable objects, it is safe to return a copy of the first parameter. For objects 
  with ponent values, it might make sense to recursively replace ponent values. 
 / 
 public Object replace(Object original, Object target, Object owner){ 
    return original;  
 }  
} 

然后再hbm.xml中定义映射关系

<hibernate-mapping package="" default-lazy="true" default-cascade="save-update,merge,persist"> 
  <typedef name="Gender" class=".alpha.hibernate.GenderUserType"> 
    <property name="gender" type="Gender"> 
        <column name="GENDER" not-null="true"> 
        </column> 
    </property> 

延伸

为每个枚举类型定义一个UserType是比较麻烦的,可以定义一个抽象类。

例如扩展下例即可适用于所有保存为index的枚举类型

public abstract class OrdinalEnumUserType<E extends Enum<E>> implements UserType {  
 
  protected Class<E> clazz; 
   
  protected OrdinalEnumUserType(Class<E> clazz) { 
    this.clazz = clazz; 
  }  
  
  private static final int[] SQL_TYPES = {Types.NUMERIC};  
  public int[] sqlTypes() {  
    return SQL_TYPES;  
  }  
  
  public Class<?> returnedClass() {  
    return clazz;  
  }  
  
  public E nullSafeGet(ResultSet resultSet, String[] names, Object owner)  
               throws HibernateException, SQLException {     
 
    //Hibernate.STRING.nullSafeGet(rs, names[0]) 
    int index = resultSet.getInt(names[0]); 
    E result = null;  
    if (!resultSet.wasNull()) {  
      result = clazz.getEnumConstants()[index];  
    }  
    return result;  
  }  
  
  public void nullSafeSet(PreparedStatement preparedStatement, 
     Object value,int index) throws HibernateException, SQLException {  
    if (null == value) {  
      preparedStatement.setNull(index, Types.NUMERIC);  
    } else {  
      //Hibernate.String.nullSafeSet(st, sex, index); 
      preparedStatement.setInt(index, ((E)value).ordinal());  
    }  
  }  
  
  public Object deepCopy(Object value) throws HibernateException{  
    return value;  
  }  
  
  public boolean isMutable() {  
    return false;  
  }  
  
  public Object assemble(Serializable cached, Object owner)  
throws HibernateException { 
     return cached; 
  }  
 
  public Serializable disassemble(Object value) throws HibernateException {  
    return (Serializable)value;  
  }  
  
  public Object replace(Object original, Object target, Object owner) 
throws HibernateException {  
    return original;  
  }  
  public int hashCode(Object x) throws HibernateException {  
    return x.hashCode();  
  }  
  public boolean equals(Object x, Object y) throws HibernateException {  
    if (x == y)  
      return true;  
    if (null == x || null == y)  
      return false;  
    return x.equals(y);  
  }  
} 

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

Copyright © 2016-2025 www.168986.cn 狼蚁网络 版权所有 Power by