Hibernate UserType 自定义类型

转自 :http://www.iteye.com/topic/182797

 

 仔细看看hibernate的DOC发现不少惊奇的东东,后悔自己的旁门助道是多么的无用. 本次主要实现目的. 数据库表:EchoMessageEmail,其中有三个字段id(自动编号)\name\Email(varchar) 实现目的:数据库字段中Email的值是类似于eiya@21cn.com;www.1718zx.cn的.所以要求以List表达.也就是生成的DataModel当中是有一个List对象的.hbm.xml

xml 代码

Java代码 复制代码  收藏代码
  1. <?xml version="1.0" encoding="utf-8"?>      
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"      
  3. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">      
  4. <!--      
  5.     Mapping file autogenerated by MyEclipse - Hibernate Tools     
  6. -->      
  7. <hibernate-mapping>      
  8.     <class name="com.travelsky.hibernate.po.EchoMessageEmail" table="echo_message_email">      
  9.         <id name="id" type="java.lang.Integer">      
  10.             <column name="ID" />      
  11.             <generator class="native"></generator>      
  12.         </id>      
  13.         <property name="name" type="java.lang.String">      
  14.             <column name="NAME" length="50" not-null="true" />      
  15.         </property>      
  16.         <property name="email" type="com.travelsky.hibernate.po.EmailList" lazy="true">      
  17.             <column name="EMAIL"/>                 
  18.         </property>              
  19.     </class>      
  20. </hibernate-mapping>    
<?xml version="1.0" encoding="utf-8"?>   
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"   
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">   
<!--   
    Mapping file autogenerated by MyEclipse - Hibernate Tools  
-->   
<hibernate-mapping>   
    <class name="com.travelsky.hibernate.po.EchoMessageEmail" table="echo_message_email">   
        <id name="id" type="java.lang.Integer">   
            <column name="ID" />   
            <generator class="native"></generator>   
        </id>   
        <property name="name" type="java.lang.String">   
            <column name="NAME" length="50" not-null="true" />   
        </property>   
        <property name="email" type="com.travelsky.hibernate.po.EmailList" lazy="true">   
            <column name="EMAIL"/>              
        </property>           
    </class>   
</hibernate-mapping>  

对应的POJO:

java 代码

Java代码 复制代码  收藏代码
  1. package com.travelsky.hibernate.po;      
  2. import java.util.List;      
  3.       
  4. /**    
  5.  * EchoMessageEmail generated by MyEclipse Persistence Tools    
  6.  */      
  7.       
  8. public class EchoMessageEmail  implements java.io.Serializable {      
  9.       
  10.      private Integer id;      
  11.      private String name;      
  12.      private List email;      
  13.       
  14.     /** default constructor */      
  15.     public EchoMessageEmail() {      
  16.     }      
  17.       
  18.     /** minimal constructor */      
  19.     public EchoMessageEmail(String name) {      
  20.         this.name = name;      
  21.     }      
  22.           
  23.     /** full constructor */      
  24.     public EchoMessageEmail(String name, List email) {      
  25.         this.name = name;      
  26.         this.email = email;      
  27.     }      
  28.       
  29.          
  30.     // Property accessors      
  31.       
  32.     public Integer getId() {      
  33.         return this.id;      
  34.     }      
  35.           
  36.     public void setId(Integer id) {      
  37.         this.id = id;      
  38.     }      
  39.       
  40.     public String getName() {      
  41.         return this.name;      
  42.     }      
  43.           
  44.     public void setName(String name) {      
  45.         this.name = name;      
  46.     }      
  47.       
  48.     public List getEmail() {      
  49.         return email;      
  50.     }      
  51.       
  52.     public void setEmail(List email) {      
  53.         this.email = email;      
  54.     }      
  55.       
  56. }     
package com.travelsky.hibernate.po;   
import java.util.List;   
   
/**  
 * EchoMessageEmail generated by MyEclipse Persistence Tools  
 */   
   
public class EchoMessageEmail  implements java.io.Serializable {   
   
     private Integer id;   
     private String name;   
     private List email;   
   
    /** default constructor */   
    public EchoMessageEmail() {   
    }   
   
    /** minimal constructor */   
    public EchoMessageEmail(String name) {   
        this.name = name;   
    }   
       
    /** full constructor */   
    public EchoMessageEmail(String name, List email) {   
        this.name = name;   
        this.email = email;   
    }   
   
      
    // Property accessors   
   
