虚位以待(AD)
虚位以待(AD)
首页 > 网络编程 > JSP编程 > JSP 中Hibernate实现映射枚举类型

JSP 中Hibernate实现映射枚举类型
类别:JSP编程   作者:码皇   来源:互联网   点击:

这篇文章主要介绍了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 OrdinalEnumUserType<E extends Enum<E>> implements UserType {
    protected Class<E> clazz;
    protected OrdinalEnumUserType(Class<E> 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);
    }
    }

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

相关热词搜索: Hibernate实现映射枚举类型 JSP Hibernate