Hibernate映射自定義數(shù)據(jù)類型

          數(shù)據(jù)庫(kù)中存在一個(gè)email字段,并允許其中存儲(chǔ)多個(gè)email地址,各地址之間使用 ; 分割,但是在POJO中,為了便于處理,email定義為一個(gè)List對(duì)象。
          如何將String字段映射為L(zhǎng)ist類型,Hibernate并沒(méi)有提供原生支持,需要我們實(shí)現(xiàn)自己的UserType。
          1.數(shù)據(jù)庫(kù)定義

          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.
          實(shí)現(xiàn)了UserType的自定義數(shù)據(jù)類型類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.
          測(cè)試類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初始化的時(shí)候會(huì)自動(dòng)調(diào)用
               * 一般用于初始化公用資源
               
          */
              
          protected void setUp() {
                  
          try {
                      
          /**
                       * 可以采用hibernate.properties或者h(yuǎn)ibernate.cfg.xml
                       * 配置文件的初始化代碼
                       * 
                       * 采用hibernate.properties
                       * Configuration config = new Configuration();
                       * config.addClass(TUser.class);
                       
          */
                      
                      
          //采用hibernate.cfg.xml配置文件,與上面的方法對(duì)比,兩個(gè)差異
                      
          //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執(zhí)行完畢的時(shí)候會(huì)自動(dòng)調(diào)用
               * 一般用于釋放資源
               
          */    
              
          protected void tearDown() {
                  
          try {
                      session.close();        
                  } 
          catch (HibernateException e) {
                      
          // TODO: handle exception
                      e.printStackTrace();
                  }        
              }    
              
              
          /**
               * 對(duì)象持久化測(cè)試(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();
                          }
                      }
                  }
              }
              
              
          /**
               * 對(duì)象讀取測(cè)試(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());
                  }
              }
          }

          運(yùn)行測(cè)試代碼,觀察數(shù)據(jù)庫(kù)中,可以發(fā)現(xiàn)email地址信息已經(jīng)以";"分隔的形式保存。同時(shí),在數(shù)據(jù)讀取時(shí),我們也無(wú)需面對(duì)原始的";"分隔字符串,轉(zhuǎn)而只需要處理List類型數(shù)據(jù)即可。

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

          評(píng)論

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

          其實(shí)作者應(yīng)該在文中給出數(shù)據(jù)庫(kù)的響應(yīng)表結(jié)構(gòu)和關(guān)聯(lián)關(guān)系,這樣給人一目了然和清晰的感覺(jué)。個(gè)人愚見(jiàn)。  回復(fù)  更多評(píng)論   

          # re: Hibernate映射自定義數(shù)據(jù)類型[未登錄](méi) 2007-08-27 18:56 哈哈

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

          為什么老是報(bào)這個(gè)錯(cuò)誤  回復(fù)  更多評(píng)論   

          <2007年8月>
          2930311234
          567891011
          12131415161718
          19202122232425
          2627282930311
          2345678

          導(dǎo)航

          常用鏈接

          隨筆分類(27)

          隨筆檔案(28)

          搜索

          最新評(píng)論

          主站蜘蛛池模板: 泾阳县| 高碑店市| 淳安县| 福安市| 密云县| 九台市| 鱼台县| 将乐县| 五华县| 崇礼县| 罗甸县| 平利县| 邯郸县| 内丘县| 建水县| 镇原县| 册亨县| 思南县| 太白县| 邵东县| 莱芜市| 浑源县| 即墨市| 临海市| 寿阳县| 开封市| 余庆县| 凉城县| 恩平市| 乌拉特中旗| 司法| 永嘉县| 伊川县| 平昌县| 咸阳市| 福泉市| 赤水市| 沁阳市| 石台县| 河池市| 电白县|