posts - 431,  comments - 344,  trackbacks - 0
对需要解决的问题的描述:
把一个enum类型的字段持久化到数据库中,写入到数据库中的值为Integer类型,且有特定的含义:

我们知道,如果我们某一个pojo对象的某个属性为enum类型的话,在持久化的时候可能会出现如下两种情况:
1、数据库中enum_col的类型为(oracle:number或者sql server:numeric)
   @Column(name="enum_col")
   public MyEnum getCol(){
      return this.col;
   }
此种情况下,存到数据库中的数据时col.ordinal()所返回的int数值
2、数据库中enum_col的类型为(oracle:varchar2,或者sql server:varchar)
   @Column(name="enum_col")
   public MyEnum getCol(){
      return this.col;
   }
此种情况下,存储到数据库中的值为定义此enum是所使用的名字如:
   public enum MyEnum{
       DATA1,
       DATA2;
   }
则,如果this.col代表DATA1则写DATA1到数据库中去。
那么我们通过什么样的手段来改变这些呢?如果使用的是hibernate的话可以借助于UserType来实现:
首先、定义一个enum MyEnumData,(在持久化的时候把其code写到数据库中去)
package ec.snow.hib.pojos;
public enum MyEnumData{
   DATA1("data1",100),
   DATA2("data2",200),
   DATA3("data3",300);
   private String name;
   private int code;
  
   public int getCode(){
      return this.code;
   }
   public String getName(){
      return this.name;
   }
   MyEnumData(String name,int code){
      this.name = name;
      this.code = code;
   }
//辅助方法,主要在UserType的实现中通过相应的code得到MyEnumData

public static MyEnumData formCode(int code){

       for(MyEnumData u:MyEnumData.values()){
          if(u.getCode()==code)return u;
       }
       return null;
   }
}
//*******************************
接下来、定义相应的UserType的实现:
package com.snow.hib.pojos;
import Java.io.Serializable;
import Java.sql.PreparedStatement;
import Java.sql.ResultSet;
import Java.sql.SQLException;
import Java.sql.Types;
import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;
/**
 *@author anwxAn Weixiao
 *@version $Id$
 */
public class MyEnumDataType implements UserType {
  
    public int[] sqlTypes() {  
        int[] types = {Types.INTEGER};        
        return types;  
    }  
 
    public Class returnedClass(){
        return UserTitle.class;  
    }  
 
    public boolean equals(Object x, Object y) throws HibernateException {  
        return x == y;  
    }  
 
    public int hashCode(Object x) throws HibernateException {  
        return x.hashCode();  
    }  
 
    public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
throws HibernateException, SQLException {  
        int code = rs.getInt(names[0]);  
        return rs.wasNull() ? null : MyEnumData.formCode(code);//notice code to use   
    }  
 
    public void nullSafeSet(PreparedStatement st, Object value, int index)
throws HibernateException, SQLException {  
        if (value == null) {  
            st.setNull(index, Types.INTEGER);  
        } else {  
            st.setInt(index, ((MyEnumData) value).getCode());  
        }  
    }  
 
    public Object deepCopy(Object value) throws HibernateException {  
        return value;  
    }  
 
    public boolean isMutable() {  
        return false;  
    }  
 
    public Serializable disassemble(Object value) throws HibernateException {  
        return (Serializable) deepCopy(value);  
    }  
 
    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);  
    }    
}
//**********************************
最后、通过自定义的UserType来实现对enum的有效持久化
package com.snow.hib.pojos;
import Java.io.Serializable;
import Javax.persistence.Column;
import Javax.persistence.Entity;
import Javax.persistence.Id;
import Javax.persistence.Table;
import org.hibernate.annotations.Type;
/**
 *@author anwxAn Weixiao
 *@version
 */
@Entity
@Table(name="my_def_type")
public class UseMyEnumData implements Serializable{  
  
    private static final long serialVersionUID = 6905822670746966787L;
    private String id;
    private String username;    
    private MyEnumData enumData;  
   
    @Column(updatable = true,nullable = true,name="MY_TITLE")
    @Type(type="com.snow.hib.pojos.MyEnumDataType")
    public MyEnumData getEnumData() {  
        return enumData;  
    }  
 
    public void setEnumData(MyEnumData data) {  
        this.enumData = data;  
    }
   
    @Column(updatable=true,nullable = true,name="USER_NAME")
    public String getUsername() {  
        return username;  
    } 
    public void setUsername(String username) {  
        this.username = username;  
    }
 /**
  * @return Returns the id.
  */
    @Id
 public String getId() {
  return id;
 }
 /**
  * @param id The id to set.
  */
 public void setId(String id) {
  this.id = id;
 }   
}
下面是测试结果:
//***************************Test result
       UseMyEnumData data = new UseMyEnumData();
          data.setId("123456");
          data.setTitle(MyEnumData.DATA1);
          data.setUsername("chsi:manager");
          manager.saveUseMyEnumData(title);
则数据库中写入的数据为: [123456 100 chsi:manager]


还有一点需要注意的是,如果系统中用来影射enum类型的数据可能有出现空值的时候hibernate在处理影射的时候会
Enum类型影射为null,也就是没有对应的数据,这在处理旧有系统数据的时候会有用处哦…………
posted on 2008-07-01 15:26 周锐 阅读(1778) 评论(0)  编辑  收藏 所属分类: Hibernate

只有注册用户登录后才能发表评论。


网站导航: