數據庫中存在一個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-07-05 14:46 knowhow 閱讀(301) 評論(0)  編輯  收藏 所屬分類: ORM:Hibernate及其他
          主站蜘蛛池模板: 江山市| 太谷县| 朝阳市| 门头沟区| 台前县| 榆树市| 揭阳市| 巴塘县| 太仆寺旗| 四子王旗| 体育| 高台县| 库车县| 阳春市| 南安市| 峨山| 宾阳县| 诸暨市| 塔城市| 长顺县| 靖安县| 岫岩| 泰宁县| 邵阳县| 邯郸县| 崇义县| 彭山县| 汽车| 阜宁县| 蕲春县| 阿合奇县| 麻阳| 仲巴县| 镇原县| 习水县| 那曲县| 万盛区| 北流市| 东源县| 包头市| 永宁县|