對需要解決的問題的描述:
把一個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
周銳 閱讀(1797)
評論(0) 編輯 收藏 所屬分類:
Hibernate