posts - 70,comments - 408,trackbacks - 0

                Hibernate采用對(duì)象標(biāo)識(shí)符,也就是通常我們所說的OID來創(chuàng)建對(duì)象和數(shù)據(jù)庫表里記錄的對(duì)應(yīng)關(guān)系,對(duì)象的OID和表里的主鍵對(duì)應(yīng),所以說OID是非常重要的,不應(yīng)該讓程序來給它賦值.數(shù)據(jù)庫區(qū)分同一表的不同記錄是用主鍵來區(qū)分.數(shù)據(jù)庫中的主鍵最重要的3個(gè)基本要素就是不允許為null,不允許有重復(fù)值,主鍵永遠(yuǎn)不會(huì)改變.所以通常我們?cè)O(shè)計(jì)表都會(huì)設(shè)計(jì)主鍵的值為自動(dòng)增加,沒有業(yè)務(wù)邏輯含義的一組數(shù)字,當(dāng)然針對(duì)每個(gè)數(shù)據(jù)庫,設(shè)置的方法也不同.但是都非常簡單.加一個(gè)屬性就可以了.
                而JAVA區(qū)分同一類的不同對(duì)象是用內(nèi)存地址,在JAVA語言中判斷兩個(gè)對(duì)象的引用變量是否想相等,有以下兩種比較方式.1)用運(yùn)算符"=="比較內(nèi)存地址,此外還可以用Object的equals方法也是按內(nèi)存地址比較.2)比較兩個(gè)對(duì)象的值是否相同,JAVA中的一些覆蓋了Object類的equals方法實(shí)現(xiàn)比較合適.例如String和Date類,還有JAVA包裝類.如果是String.equals(String)這種方式的比較就是比較這兩個(gè)String的值的.如果是Object原是的equals方法就是比較地址了.這點(diǎn)很容易混淆.
                通常,為了包裝Hibernate的OID的唯一性和不可變性,由Hibernate或者底層數(shù)據(jù)庫來給OID賦值比較合理.因此我們?cè)诰幊痰臅r(shí)候最好把持久化類的OID設(shè)置為private或者protected類型,這樣可以防止JAVA程序隨便更改OID.而OID的get方法我們還是要設(shè)置為public類型,這樣方便我們讀取. 在對(duì)象-關(guān)系映射文件里的<id元素是用來設(shè)置對(duì)象標(biāo)識(shí)符OID的.type通常設(shè)置為long.而<generator子元素用來設(shè)置OID的標(biāo)識(shí)符生成器,Hibernate提供了標(biāo)識(shí)符生成器的接口net.sf.hibernate.id.IdentifierGenerator接口,并且提供了N多中內(nèi)置的實(shí)現(xiàn),和對(duì)應(yīng)的縮寫.我們只要把這些實(shí)現(xiàn)類的類名或者所寫設(shè)置在<generator子元素的class屬性中,就能完成OID的配置了.具體的內(nèi)置標(biāo)識(shí)符生成器如下:
                1)increment 代理主鍵,hibernate自動(dòng)以遞增的方式來生成標(biāo)識(shí)符,每次增加1.
                2)identity 代理主鍵,由底層數(shù)據(jù)庫生成標(biāo)識(shí)符,前提就是底層的數(shù)據(jù)庫支持自動(dòng)增長的類型.
                3)sequence 代理主鍵,hibernate根據(jù)底層數(shù)據(jù)庫生成的標(biāo)識(shí)符,前提是底層數(shù)據(jù)庫支持序列
                4)hilo 代理主鍵,hibernate根據(jù)higg/low算法來生成的標(biāo)識(shí)符,把特定表的字段作為high的值,默認(rèn)選用hibernate_unique_key表的next_hi字段
                5)native 代理主鍵,根據(jù)底層數(shù)據(jù)庫對(duì)自動(dòng)生成標(biāo)識(shí)符的支持能力,還選擇identity,sequence,或hilo.
                6)uuid.hex 代理主鍵,hibernate采用128位的UUID算法生成標(biāo)識(shí)符,UUID算法能夠在網(wǎng)絡(luò)環(huán)境下生成唯一字符串標(biāo)識(shí)符.不過字符串要比數(shù)據(jù)占用的空間多的多.所以不流行使用.
                7)assigned 適用于自然主鍵,由JAVA應(yīng)用程序負(fù)責(zé)生成標(biāo)識(shí)符,為了能讓JAVA設(shè)置OID.不能吧setId方法設(shè)置為非公共類型了,這種方式也盡量避免使用.
                這里個(gè)人覺得第一種方式,也就是說由Hibernate來生成對(duì)象標(biāo)識(shí)符的方式比較好.但是這種方式的缺點(diǎn)是只能一個(gè)Hibernate對(duì)應(yīng)一個(gè)數(shù)據(jù)庫的表.當(dāng)同時(shí)創(chuàng)建了SeesionFactory實(shí)例的時(shí)候.兩個(gè)或者更多的Hibernate對(duì)應(yīng)同一個(gè)數(shù)據(jù)庫的時(shí)候就會(huì)插入出錯(cuò).這個(gè)時(shí)候我們可以選擇第二種方式把標(biāo)識(shí)符的生成工作交給底層數(shù)據(jù)庫.還有一個(gè)小知識(shí)點(diǎn)要注意就是OID必須定義為long,int,short類型,如果定義為byte會(huì)報(bào)異常,這里推薦用long.
                總結(jié)一下,這7中生成OID標(biāo)識(shí)符的方法,increment 比較常用,把標(biāo)識(shí)符生成的權(quán)力交給Hibernate處理.但是當(dāng)同時(shí)多個(gè)Hibernate應(yīng)用操作同一個(gè)數(shù)據(jù)庫,甚至同一張表的時(shí)候.就推薦使用identity 依賴底層數(shù)據(jù)庫實(shí)現(xiàn),但是數(shù)據(jù)庫必須支持自動(dòng)增長,sequence 以來底層數(shù)據(jù)庫實(shí)現(xiàn),但是數(shù)據(jù)庫必須支持系列.hilo 根據(jù)特定的表實(shí)現(xiàn).這三種方式了.當(dāng)然針對(duì)不同的數(shù)據(jù)庫選擇不同的方法.如果你不能確定你使用的數(shù)據(jù)庫具體支持什么的情況下.可以選擇第三種.或者用native 讓Hibernate來幫選擇identity,sequence,或hilo.后邊的自然主鍵不推薦使用,因?yàn)樽匀恢麈I就是具有業(yè)務(wù)含義的主鍵,在現(xiàn)在的軟件開發(fā)結(jié)構(gòu)中,已經(jīng)很少有人用了.下面總結(jié)一下幾種常用數(shù)據(jù)庫,可以使用的標(biāo)識(shí)符類型.
                MySQL:identity數(shù)據(jù)庫底層實(shí)現(xiàn),需要支持自動(dòng)增長,increment由Hibernate實(shí)現(xiàn),hilo用特定的表實(shí)現(xiàn),
                MSSQL:identity數(shù)據(jù)庫底層實(shí)現(xiàn),需要支持自動(dòng)增長,increment由Hibernate實(shí)現(xiàn),hilo用特定的表實(shí)現(xiàn),
                Oracle:sequence數(shù)據(jù)庫底層實(shí)現(xiàn),需要支持序列,increment由Hibernate實(shí)現(xiàn),hilo用特定的表實(shí)現(xiàn),
                以上不難發(fā)現(xiàn),所有的數(shù)據(jù)庫都支持Hibernate用increment實(shí)現(xiàn)OID的生成,MYSQL和MSSQL數(shù)據(jù)庫底層實(shí)現(xiàn)支持自動(dòng)增長,而Oracle支持序列,還有用特殊表的實(shí)現(xiàn)方式這三個(gè)數(shù)據(jù)庫都支持.還有一種實(shí)現(xiàn)方式適用于所有的數(shù)據(jù)庫,就是native,由Hibernate去選擇使用什么樣的方式來生成IOD對(duì)象標(biāo)識(shí)符,這種方式也是跨平臺(tái)的.下面是各種設(shè)置方式的例子*.hbm.xml文件四個(gè).例題來源孫MM的<<精通Hibernate>>一書.我非常喜歡這本書,講的非常簡單明了.感興趣的朋友可以去買一本看看(當(dāng)當(dāng)打7.3折哦).
          <?xml version="1.0"?>
          <!DOCTYPE hibernate-mapping
          PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
          "<hibernate-mapping>

            <class name="mypack.HiloTester"  table="HILO_TESTER">
             
              <id name="id" type="long" column="ID">
              <generator class="hilo">
                          <param name="table">hi_value</param>
                          <param name="column">next_value</param>
                          <param name="max_lo">100</param>
                  </generator>
              </id>

              <property name="name" type="string" >
                  <column name="name" length="15" />
              </property>
             
            </class>
           
          </hibernate-mapping>

          <?xml version="1.0"?>
          <!DOCTYPE hibernate-mapping
          PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
          "
          <hibernate-mapping>

            <class name="mypack.IdentityTester"  table="IDENTITY_TESTER">
             
              <id name="id" type="long" column="ID">
                <generator class="identity"/>
              </id>

              <property name="name" type="string" >
                  <column name="name" length="15"/>
              </property>
             
            </class>
           
          </hibernate-mapping>

          <?xml version="1.0"?>
          <!DOCTYPE hibernate-mapping
          PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
          "
          <hibernate-mapping>

            <class name="mypack.NativeTester" table="NATIVE_TESTER" >
             
              <id name="id" type="long" column="ID">
                <generator class="native"/>
              </id>

              <property name="name" type="string" >
                  <column name="name" length="15" />
              </property>
             
            </class>
           
          </hibernate-mapping>

          <?xml version="1.0"?>
          <!DOCTYPE hibernate-mapping
          PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
          "
          <hibernate-mapping>

            <class name="mypack.IncrementTester" table="INCREMENT_TESTER" >
             
              <id name="id" type="long" column="ID">
                <meta attribute="scope-set">private</meta>
                <generator class="increment"/>
              </id>

              <property name="name" type="string" >
                  <column name="NAME" length="15" />
              </property>
             
            </class>
           
          </hibernate-mapping>


          FeedBack:
          # re: 映射對(duì)象標(biāo)識(shí)符
          2007-05-22 23:51 | 熱門單曲
          多謝樓主分享 頂了  回復(fù)  更多評(píng)論
            

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


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 谷城县| 新河县| 衡阳市| 恭城| 雅安市| 南漳县| 周宁县| 曲靖市| 凤山市| 依兰县| 高安市| 新郑市| 烟台市| 石城县| 江油市| 武冈市| 章丘市| 淮安市| 保定市| 留坝县| 宜良县| 阳江市| 瑞安市| 安乡县| 黄石市| 文成县| 北流市| 盱眙县| 鲁甸县| 安新县| 安陆市| 沧源| 沙洋县| 从江县| 晋州市| 凤台县| 邵武市| 台江县| 高清| 霍城县| 清徐县|