对需要解决的问题的描述:
把一个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