JSP 中Hibernate實(shí)現(xiàn)映射枚舉類型
JSP 中Hibernate實(shí)現(xiàn)映射枚舉類型
問(wèn)題:
Java BO類Gender是枚舉類型,想在數(shù)據(jù)庫(kù)中存成字符串格式,如何編寫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>. */ /**設(shè)置和Gender類的sex屬性對(duì)應(yīng)的字段的SQL類型 */ public int[] sqlTypes() { return typeList; } /*The class returned by <tt>nullSafeGet()</tt>.*/ /** 設(shè)置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對(duì)象的快照,由于Gender類是不可變類, 因此直接將參數(shù)代表的Gender對(duì)象返回 */ public Object deepCopy(Object value) { return (Gender)value; } /** 比較一個(gè)Gender對(duì)象是否和它的快照相同 */ public boolean equals(Object x, Object y) { //由于內(nèi)存中只可能有兩個(gè)靜態(tài)常量Gender實(shí)例, //因此可以直接按內(nèi)存地址比較 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,然后返回相應(yīng)的Gender實(shí)例 */ 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實(shí)例 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對(duì)象的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中定義映射關(guān)系:
<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>
延伸:
為每個(gè)枚舉類型定義一個(gè)UserType是比較麻煩的,可以定義一個(gè)抽象類。
例如擴(kuò)展下例即可適用于所有保存為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); } }
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
- JS 對(duì)象屬性相關(guān)(檢查屬性、枚舉屬性等)
- JavaScript枚舉選擇jquery插件代碼實(shí)例
- JavaScript enum枚舉類型定義及使用方法
- Node.JS枚舉統(tǒng)計(jì)當(dāng)前文件夾和子目錄下所有代碼文件行數(shù)
- 深入剖析JavaScript中的枚舉功能
- javascript實(shí)現(xiàn)Emrips反質(zhì)數(shù)枚舉的示例代碼
- JavaScript學(xué)習(xí)筆記整理_簡(jiǎn)單實(shí)現(xiàn)枚舉類型,撲克牌應(yīng)用
- 通過(guò)實(shí)例解析js可枚舉屬性與不可枚舉屬性
相關(guān)文章
詳解Struts2中對(duì)未登錄jsp頁(yè)面實(shí)現(xiàn)攔截功能
這篇文章主要介紹了Struts2中對(duì)未登錄jsp頁(yè)面進(jìn)行攔截功能的實(shí)現(xiàn),在演示源碼的同時(shí)對(duì)步驟和原理進(jìn)行了分析,具有一定參考價(jià)值,需要得朋友可以了解下。2017-09-09jsp實(shí)現(xiàn)簡(jiǎn)單驗(yàn)證碼的方法
這篇文章主要介紹了jsp實(shí)現(xiàn)簡(jiǎn)單驗(yàn)證碼的方法,涉及簡(jiǎn)單的JSP驗(yàn)證碼圖片生成技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-10-10JSP實(shí)現(xiàn)計(jì)算器功能(網(wǎng)頁(yè)版)
這篇文章講述了JSP實(shí)現(xiàn)計(jì)算器功能的詳細(xì)代碼,網(wǎng)頁(yè)版的計(jì)算器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2015-12-12驚現(xiàn)支撐1億pv/天的超級(jí)數(shù)據(jù)庫(kù)解決方案
我說(shuō)的系統(tǒng)主要是構(gòu)建在hibernate之上的高效數(shù)據(jù)庫(kù)緩存系統(tǒng),其中包含了分布式解決方案,該系統(tǒng)已經(jīng)應(yīng)用在舍得網(wǎng)上了,沒有發(fā)現(xiàn)大問(wèn)題,2008-07-07jsp 標(biāo)準(zhǔn)標(biāo)簽庫(kù)簡(jiǎn)析
jsp開發(fā)者指定了 JSTL ,提供了一組統(tǒng)一的通用的自定義標(biāo)簽文件,并將這些文件組合在一起,形成了jsp標(biāo)準(zhǔn)標(biāo)簽庫(kù)2012-11-11