    public Integer getId() {   
        return this.id;   
    }   
       
    public void setId(Integer id) {   
        this.id = id;   
    }   
   
    public String getName() {   
        return this.name;   
    }   
       
    public void setName(String name) {   
        this.name = name;   
    }   
   
    public List getEmail() {   
        return email;   
    }   
   
    public void setEmail(List email) {   
        this.email = email;   
    }   
   
}   


UserType接口各方法的详解

Java代码 复制代码  收藏代码
  1.   
  2. import java.sql.PreparedStatement;      
  3. import java.sql.ResultSet;      
  4. import java.sql.SQLException;      
  5.       
  6. import net.sf.hibernate.HibernateException;      
  7.       
  8. /**    
  9.  * @author hy-he    
  10.  *    
  11.  */      
  12. public interface UserType {      
  13.       
  14.  /**    
  15.   * 返回UserType所映射字段的SQL类型(java.sql.Types)    
  16.   * 返回类型为int[],其中包含了映射个字段的SQL类型代码    
  17.   * (UserType可以映射到一个或者多个字段)    
  18.   * @return    
  19.   */      
  20.  public int[]sqlTypes();      
  21.       
  22.       
  23.  /**    
  24.   * UserType.nullSafeGet()所返回的自定义数据类型    
  25.   * @return    
  26.   */      
  27.  public Class returnedClass();      
  28.       
  29.       
  30.  /**    
  31.   * 自定义数据类型的比对方法    
  32.   * 此方法将用作脏数据检查,参数x、y分别为数据的两个副本    
  33.   * 如果equals方法返回false,则Hibernate将认为数据发生变化,并将变化更新到数据库表中    
  34.   * @param x    
  35.   * @param y    
  36.   * @return    
  37.   * @throws HibernateException    
  38.   */      
  39.  public boolean equals(Object x,Object y)throws HibernateException;      
  40.       
  41.       
  42.  /**    
  43.   * 从JDBC ResultSet读取数据,将其转换为自定义类型后返回    
  44.   * (此方法要求对克能出现null值进行处理)    
  45.   * names中包含了当前自定义类型的映射字段名称    
  46.   * @param rs    
  47.   * @param names    
  48.   * @param owner    
  49.   * @return    
  50.   * @throws HibernateException    
  51.   * @throws SQLException    
  52.   */      
  53.  public Object nullSafeGet(ResultSet rs,String[] names,Object owner)throws HibernateException,SQLException;      
  54.       
  55.       
  56.  /**    
  57.   * 本方法将在Hibernate进行数据保存时被调用    
  58.   * 我们可以通过PreparedStateme将自定义数据写入到对应的数据库表字段    
  59.   * @param st    
  60.   * @param value    
  61.   * @param index    
  62.   * @throws HibernateException    
  63.   * @throws SQLException    
  64.   */      
  65.  public void nullSafeSet(PreparedStatement st,Object value,int index)throws HibernateException,SQLException;      
  66.       
  67.       
  68.  /**    
  69.   * 提供自定义类型的完全复制方法    
  70.   * 本方法将用构造返回对象    
  71.   * 当nullSafeGet方法调用之后,我们获得了自定义数据对象,在向用户返回自定义数据之前,    
  72.   * deepCopy方法将被调用,它将根据自定义数据对象构造一个完全拷贝,并将此拷贝返回给用户    
  73.   * 此时我们就得到了自定义数据对象的两个版本,第一个是从数据库读出的原始版本,其二是我们通过    
  74.   * deepCopy方法构造的复制版本,原始的版本将有Hibernate维护,复制版由用户使用。原始版本用作    
  75.   * 稍后的脏数据检查依据;Hibernate将在脏数据检查过程中将两个版本的数据进行对比(通过调用    
  76.   * equals方法),如果数据发生了变化(equals方法返回false),则执行对应的持久化操作    
  77.   *    
  78.   * @param value    
  79.   * @return    
  80.   * @throws HibernateException    
  81.   */      
  82.  public Object deppCopy(Object value)throws HibernateException;      
  83.       
  84.       
  85.  /**    
  86.   * 本类型实例是否可变    
  87.   * @return    
  88.   */      
  89.  public boolean isMutable();      
  90. }     
import java.sql.PreparedStatement;   
import java.sql.ResultSet;   
import java.sql.SQLException;   
   
import net.sf.hibernate.HibernateException;   
   
