Hibernate UserType 自定义类型

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

 

 仔细看看hibernate的DOC发现不少惊奇的东东,后悔自己的旁门助道是多么的无用. 本次主要实现目的. 数据库表:EchoMessageEmail,其中有三个字段id(自动编号)\name\Email(varchar) 实现目的:数据库字段中Email的值是类似于[email protected];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>    

对应的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. }     


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. }     



其中的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. }     


测试类:


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. }     

你可能感兴趣的:(Hibernate,object,String,list,equals,import)