如鵬網(wǎng) 大學(xué)生計(jì)算機(jī)學(xué)習(xí)社區(qū)

          CowNew開源團(tuán)隊(duì)

          http://www.cownew.com 郵件請(qǐng)聯(lián)系 about521 at 163.com

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            363 隨筆 :: 2 文章 :: 808 評(píng)論 :: 0 Trackbacks

          工廠方法模式
             
          以可移植的、可擴(kuò)展的方式來生成流水號(hào)EJB應(yīng)用中的一個(gè)難點(diǎn)。 現(xiàn)在比較成熟的流水號(hào)生成策略有全局唯一標(biāo)識(shí)(即UUID)和使用數(shù)據(jù)庫(kù)內(nèi)置流水號(hào)生成策略。全局唯一標(biāo)識(shí)有單件模式、根據(jù)網(wǎng)絡(luò)標(biāo)識(shí)(Mac地址+IPJVM唯一對(duì)象標(biāo)識(shí))等策略。不同的數(shù)據(jù)庫(kù)也有不同的流水號(hào)生成策略:例如Oracle采用內(nèi)置流水號(hào)產(chǎn)生機(jī)制,SQL Server則采用Identity機(jī)制。這給我們帶來方便的同時(shí)也使得應(yīng)用程序在不同系統(tǒng)之間移植變得很麻煩。我采用工廠方法模式解決這個(gè)問題。
            
          結(jié)構(gòu)圖


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

          1)我們首先看SQLSequenceCreator的實(shí)現(xiàn)代碼

              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());

          我們是調(diào)用我們自定義的存儲(chǔ)過程來生成流水號(hào)的,存儲(chǔ)過程的代碼請(qǐng)參看代碼。

          2Oracle的實(shí)現(xiàn)代碼

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

              Statement  stmt = conn.createStatement();

              ResultSet rs = stmt.executeQuery(strSQL);

              rs.next();

          return rs.getString(1);

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

          3

          UUID的實(shí)現(xiàn)代碼

          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是一個(gè)基于字符串的主鍵,他有一下字符串組合而成:利用System.currentTimeMillis()精確道毫秒的唯一、IP地址的十六進(jìn)制標(biāo)識(shí)、利用System.identityHashCode(this)得到的一個(gè)JVM內(nèi)部的唯一地址標(biāo)識(shí)和利用隨機(jī)數(shù)生成器生成隨機(jī)數(shù)。

           

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

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

          posted on 2006-03-11 00:11 CowNew開源團(tuán)隊(duì) 閱讀(3022) 評(píng)論(1)  編輯  收藏

          評(píng)論

          # re: 工廠方法模式解決流水號(hào)生成問題 2006-03-11 11:37 Parker
          org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer  回復(fù)  更多評(píng)論
            


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


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 开远市| 阿拉尔市| 广州市| 临沭县| 龙口市| 玉龙| 溧阳市| 朝阳市| 孝昌县| 庆城县| 博兴县| 平原县| 乐平市| 济宁市| 社旗县| 桑日县| 会理县| 民权县| 东港市| 嘉义市| 海林市| 福建省| 嘉义县| 陆良县| 饶平县| 赣州市| 墨脱县| 恩施市| 阿拉善左旗| 临澧县| 河东区| 独山县| 博野县| 万宁市| 灵台县| 牙克石市| 宣威市| 靖远县| 濉溪县| 正阳县| 安仁县|