Hibernate映射自定義數據類型

          數據庫中存在一個email字段,并允許其中存儲多個email地址,各地址之間使用 ; 分割,但是在POJO中,為了便于處理,email定義為一個List對象。
          如何將String字段映射為List類型,Hibernate并沒有提供原生支持,需要我們實現自己的UserType。
          1.數據庫定義

          DROP   TABLE  t_user_mail;

          CREATE   TABLE  t_user_mail (
                 id 
          INT   NOT   NULL  AUTO_INCREMENT
               , name 
          VARCHAR ( 50 )
               , age 
          INT
               , email 
          VARCHAR ( 300 )
               , 
          PRIMARY   KEY  (id)
          );


          2.
          實現了UserType的自定義數據類型類EMailList

          package  cn.blogjava.usertype;

          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.Hibernate;
          import  org.hibernate.HibernateException;
          import  org.hibernate.usertype.UserType;

          public   class  EMailList  implements  UserType {

              
          private   static   final   char  SPLITTER =   ' ; ' ;
              
          private   static   final   int [] TYPES  =   new   int [] {Types.VARCHAR};
              
              
          public   int [] sqlTypes() {
                  
          //  TODO Auto-generated method stub
                   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   int  hashCode(Object arg0)  throws  HibernateException {
                  
          //  TODO Auto-generated method stub
                   return   0 ;
              }

              
          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 {
                  
          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() {
                  
          //  TODO Auto-generated method stub
                   return   false ;
              }

              
          public  Serializable disassemble(Object arg0)  throws  HibernateException {
                  
          //  TODO Auto-generated method stub
                   return   null ;
              }

              
          public  Object assemble(Serializable arg0, Object arg1)
                      
          throws  HibernateException {
                  
          //  TODO Auto-generated method stub
                   return   null ;
              }

              
          public  Object replace(Object arg0, Object arg1, Object arg2)
                      
          throws  HibernateException {
                  
          //  TODO Auto-generated method stub
                   return   null ;
              }
              
              
          private  String assemble(List emailList) {
                  StringBuffer strBuf 
          =   new  StringBuffer();
                  
          for  ( int  i  =   0 ; i  <  emailList.size() - 1 ; i ++ ) {
                      strBuf.append((String)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;
              }

          }


          3.
          配置文件TUserMail.hbm.xml
          <?xml version="1.0"?>
          <!DOCTYPE hibernate-mapping PUBLIC 
          "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
          <hibernate-mapping>
          <!-- 
                  Auto-generated mapping file from
                  the hibernate.org cfg2hbm engine
          -->
              <class name
          ="cn.blogjava.usertype.TUserMail" table="t_user_mail" catalog="sample">
                  <id name
          ="id" type="integer">
                      <column name
          ="id" />
                      <generator class
          ="native" />
                  </id>
                  <property name
          ="name" type="string">
                      <column name
          ="name" length="50" />
                  </property>
                  <property name
          ="age" type="integer">
                      <column name
          ="age" />
                  </property>
                  <property name
          ="email" type="cn.blogjava.usertype.EMailList">
                      <column name
          ="email" length="300" />
                  </property>
              </class>
          </hibernate-mapping>

          4.
          在hibernate.cfg.xml載入TUserMail.hbm.xml
          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE hibernate-configuration PUBLIC
                  
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
                  
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
          <hibernate-configuration>
              <session-factory>
                  <property name
          ="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
                  <property name
          ="hibernate.connection.password">1234</property>
                  <property name
          ="hibernate.connection.url">jdbc:mysql://localhost:3306/sample</property>
                  <property name
          ="hibernate.connection.username">root</property>
                  <property name
          ="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
                  <mapping resource
          ="cn/blogjava/start/TUser.hbm.xml" />
                  <mapping resource
          ="cn/blogjava/usertype/TUserMail.hbm.xml" />
              </session-factory>
          </hibernate-configuration>

          5.
          測試類HibernateTest.java
          package cn.blogjava.usertype;

          import java.util.ArrayList;
          import java.util.List;

          import junit.framework.Assert;
          import junit.framework.TestCase;

          import org.hibernate.HibernateException;
          import org.hibernate.Session;
          import org.hibernate.SessionFactory;
          import org.hibernate.Transaction;
          import org.hibernate.cfg.Configuration;


          public class HibernateTest extends TestCase {
              
              Session session 
          = null;
              
          /**
               * JUnit中的setUp方法在TestCase初始化的時候會自動調用
               * 一般用于初始化公用資源
               
          */
              
          protected void setUp() {
                  
          try {
                      
          /**
                       * 可以采用hibernate.properties或者hibernate.cfg.xml
                       * 配置文件的初始化代碼
                       * 
                       * 采用hibernate.properties
                       * Configuration config = new Configuration();
                       * config.addClass(TUser.class);
                       
          */
                      
                      
          //采用hibernate.cfg.xml配置文件,與上面的方法對比,兩個差異
                      
          //1.Configuration的初始化方式
                      
          //2.xml
                      Configuration config = new Configuration().configure();
                      SessionFactory sessionFactory 
          = config.buildSessionFactory();
                      session 
          = sessionFactory.openSession();
                      
                  } 
          catch (HibernateException e) {
                      
          // TODO: handle exception
                      e.printStackTrace();
                  }        
              }

              
          /**
               * JUnit中的tearDown方法在TestCase執行完畢的時候會自動調用
               * 一般用于釋放資源
               
          */    
              
          protected void tearDown() {
                  
          try {
                      session.close();        
                  } 
          catch (HibernateException e) {
                      
          // TODO: handle exception
                      e.printStackTrace();
                  }        
              }    
              
              
          /**
               * 對象持久化測試(Insert方法)
               
          */        
              
          public void testInsert() {
                  Transaction tran 
          = null;
                  
          try {
                      tran 
          = session.beginTransaction();
                      TUserMail user 
          = new TUserMail();
                      user.setName(
          "byf");
                      List list 
          = new ArrayList();
                      list.add(
          "baiyf@msn.com");
                      list.add(
          "bexy@163.com");
                      user.setEmail(list);
                      session.save(user);
                      session.flush();
                      tran.commit();
                      Assert.assertEquals(user.getId().intValue()
          >0 ,true);
                  } 
          catch (HibernateException e) {
                      
          // TODO: handle exception
                      e.printStackTrace();
                      Assert.fail(e.getMessage());
                      
          if(tran != null) {
                          
          try {
                              tran.rollback();
                          } 
          catch (Exception e1) {
                              
          // TODO: handle exception
                              e1.printStackTrace();
                          }
                      }
                  }
              }
              
              
          /**
               * 對象讀取測試(Select方法)
               
          */            
              
          public void testSelect(){
                  String hql 
          = " from TUserMail where name='byf'";
                  
          try {
                      List userList 
          = session.createQuery(hql).list();
                      TUserMail user 
          = (TUserMail)userList.get(0);
                      List mailList 
          = user.getEmail();

                      Assert.assertEquals((String)mailList.get(
          0), "baiyf@msn.com");
                      Assert.assertEquals((String)mailList.get(
          1), "bexy@163.com");
                  } 
          catch (Exception e) {
                      
          // TODO: handle exception
                      e.printStackTrace();
                      Assert.fail(e.getMessage());
                  }
              }
          }

          運行測試代碼,觀察數據庫中,可以發現email地址信息已經以";"分隔的形式保存。同時,在數據讀取時,我們也無需面對原始的";"分隔字符串,轉而只需要處理List類型數據即可。

          posted on 2006-06-29 16:36 baim 閱讀(1966) 評論(2)  編輯  收藏 所屬分類: 開源軟件框架

          評論

          # re: Hibernate映射自定義數據類型 2006-08-14 15:16 kocr

          其實作者應該在文中給出數據庫的響應表結構和關聯關系,這樣給人一目了然和清晰的感覺。個人愚見。  回復  更多評論   

          # re: Hibernate映射自定義數據類型[未登錄] 2007-08-27 18:56 哈哈

          Could not determine type for: entity.EMailList, for columns: [org.hibernate.mapping.Column(email)

          為什么老是報這個錯誤  回復  更多評論   

          <2006年6月>
          28293031123
          45678910
          11121314151617
          18192021222324
          2526272829301
          2345678

          導航

          常用鏈接

          隨筆分類(27)

          隨筆檔案(28)

          搜索

          最新評論

          主站蜘蛛池模板: 勐海县| 呼伦贝尔市| 东安县| 尤溪县| 台山市| 曲阜市| 凯里市| 静宁县| 盐源县| 保靖县| 浮梁县| 洞头县| 扎鲁特旗| 农安县| 永德县| 明光市| 昌都县| 盱眙县| 永平县| 饶河县| 宁远县| SHOW| 大安市| 瑞丽市| 尼勒克县| 原平市| 涡阳县| 苍山县| 天等县| 班戈县| 芷江| 彩票| 沽源县| 阿拉善盟| 呼玛县| 偏关县| 织金县| 永福县| 连州市| 集贤县| 剑川县|