/**  
 * @author hy-he  
 *  
 */   
public interface UserType {   
   
 /**  
  * 返回UserType所映射字段的SQL类型(java.sql.Types)  
  * 返回类型为int[],其中包含了映射个字段的SQL类型代码  
  * (UserType可以映射到一个或者多个字段)  
  * @return  
  */   
 public int[]sqlTypes();   
   
   
 /**  
  * UserType.nullSafeGet()所返回的自定义数据类型  
  * @return  
  */   
 public Class returnedClass();   
   
   
 /**  
  * 自定义数据类型的比对方法  
  * 此方法将用作脏数据检查,参数x、y分别为数据的两个副本  
  * 如果equals方法返回false,则Hibernate将认为数据发生变化,并将变化更新到数据库表中  
  * @param x  
  * @param y  
  * @return  
  * @throws HibernateException  
  */   
 public boolean equals(Object x,Object y)throws HibernateException;   
   
   
 /**  
  * 从JDBC ResultSet读取数据,将其转换为自定义类型后返回  
  * (此方法要求对克能出现null值进行处理)  
  * names中包含了当前自定义类型的映射字段名称  
  * @param rs  
  * @param names  
  * @param owner  
  * @return  
  * @throws HibernateException  
  * @throws SQLException  
  */   
 public Object nullSafeGet(ResultSet rs,String[] names,Object owner)throws HibernateException,SQLException;   
   
   
 /**  
  * 本方法将在Hibernate进行数据保存时被调用  
  * 我们可以通过PreparedStateme将自定义数据写入到对应的数据库表字段  
  * @param st  
  * @param value  
  * @param index  
  * @throws HibernateException  
  * @throws SQLException  
  */   
 public void nullSafeSet(PreparedStatement st,Object value,int index)throws HibernateException,SQLException;   
   
   
 /**  
  * 提供自定义类型的完全复制方法  
  * 本方法将用构造返回对象  
  * 当nullSafeGet方法调用之后,我们获得了自定义数据对象,在向用户返回自定义数据之前,  
  * deepCopy方法将被调用,它将根据自定义数据对象构造一个完全拷贝,并将此拷贝返回给用户  
  * 此时我们就得到了自定义数据对象的两个版本,第一个是从数据库读出的原始版本,其二是我们通过  
  * deepCopy方法构造的复制版本,原始的版本将有Hibernate维护,复制版由用户使用。原始版本用作  
  * 稍后的脏数据检查依据;Hibernate将在脏数据检查过程中将两个版本的数据进行对比(通过调用  
  * equals方法),如果数据发生了变化(equals方法返回false),则执行对应的持久化操作  
  *  
  * @param value  
  * @return  
  * @throws HibernateException  
  */   
 public Object deppCopy(Object value)throws HibernateException;   
   
   
 /**  
  * 本类型实例是否可变  
  * @return  
  */   
 public boolean isMutable();   
}   




其中的UserType的一个类:EmailList

java 代码

