UserType取代枚举类型

枚举类型是一种常见的Java设计模式.在枚举类型的Java类中,定义了这个类本身是一些静态实例.例1定义了一个Gender类,它包含两个静态常量类型的Gender实例:Gender.FEMALE和Gender.MALE.Gender类有两个属性:sex和description.sex属性代表性别的缩写,可选值'F'和'M';description属性代表性别的完整名字,可选值为"Female"和"MALE".

例1:

package mypack;

import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.NoSuchElementException;

/**
* @author lfm
*
*/
public class Gender implements Serializable {

private final Character sex;

private final transient String description;

public String getDescription() {
return description;
}

public Character getSex() {
return sex;
}

private static final Map instanceBySex = new HashMap();

public Gender(Character sex, String description) {
this.sex = sex;
this.description = description;
instanceBySex.put(sex, description);
}

public static final Gender FEMALE = new Gender(new Character('F'), "Female");

public static final Gender MALE = new Gender(new Character('M'), "Male");

public static Collection getAllValues() {
return Collections.unmodifiableCollection(instanceBySex.values());
}

public static Gender getInstanceBySex(Character sex) {
Gender result = (Gender)instanceBySex.get(sex);
if(result == null)
throw new NoSuchElementException(sex.toString());
return result;
}

public String toString() {
return description;
}

private Object readResolve() {
return getInstanceBySex(sex);
}
}

当业务类型中有一些固定的常量数据,就可以用枚举类型的类来实现.枚举类型的优点在于节省内存空间.以Gender类为例,当程序运行后,在内存中只可能有两个Gender实例:Gender.FEMALE和Gender.MALE.Gender类封装了构造方法,不允许外部程序构造Gender实例.

假定在Customer类中有一个Gender类型的gender属性,在CUSTOMERS表中有一个CHAR(1)类型的GENDER字段,可选值为'F'和'M'.可以创建一个GenderUserType类,它负责把持久化类的Gender类型的属性映射到数据库中CHAR(1)类型的字段.例2是GenderUserType类的源程序.

例2:

package mypack;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.NoSuchElementException;

import net.sf.hibernate.Hibernate;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.UserType;

/**
* @author lfm
*
*/
public class GenderUserType implements UserType {

/* (非 Javadoc)
* @see net.sf.hibernate.UserType#sqlTypes()
*/
public int[] sqlTypes() {
// TODO 自动生成方法存根
return new int[]{Types.CHAR};
}

/* (非 Javadoc)
* @see net.sf.hibernate.UserType#returnedClass()
*/
public Class returnedClass() {
// TODO 自动生成方法存根
return Gender.class;
}

/* (非 Javadoc)
* @see net.sf.hibernate.UserType#equals(java.lang.Object, java.lang.Object)
*/
public boolean equals(Object x, Object y) throws HibernateException {
// TODO 自动生成方法存根
//由于内存中只可能有两个静态常量Gender实例,因此可以直接按内存地址比较
return x == y;
}

/* (非 Javadoc)
* @see net.sf.hibernate.UserType#nullSafeGet(java.sql.ResultSet, java.lang.String[], java.lang.Object)
*/
public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
throws HibernateException, SQLException {
// TODO 自动生成方法存根
Character sex = (Character)Hibernate.CHARACTER.nullSafeGet(rs, names[0]);
if(sex == null)
return null;
try {
return Gender.getInstanceBySex(sex);
}catch (NoSuchElementException e) {
// TODO: handle exception
throw new HibernateException("Bad Gender value: " + sex, e);
}
}

/* (非 Javadoc)
* @see net.sf.hibernate.UserType#nullSafeSet(java.sql.PreparedStatement, java.lang.Object, int)
*/
public void nullSafeSet(PreparedStatement st, Object value, int index)
throws HibernateException, SQLException {
// TODO 自动生成方法存根
Character sex = null;
if(value != null)
sex = ((Gender)value).getSex();
Hibernate.CHARACTER.nullSafeSet(st, sex, index);
}

/* (非 Javadoc)
* @see net.sf.hibernate.UserType#deepCopy(java.lang.Object)
*/
public Object deepCopy(Object value) throws HibernateException {
// TODO 自动生成方法存根
return (Gender)value;
}

/* (非 Javadoc)
* @see net.sf.hibernate.UserType#isMutable()
*/
public boolean isMutable() {
// TODO 自动生成方法存根
return false;
}

}

创建了GenderUserType类后,只需按如下方式映射Customer类的gender属性:

<property name="gender" type="mypack.GenderUserType">

<column name="SEX" length="1"/>

</property>

你可能感兴趣的:(user)