java

位置:IT落伍者 >> java >> 浏览文章

Hibernate如何映射枚举类型


发布日期:2023年01月17日
 
Hibernate如何映射枚举类型

问题

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);

}

}

               

上一篇:Java程序员必须了解的七大开源协议

下一篇:Eclipse快速上手指南之使用ANT