如鵬網 大學生計算機學習社區

          CowNew開源團隊

          http://www.cownew.com 郵件請聯系 about521 at 163.com

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            363 隨筆 :: 2 文章 :: 808 評論 :: 0 Trackbacks

          工廠方法模式
             
          以可移植的、可擴展的方式來生成流水號EJB應用中的一個難點。 現在比較成熟的流水號生成策略有全局唯一標識(即UUID)和使用數據庫內置流水號生成策略。全局唯一標識有單件模式、根據網絡標識(Mac地址+IPJVM唯一對象標識)等策略。不同的數據庫也有不同的流水號生成策略:例如Oracle采用內置流水號產生機制,SQL Server則采用Identity機制。這給我們帶來方便的同時也使得應用程序在不同系統之間移植變得很麻煩。我采用工廠方法模式解決這個問題。
            
          結構圖


          我們首先定義一個基類接口,它定義了各種唯一序列生成器的共同的方法。
          abstract public interface SequenceCreator {
            abstract public String getSequenceId(String aId);
            abstract public Integer getSequenceAsInt(String aId);
          }
           
          兩個函數的參數aId是不同流水號生成標識。getSequenceId是產生以字符串形式返回的流水號,getSequenceAsInt是以整形形式返回流水號。為了防止無謂的重復,下面的實例中我們將只寫各個方法的getSequenceId實現。

          1)我們首先看SQLSequenceCreator的實現代碼

              Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

              Connection con = java.sql.DriverManager.getConnection("jdbc:odbc:DNSEJB");

              CallableStatement cs = con.prepareCall("{call SetIndex(?,?,?)}");

              cs.registerOutParameter(2,Types.VARCHAR);

              cs.setString(1,aId);

              cs.setInt(3,10);

              cs.executeUpdate();

              String str= cs.getString(2);

              return str.substring(aId.length(), str.length());

          我們是調用我們自定義的存儲過程來生成流水號的,存儲過程的代碼請參看代碼。

          2Oracle的實現代碼

          String strSQL = "select " + sequence_name + ".nextval from DUAL";

              Statement  stmt = conn.createStatement();

              ResultSet rs = stmt.executeQuery(strSQL);

              rs.next();

          return rs.getString(1);

          Oracle對流水號生成提供了比較好的支持,而且Oracle的生成策略也比SQLServer更高效,消耗更少的資源,資源鎖定情況也比SQLServer少。

          3

          UUID的實現代碼

          InetAddress inet = InetAddress .getLocalHost();

          Byte[] bytes = inet.getAddress();

          String hexInetAddress = hexFormat(getInt(bytes),8);

          String thisHashCode=hexFormat(System.identityHashCode(this),8);

          MideValue = hexInetAddress+thisHashCode;

          Seeder = new SecureRandom();

          In node = seeder.nextInt();

          Long timeNow = System.currentTimeMillis();

          Int timeLow = (int)timeNow&oxFFFFFFF;

          Int  node = seeder.nextInt();

          Return (hexFormat(timeLow,8)+mid+hexFormat(node,8));

              UUID是一個基于字符串的主鍵,他有一下字符串組合而成:利用System.currentTimeMillis()精確道毫秒的唯一、IP地址的十六進制標識、利用System.identityHashCode(this)得到的一個JVM內部的唯一地址標識和利用隨機數生成器生成隨機數。

           

          還有很多不同的流水號生成策略,我們不準備一一羅列。我們的主要問題是要解決在采用不同的序列生成策略時將代碼的修改減到最小。

          我們定義的SequenceCreator 類定義了所有流水號生成策略公共的方法,并且把這些方法定義為虛方法,在不同的流水號生成策略代碼中只要覆蓋這些方法即可。序列號生成器工廠類SequenceCreatorFactory getSquenceCreator()并不返回具體的流水號生成類,而是返回SequenceCreator,這樣當采用不同策略時只要修改getSquenceCreator方法即可。

          posted on 2006-03-11 00:11 CowNew開源團隊 閱讀(3019) 評論(1)  編輯  收藏

          評論

          # re: 工廠方法模式解決流水號生成問題 2006-03-11 11:37 Parker
          org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer  回復  更多評論
            


          只有注冊用戶登錄后才能發表評論。


          網站導航:
          博客園   IT新聞   Chat2DB   C++博客   博問  
           
          主站蜘蛛池模板: 洪湖市| 固安县| 长宁县| 上思县| 乳源| 晋宁县| 内黄县| 河津市| 黑水县| 洛川县| 汕尾市| 台中县| 沂源县| 阳山县| 丰都县| 化州市| 甘孜县| 田林县| 自治县| 凭祥市| 平舆县| 五指山市| 盐亭县| 海阳市| 鲜城| 武川县| 南江县| 陆良县| 梅河口市| 铜陵市| 比如县| 双峰县| 申扎县| 盘山县| 屏东市| 闵行区| 察雅县| 满城县| 奈曼旗| 新津县| 加查县|