Java代码 复制代码  收藏代码
  1. package com.travelsky.hibernate.po;      
  2.       
  3. import java.io.Serializable;      
  4. import java.sql.PreparedStatement;      
  5. import java.sql.ResultSet;      
  6. import java.sql.SQLException;      
  7. import java.sql.Types;      
  8. import java.util.ArrayList;      
  9. import java.util.List;      
  10.       
  11. import org.apache.commons.lang.StringUtils;      
  12. import org.hibernate.HibernateException;      
  13. import org.hibernate.Hibernate;      
  14.       
  15. /**    
  16.  * 必须得引用java.io.Serializable,UserType是反序列化    
  17.  * 另外,我使用的hibernate版本是3.2,UserType从2.0到3.2有很大的差异,应该多多看看官方的doc    
  18.  *     
  19.  * @author @家军.严重注意org.hibernate.usertype.UserType,不要自己造车呀.   
  20.  *     
  21.  */      
  22. public class EmailList implements java.io.Serializable,org.hibernate.usertype.UserType{      
  23.       
  24.     private List emails;      
  25.       
  26.     private static final String SPLITTER = ";";      
  27.       
  28.     private static final int[] TYPES = new int[] { Types.VARCHAR };      
  29.       
  30.     public int[] sqlTypes() {      
  31.               
  32.         return TYPES;      
  33.     }      
  34.       
  35.     public Class returnedClass() {      
  36.         // TODO Auto-generated method stub      
  37.         return List.class;      
  38.     }      
  39.       
  40.     public boolean equals(Object x, Object y) throws HibernateException {      
  41.         if (x == y)      
  42.             return true;      
  43.         if (x != null && y != null) {      
  44.             List xList = (List) x;      
  45.             List yList = (List) y;      
  46.             if (xList.size() != yList.size())      
  47.                 return false;      
  48.             for (int i = 0; i < xList.size(); i++) {      
  49.                 String str1 = (String) xList.get(i);      
  50.                 String str2 = (String) yList.get(i);      
  51.                 if (!str1.equals(str2))      
  52.                     return false;      
  53.             }      
  54.             return true;      
  55.         }      
  56.         return false;      
  57.     }      
  58.       
  59.     public Object nullSafeGet(ResultSet rs, String[] names, Object owner)      
  60.             throws HibernateException, SQLException {      
  61.         String value = (String) Hibernate.STRING.nullSafeGet(rs, names[0]);      
  62.         if (value != null) {      
  63.             return parse(value);      
  64.         } else {      
  65.             return null;      
  66.         }      
  67.     }      
  68.       
  69.     public void nullSafeSet(PreparedStatement st, Object value, int index)      
  70.             throws HibernateException, SQLException {      
  71.         System.out.println("Set method excecuted");      
  72.         if (value != null) {      
  73.             String str = assemble((List) value);      
  74.             Hibernate.STRING.nullSafeSet(st, str, index);      
  75.         } else {      
  76.             Hibernate.STRING.nullSafeSet(st, value, index);      
  77.         }      
  78.       
  79.     }      
  80.       
  81.     public Object deepCopy(Object value) throws HibernateException {      
  82.         List sourcelist = (List) value;      
  83.         List targetlist = new ArrayList();      
  84.         targetlist.addAll(sourcelist);      
  85.         return targetlist;      
  86.     }      
  87.       
  88.     public boolean isMutable() {              
  89.         return false;      
  90.     }      
  91.       
  92.     private String assemble(List emailList) {      
  93.         StringBuffer strBuf = new StringBuffer();      
  94.         for (int i = 0; i < emailList.size() - 1; i++) {      
  95.             strBuf.append(emailList.get(i)).append(SPLITTER);      
  96.         }      
  97.         strBuf.append(emailList.get(emailList.size() - 1));      
  98.         return strBuf.toString();      
  99.     }      
  100.       
  101.     private List parse(String value) {      
  102.         String[] strs = StringUtils.split(value, SPLITTER);      
  103.         List emailList = new ArrayList();      
  104.         for (int i = 0; i < strs.length; i++) {      
  105.             emailList.add(strs[i]);      
  106.         }      
  107.         return emailList;      
  108.     }      
  109.       
  110.     public Object assemble(Serializable arg0, Object arg1) throws HibernateException {      
  111.         // TODO Auto-generated method stub      
  112.         return null;      
  113.     }      
  114.       
  115.     public Serializable disassemble(Object arg0) throws HibernateException {      
  116.         // TODO Auto-generated method stub      
  117.         return null;      
  118.     }      
  119.       
  120.     public int hashCode(Object arg0) throws HibernateException {      
  121.         // TODO Auto-generated method stub      
  122.         return 0;      
  123.     }      
  124.       
  125.     public Object replace(Object arg0, Object arg1, Object arg2) throws HibernateException {      
  126.         // TODO Auto-generated method stub      
  127.         return null;      
  128.     }      
  129.       
  130. }     
package com.travelsky.hibernate.po;   
   
import java.io.Serializable;   
import java.sql.PreparedStatement;   
import java.sql.ResultSet;   
import java.sql.SQLException;   
import java.sql.Types;   
import java.util.ArrayList;   
import java.util.List;   
   
import org.apache.commons.lang.StringUtils;   
import org.hibernate.HibernateException;   
import org.hibernate.Hibernate;   
   
/**  
 * 必须得引用java.io.Serializable,UserType是反序列化  
 * 另外,我使用的hibernate版本是3.2,UserType从2.0到3.2有很大的差异,应该多多看看官方的doc  
 *   
 * @author @家军.严重注意org.hibernate.usertype.UserType,不要自己造车呀. 
 *   
 */   
public class EmailList implements java.io.Serializable,org.hibernate.usertype.UserType{   
   
    private List emails;   
   
    private static final String SPLITTER = ";";   
   
