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);
}
}
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
【说明】:本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:254677821)!