论坛首页 Java企业应用论坛

hibernate3.2上使用UserType范例

浏览 4504 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-04-15  
仔细看看hibernate的DOC发现不少惊奇的东东,后悔自己的旁门助道是多么的无用. 本次主要实现目的. 数据库表:EchoMessageEmail,其中有三个字段id(自动编号)\name\Email(varchar) 实现目的:数据库字段中Email的值是类似于eiya@21cn.com;www.1718zx.cn的.所以要求以List表达.也就是生成的DataModel当中是有一个List对象的.hbm.xml

xml 代码

<?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 代码

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接口各方法的详解


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 代码

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


测试类:


package com.travelsky.test;   
import java.util.List;   
import java.util.ListIterator;   
import com.travelsky.hibernate.po.EchoMessageEmail;   
import org.hibernate.Query;   
import org.hibernate.Session;   
import org.hibernate.SessionFactory;   
import org.hibernate.cfg.Configuration;   
   
public class HibernateTest {   
   
    public static void main(String[] args) throws Exception{           
        Configuration config = new Configuration().configure();   
        SessionFactory factory = config.buildSessionFactory();   
        Session session = factory.openSession();   
        Query query = session.createQuery("from EchoMessageEmail as a");   
        /**  
         * 理论上来说,这里不存在lazy加载,为了安全起见使用了Iterator  
         *   
         */   
        ListIterator iterator = query.list().listIterator();   
        EchoMessageEmail tt = (EchoMessageEmail) iterator.next();//只找第一个   
        List emails = tt.getEmail();               
        for (int i = 0; i < emails.size(); i++) {   
            String emailStr = (String)emails.get(i);   
            System.out.println(emailStr);   
        }          
        session.close();   
    }      
}   

   发表时间:2008-04-15  
看到就头疼 还要自己把内容复制放到eclipse里面
0 请登录后投票
   发表时间:2008-04-16  
请问LZ,把你的代码采用hibernate annotations的方式改写,自定义用户类型如何使其映射为List呢?
0 请登录后投票
   发表时间:2008-04-18  
这么麻烦,用@CollectionOfElements了事
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics