posts - 241,  comments - 116,  trackbacks - 0
          Hibernate的強(qiáng)大用過的童鞋肯定會(huì)知道的,通過OR映射我們可以很方便的實(shí)現(xiàn)數(shù)據(jù)庫操作,Hibernate對(duì)我們一些類型的映射都提供了 很好的支持,但是顯然也有不給力的地方,比如簡單的注冊(cè),一個(gè)人可能有好多郵箱,對(duì)于這個(gè)問題怎么做呢?有人說簡單,可以另外開一張表,恩,很不錯(cuò),確實(shí) 可以,可是這樣有時(shí)候可能小題大作了。也有人說,直接將郵箱拼接成字符串然后在存儲(chǔ),這個(gè)想法也很好,但在我們讀出來的時(shí)候就要再進(jìn)行一次解析操作,將 EMAIL還原,這些都要求我們編程人員自己完成。那么Hibernate有沒有提供什么好的支持呢?回答是肯定的,Hibernate給我們提供了一個(gè) UserType接口,通過UserType我們可以對(duì)一些常見的類型進(jìn)行封轉(zhuǎn),轉(zhuǎn)變成具有個(gè)性的類型。下面我們就來體驗(yàn)一下吧: 債務(wù)追討

              首先我么創(chuàng)建一個(gè)自定義類型的類,讓他實(shí)現(xiàn)UserType接口:

          /**
           * @author :LYL
           *@date:2011-4-26,下午08:39:42
           */
          package com.lyl.hibernate.mytype;

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

          import com.opensymphony.oscache.util.StringUtil;

          public class ArrayType implements UserType{

              private static final char Spliter=';';

              /**
               * 自定義類型的完全復(fù)制方法,構(gòu)造返回對(duì)象
               *    1. 當(dāng)nullSafeGet方法調(diào)用之后,我們獲得了自定義數(shù)據(jù)對(duì)象,在向用戶返回自定義數(shù)據(jù)之前
               * deepCopy方法被調(diào)用,它將根據(jù)自定義數(shù)據(jù)對(duì)象構(gòu)造一個(gè)完全拷貝,把拷貝返還給客戶使用。
               *    2.此時(shí)我們就得到了自定義數(shù)據(jù)對(duì)象的兩個(gè)版本
               *     原始版本由hibernate維護(hù),用作臟數(shù)據(jù)檢查依據(jù),復(fù)制版本由用戶使用,hibernate將在
               * 臟數(shù)據(jù)檢查過程中比較這兩個(gè)版本的數(shù)據(jù)。人人
               *
               *
               */
              @Override
              public Object deepCopy(Object value) throws HibernateException {
                  List source=(List)value;
                  List target=new ArrayList();
                  target.addAll(source);
                  return target;
              }

              /**
               * 自定義數(shù)據(jù)類型比對(duì)方法
               * 用作臟數(shù)據(jù)檢查,X,Y為兩個(gè)副本
               */
              @Override
              public boolean equals(Object x, Object y) throws HibernateException {
                  if (x==y) {
                      return true;
                  }
                  if(x!=null&&y!=null){
                      List xList=(List)x;
                      List ylList=(List)y;
                      if (xList.size()!=ylList.size()) {
                          return false;
                      }
                      for(int i=0;i<xList.size();i++){
                          String s1=(String)xList.get(i);
                          String s2=(String)ylList.get(i);
                          if (!s1.equals(s2)) {
                              return false;
                          }
                      }
                      return true;
                  }
                  return false;
              }

              /**
               * 返回給定類型的hashCode
               */
              @Override
              public int hashCode(Object value) throws HibernateException {
                  return value.hashCode();
              }

              /**
               * 表示本類型實(shí)例是否可變
               */
              @Override
              public boolean isMutable() {
                  // TODO Auto-generated method stub
                  return false;
              }

              /**
               * 讀取數(shù)據(jù)轉(zhuǎn)換為自定義類型返回
               * names包含了自定義類型的映射字段名稱
               */
              @SuppressWarnings("deprecation")
              @Override
              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;
                  }

              }

              /**
               * 數(shù)據(jù)保存時(shí)被調(diào)用
               */
              @Override
              public void nullSafeSet(PreparedStatement ps, Object value, int index)
              throws HibernateException, SQLException {
                  if(value!=null){
                      String str=combain((List)value);
                      //保存數(shù)據(jù)
                      Hibernate.STRING.nullSafeSet(ps, str,index);
                  }else {
                      //空值就直接保存了
                      Hibernate.STRING.nullSafeSet(ps,value.toString(),index);
                  }
              }

              /**
               * 將數(shù)據(jù)解析為LIST返回
               * @param value
               * @return
               */
              private List parse(String value){
                  List list=StringUtil.split(value, Spliter);
                  return list;
              }

              private String combain(List list){
                  StringBuffer sb=new StringBuffer();
                  for(int i=0;i<list.size()-1;i++){
                      sb.append(list.get(i)).append(Spliter);
                  }
                  sb.append(list.get(list.size()-1));
                  return sb.toString();
              }

              /**
               * 修改類型對(duì)應(yīng)的java類型
               * 我們這邊使用LIST類型
               */
              @Override
              public Class returnedClass() {
                  return List.class;
              }

              /**
               * 修改類型對(duì)應(yīng)的SQL類型
               * 使用VARCHAR
               */
              @Override
              public int[] sqlTypes() {
                  return new int[]{Types.VARCHAR};
              }

              @Override
              public Object replace(Object arg0, Object arg1, Object arg2)
              throws HibernateException {
                  return null;
              }

              /**
               * 不知干嘛用的
               */
              @Override
              public Object assemble(Serializable arg0, Object arg1)
              throws HibernateException {
                  return null;
              }
              @Override
              public Serializable disassemble(Object arg0) throws HibernateException {
                  return null;
              }
          }

          然后我們?cè)谂渲肙R映射文件時(shí),指定一下自己的類型:

          <property name="emails" column="emails" type="com.lyl.hibernate.mytype.ArrayType"/>

          posted on 2011-04-28 09:25 墻頭草 閱讀(3291) 評(píng)論(0)  編輯  收藏

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          人人游戲網(wǎng) 軟件開發(fā)網(wǎng) 貨運(yùn)專家
          主站蜘蛛池模板: 镇安县| 延吉市| 攀枝花市| 宁南县| 马关县| 乌审旗| 威远县| 尤溪县| 凤凰县| 华蓥市| 台南县| 佳木斯市| 临邑县| 绍兴市| 渭源县| 平塘县| 永新县| 黑山县| 江津市| 锡林郭勒盟| 华容县| 游戏| 高青县| 阳新县| 子洲县| 利津县| 独山县| 抚顺县| 庐江县| 亚东县| 浪卡子县| 芮城县| 岱山县| 横峰县| 荣昌县| 平和县| 太湖县| 昌江| 巴彦淖尔市| 盱眙县| 宜川县|