• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    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, stopping 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 component values, it might make sense to recursively replace component 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="com.alpha.hibernate.GenderUserType"> 
        property name="gender" type="Gender"> 
            column name="GENDER" not-null="true"> 
            /column> 
        /property> 
    

    延伸:

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

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

    public abstract class OrdinalEnumUserTypeE extends EnumE>> implements UserType {  
     
      protected ClassE> clazz; 
       
      protected OrdinalEnumUserType(ClassE> 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);  
      }  
    } 
    

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

    您可能感兴趣的文章:
    • JS 对象属性相关(检查属性、枚举属性等)
    • JavaScript枚举选择jquery插件代码实例
    • JavaScript enum枚举类型定义及使用方法
    • Node.JS枚举统计当前文件夹和子目录下所有代码文件行数
    • 深入剖析JavaScript中的枚举功能
    • javascript实现Emrips反质数枚举的示例代码
    • JavaScript学习笔记整理_简单实现枚举类型,扑克牌应用
    • 通过实例解析js可枚举属性与不可枚举属性
    上一篇:Hibernate使用中防止SQL注入的几种方案
    下一篇:JSP 中Spring的Resource类读写中文Properties实例代码
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    JSP 中Hibernate实现映射枚举类型 JSP,中,Hibernate,实现,映射,