精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-08-16
最后修改:2009-12-19
在项目中许多地方使用枚举类,枚举对象值对应数据一个常量。增加代码的可读性等。具体使用如下:
JPA参考手册:JPA注释参考手册 http://www.oidn.net/blog/article.asp?id=250 Hibernate Annotation 用户类型(User Type) 使用UserType首先要弄清楚它的目的。大家知道Hibernate解决的主要是对象数据库阻抗失衡的问题,也就是如何将一个或多个对象保存到一个或多个数据库表格中。 这其中有很多方法,其实大部分情况下采用@Embeddable和 @Embedded 就可以解决问题了,只有嵌入对象方式无法满足要求时,或者是Hibernate默认的持久化方式无法满足要求时,才应该考虑UserType。 总之记住一 个原则,不到山穷水尽,不要轻易使用UserType。还有一个要慎重考虑使用UserType的原因是:一旦采用了UserType,你的项目就脱离了 JPA,而直接和Hibernate耦合在一起了。
今天我先举个immutable的例子。
public class Status {
public static final int ACTIVATED = 5 ; public static final int DEACTIVATED = 6 ; }
public enum Status {
ACTIVATED, DEACTIVATED; }
public interface DescriptionID {
String getDescription(); int getId(); }
public enum Status implements DescriptionID {
ACTIVATED( 5 , " This object is activated " ), DEACTIVATED( 9 , " This object is deactivated " ); private Integer id; private String description; private static List < Status > list; static { list = new ArrayList < Status > ( 2 ); list.add(ACTIVATED); list.add(DEACTIVATED); } private Status( int statusNr, String description) { this .id = statusNr; this .description = description; } public String getDescription() { return this .description; } public Integer getId() { return id; } public static List < Status > getAll() { return list; } public static Status findById(Integer id) { for (Status status : getAll()) { if (id == status.getId()) { return status; } } return null ; } }
List()方法是为了方便获取所有的Status常 量,例如在用户界面通过ComboBox展示,findById()方法是为了通过给定Id获得对应的Enum实例。其中findById()方法参数一 定要是Integer,原因后面会讲到。 下面编写DescriptionIDUserType: public class DescriptionIDUserType implements UserType, ParameterizedType { private Class enumClass; public void setParameterValues(Properties parameters) { try { enumClass = ReflectHelper.classForName(parameters.getProperty( " class " )); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public Object assemble(Serializable cached, Object arg1) throws HibernateException { return cached; } /* * (non-Javadoc) * * @see org.hibernate.usertype.UserType#deepCopy(java.lang.Object) */ public Object deepCopy(Object value) throws HibernateException { // TODO Auto-generated method stub return value; } /* * (non-Javadoc) * * @see org.hibernate.usertype.UserType#disassemble(java.lang.Object) */ public Serializable disassemble(Object value) throws HibernateException { // TODO Auto-generated method stub return (Serializable) value; } /* * (non-Javadoc) * * @see org.hibernate.usertype.UserType#equals(java.lang.Object, * java.lang.Object) */ public boolean equals(Object id1, Object id2) throws HibernateException { if (id1 == id2) { return true ; } if (id1 == null || id2 == null ) { return false ; } final DescriptionID did1 = (DescriptionID) id1; final DescriptionID did2 = (DescriptionID) id2; return did1.getId() == did2.getId() && StringUtils.equals(did1.getDescription(), did2 .getDescription()); } /* * (non-Javadoc) * * @see org.hibernate.usertype.UserType#hashCode(java.lang.Object) */ public int hashCode(Object value) throws HibernateException { // TODO Auto-generated method stub return value.hashCode(); } /* * (non-Javadoc) * * @see org.hibernate.usertype.UserType#isMutable() */ public boolean isMutable() { // TODO Auto-generated method stub return false ; } /* * (non-Javadoc) * * @see org.hibernate.usertype.UserType#nullSafeGet(java.sql.ResultSet, * java.lang.String[], java.lang.Object) */ public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner) throws HibernateException, SQLException { try { int id = resultSet.getInt(names[ 0 ]); if (resultSet.wasNull()) { return null ; } return enumClass.getMethod( " findById " , new Class[] { Integer. class }) .invoke( null , id); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null ; } /* * (non-Javadoc) * * @see org.hibernate.usertype.UserType#nullSafeSet(java.sql.PreparedStatement, * java.lang.Object, int) */ public void nullSafeSet(PreparedStatement statement, Object value, int index) throws HibernateException, SQLException { if (value == null ) { statement.setNull(index, Hibernate.INTEGER.sqlType()); } else { DescriptionID dID = (DescriptionID) value; statement.setInt(index, dID.getId()); } } /* * (non-Javadoc) * * @see org.hibernate.usertype.UserType#replace(java.lang.Object, * java.lang.Object, java.lang.Object) */ public Object replace(Object original, Object arg1, Object arg2) throws HibernateException { // TODO Auto-generated method stub return original; } /* * (non-Javadoc) * * @see org.hibernate.usertype.UserType#returnedClass() */ public Class returnedClass() { return DescriptionID. class ; } /* * (non-Javadoc) * * @see org.hibernate.usertype.UserType#sqlTypes() */ public int [] sqlTypes() { return new int []{Hibernate.INTEGER.sqlType()}; } }
在nullSaftGet中我们使用Java Reflection并借助用户给出的enum类参数直接调用该enum类的findById()方法,这样我们就可以使用数据库中的integer找到 对应的enum实例。 注意,由于使用了Java Reflection,所以findById()方法参数必须是Integer而非int。 在nullSafeSet中,我们则通过 DescriptionID接口直接获取enum实例的id属性,并且将它保存到数据库中去。
@TypeDefs({@TypeDef(name = " status " , typeClass = DescriptionIDUserType. class ,
parameters = {@Parameter(name = " class " , value = " com.yourpackage.Status " )})}) @Entity public class SomeObject { private Integer objectId; private Status status; @Id @GeneratedValue(strategy=GenerationType.AUTO) public Integer getObjectId() { return objectId; } public void setObjectId(Integer objectId) { this .objectId = objectId; } @Type(type = " status " ) public Status getStatus() { return status; } public void setStatus(Status status) { this .status = status; } }
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-05-21
感觉有点复杂,算了还是在get,set里面操作把
|
|
返回顶楼 | |
浏览 2959 次