    private static final int[] TYPES = new int[] { Types.VARCHAR };   
   
    public int[] sqlTypes() {   
           
        return TYPES;   
    }   
   
    public Class returnedClass() {   
        // TODO Auto-generated method stub   
        return List.class;   
    }   
   
    public boolean equals(Object x, Object y) throws HibernateException {   
        if (x == y)   
            return true;   
        if (x != null && y != null) {   
            List xList = (List) x;   
            List yList = (List) y;   
            if (xList.size() != yList.size())   
                return false;   
            for (int i = 0; i < xList.size(); i++) {   
                String str1 = (String) xList.get(i);   
                String str2 = (String) yList.get(i);   
                if (!str1.equals(str2))   
                    return false;   
            }   
            return true;   
        }   
        return false;   
    }   
   
    public Object nullSafeGet(ResultSet rs, String[] names, Object owner)   
            throws HibernateException, SQLException {   
        String value = (String) Hibernate.STRING.nullSafeGet(rs, names[0]);   
        if (value != null) {   
            return parse(value);   
        } else {   
            return null;   
        }   
    }   
   
    public void nullSafeSet(PreparedStatement st, Object value, int index)   
            throws HibernateException, SQLException {   
        System.out.println("Set method excecuted");   
        if (value != null) {   
            String str = assemble((List) value);   
            Hibernate.STRING.nullSafeSet(st, str, index);   
        } else {   
            Hibernate.STRING.nullSafeSet(st, value, index);   
        }   
   
    }   
   
    public Object deepCopy(Object value) throws HibernateException {   
        List sourcelist = (List) value;   
        List targetlist = new ArrayList();   
        targetlist.addAll(sourcelist);   
        return targetlist;   
    }   
   
    public boolean isMutable() {           
        return false;   
    }   
   
    private String assemble(List emailList) {   
        StringBuffer strBuf = new StringBuffer();   
        for (int i = 0; i < emailList.size() - 1; i++) {   
            strBuf.append(emailList.get(i)).append(SPLITTER);   
        }   
        strBuf.append(emailList.get(emailList.size() - 1));   
        return strBuf.toString();   
    }   
   
    private List parse(String value) {   
        String[] strs = StringUtils.split(value, SPLITTER);   
        List emailList = new ArrayList();   
        for (int i = 0; i < strs.length; i++) {   
            emailList.add(strs[i]);   
        }   
        return emailList;   
    }   
   
    public Object assemble(Serializable arg0, Object arg1) throws HibernateException {   
        // TODO Auto-generated method stub   
        return null;   
    }   
   
    public Serializable disassemble(Object arg0) throws HibernateException {   
        // TODO Auto-generated method stub   
        return null;   
    }   
   
    public int hashCode(Object arg0) throws HibernateException {   
        // TODO Auto-generated method stub   
        return 0;   
    }   
   
    public Object replace(Object arg0, Object arg1, Object arg2) throws HibernateException {   
        // TODO Auto-generated method stub   
        return null;   
    }   
   
}   


测试类:


Java代码 复制代码  收藏代码
  1. package com.travelsky.test;      
  2. import java.util.List;      
  3. import java.util.ListIterator;      
  4. import com.travelsky.hibernate.po.EchoMessageEmail;      
  5. import org.hibernate.Query;      
  6. import org.hibernate.Session;      
  7. import org.hibernate.SessionFactory;      
  8. import org.hibernate.cfg.Configuration;      
  9.       
  10. public class HibernateTest {      
  11.       
  12.     public static void main(String[] args) throws Exception{              
  13.         Configuration config = new Configuration().configure();      
  14.         SessionFactory factory = config.buildSessionFactory();      
  15.         Session session = factory.openSession();      
  16.         Query query = session.createQuery("from EchoMessageEmail as a");      
  17.         /**    
  18.          * 理论上来说,这里不存在lazy加载,为了安全起见使用了Iterator    
  19.          *     
  20.          */      
  21.         ListIterator iterator = query.list().listIterator();      
  22.         EchoMessageEmail tt = (EchoMessageEmail) iterator.next();//只找第一个      
  23.         List emails = tt.getEmail();                  
  24.         for (int i = 0; i < emails.size(); i++) {      
  25.             String emailStr = (String)emails.get(i);      
  26.             System.out.println(emailStr);      
  27.         }             
  28.         session.close();      
  29.     }         
  30. }     
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值