熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java開源技術 >> 正文

Hibernate如何映射枚舉類型

2013-11-23 20:15:17  來源: Java開源技術 

  問題

  Java BO類Gender是枚舉類型想在數據庫中存成字符串格式如何編寫hbmxml?

  [java] view plaincopyprint?

  public enum Gender{

  UNKNOWN(Unknown)

  MALE(Male)

  FEMALE(Female);

  private String key;

  private Gender(final String key) {

  thiskey = key;

  }

  public getGender(String key) {

  for (Gender gender : Gendervalues()) {

  if (keyeuqals(gendergetKey()))

  return gender;

  }

  throw new NoSuchElementException(key);

  }

  }

  public enum Gender{

  UNKNOWN(Unknown)

  MALE(Male)

  FEMALE(Female);

  private String key;

  private Gender(final String key) {

  thiskey = key;

  }

  public getGender(String key) {

  for (Gender gender : Gendervalues()) {

  if (keyeuqals(gendergetKey()))

  return gender;

  }

  throw new NoSuchElementException(key);

  }

  }

  使用UserType

  [java] view plaincopyprint?

  public class GenderUserType implements UserType {

  private static int[] typeList = {  TypesVARCHAR};

  /*

  * Return the SQL type codes for the columns mapped by this type

  * The codes are defined on <tt>javasqlTypes</tt> */

  /**設置和Gender類的sex屬性對應的字段的SQL類型 */

  public int[] sqlTypes() {

  return typeList;

  }

  /*The class returned by <tt>nullSafeGet()</tt>*/

  /** 設置GenderUserType所映射的Java類Gender類 */

  public Class returnedClass() {

  return Genderclass;

  }

  /** 指明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 xhashCode();

  }

  /*

  * 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) HibernateSTRINGnullSafeGet(rs names[]);

  if (sex == null) { return null; }

  //按照性別查找匹配的Gender實例

  try {

  return GendergetGender(sex);

  }catch (javautilNoSuchElementException 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 multicolumn 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();

  HibernateStringnullSafeSet(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;

  }

  }

  public class GenderUserType implements UserType {

  private static int[] typeList = {  TypesVARCHAR};

  /*

  * Return the SQL type codes for the columns mapped by this type

  * The codes are defined on <tt>javasqlTypes</tt> */

  /**設置和Gender類的sex屬性對應的字段的SQL類型 */

  public int[] sqlTypes() {

  return typeList;

  }

  /*The class returned by <tt>nullSafeGet()</tt>*/

  /** 設置GenderUserType所映射的Java類Gender類 */

  public Class returnedClass() {

  return Genderclass;

  }

  /** 指明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 xhashCode();

  }

  /*

  * 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) HibernateSTRINGnullSafeGet(rs names[]);

  if (sex == null) { return null; }

  //按照性別查找匹配的Gender實例

  try {

  return GendergetGender(sex);

  }catch (javautilNoSuchElementException 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 multicolumn 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();

  HibernateStringnullSafeSet(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;

  }

  }

  然後再hbmxml中定義映射關系

  [html] view plaincopyprint?

  <hibernatemapping package= defaultlazy=true defaultcascade=saveupdatemergepersist>

  <typedef name=Gender class=comalphahibernateGenderUserType>

  <property name=gender type=Gender>

  <column name=GENDER notnull=true>

  </column>

  </property>

  <hibernatemapping package= defaultlazy=true defaultcascade=saveupdatemergepersist>

  <typedef name=Gender class=comalphahibernateGenderUserType>

  <property name=gender type=Gender>

  <column name=GENDER notnull=true>

  </column>

  </property>

  延伸

  為每個枚舉類型定義一個UserType是比較麻煩的可以定義一個抽象類

  例如擴展下例即可適用於所有保存為index的枚舉類型

  [java] view plaincopyprint?

  public abstract class OrdinalEnumUserType<E extends Enum<E>> implements UserType {

  protected Class<E> clazz;

  protected OrdinalBasedEnumUserType(Class<E> clazz) {

  thisclazz = clazz;

  }

  private static final int[] SQL_TYPES = {TypesNUMERIC};

  public int[] sqlTypes() {

  return SQL_TYPES;

  }

  public Class<?> returnedClass() {

  return clazz;

  }

  public E nullSafeGet(ResultSet resultSet String[] names Object owner)

  throws HibernateException SQLException {

  //HibernateSTRINGnullSafeGet(rs names[])

  int index = resultSetgetInt(names[]);

  E result = null;

  if (!resultSetwasNull()) {

  result = clazzgetEnumConstants()[index];

  }

  return result;

  }

  public void nullSafeSet(PreparedStatement preparedStatement

  Object valueint index) throws HibernateException SQLException {

  if (null == value) {

  preparedStatementsetNull(index TypesNUMERIC);

  } else {

  //HibernateStringnullSafeSet(st sex index);

  preparedStatementsetInt(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 xhashCode();

  }

  public boolean equals(Object x Object y) throws HibernateException {

  if (x == y)

  return true;

  if (null == x || null == y)

  return false;

  return xequals(y);

  }

  }

  public abstract class OrdinalEnumUserType<E extends Enum<E>> implements UserType {

  protected Class<E> clazz;

  protected OrdinalBasedEnumUserType(Class<E> clazz) {

  thisclazz = clazz;

  }

  private static final int[] SQL_TYPES = {TypesNUMERIC};

  public int[] sqlTypes() {

  return SQL_TYPES;

  }

  public Class<?> returnedClass() {

  return clazz;

  }

  public E nullSafeGet(ResultSet resultSet String[] names Object owner)

  throws HibernateException SQLException {

  //HibernateSTRINGnullSafeGet(rs names[])

  int index = resultSetgetInt(names[]);

  E result = null;

  if (!resultSetwasNull()) {

  result = clazzgetEnumConstants()[index];

  }

  return result;

  }

  public void nullSafeSet(PreparedStatement preparedStatement

  Object valueint index) throws HibernateException SQLException {

  if (null == value) {

  preparedStatementsetNull(index TypesNUMERIC);

  } else {

  //HibernateStringnullSafeSet(st sex index);

  preparedStatementsetInt(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 xhashCode();

  }

  public boolean equals(Object x Object y) throws HibernateException {

  if (x == y)

  return true;

  if (null == x || null == y)

  return false;

  return xequals(y);

  }

  }


From:http://tw.wingwit.com/Article/program/Java/ky/201311/28186.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.