Chinaunix首页 | 论坛 | 博客
  • 博客访问: 969857
  • 博文数量: 168
  • 博客积分: 3853
  • 博客等级: 中校
  • 技术积分: 1854
  • 用 户 组: 普通用户
  • 注册时间: 2008-01-15 23:50
文章分类

全部博文(168)

文章存档

2014年(12)

2013年(46)

2012年(60)

2011年(11)

2010年(1)

2009年(17)

2008年(21)

我的朋友

分类: Java

2013-01-31 16:59:54


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


}


我们的这个UserType是要支持实现DescriptionID的各种不同的enum,而enum是没法继承的。所以我们需要用户给出具体的参数,以进一步确定到底是哪个enum类。这也就导致了,我们的这个类需要实现 ParameterizedType接口。  由于enum类本身是immutable的,所以这个UserType的实现类相对比较简单,主要的两个方法是 nullSafeGet和 nullSafeSet。  

在nullSaftGet中我们使用Java Reflection并借助用户给出的enum类参数直接调用该enum类的findById()方法,这样我们就可以使用数据库中的integer找到 对应的enum实例。

注意,由于使用了Java Reflection,所以findById()方法参数必须是Integer而非int。 在nullSafeSet中,我们则通过 DescriptionID接口直接获取enum实例的id属性,并且将它保存到数据库中去。 最后看看怎么使用这个UserType:
@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;
    }
} 

其中值得讲讲的就是定义Type时使用的parameter,"class"参数是我们自己定义的,该参数为DescriptionIDUserType提供 了具体的enum类。前面已经讲过了,DescriptionIDUserType就是在运行时态利用这个参数自定义enum与数据库之间的持久化逻辑。

使用这个UserType之后,我们就可以在确保数据库数据不变的情况下,成功地将类型不保险的常量类改写成enum,而且这个UserType支持所有实现了
DescriptionID接口的enum类。
阅读(2940) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~