JSP 中Hibernate实现映射枚举类型
程序员文章站
2023-11-29 20:16:16
jsp 中hibernate实现映射枚举类型
问题:
java bo类gender是枚举类型,想在数据库中存成字符串格式,如何编写hbm.xml?
pub...
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); } }
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!