大漠駝鈴

          置身浩瀚的沙漠,方向最為重要,希望此blog能向大漠駝鈴一樣,給我方向和指引。
          Java,Php,Shell,Python,服務(wù)器運(yùn)維,大數(shù)據(jù),SEO, 網(wǎng)站開(kāi)發(fā)、運(yùn)維,云服務(wù)技術(shù)支持,IM服務(wù)供應(yīng)商, FreeSwitch搭建,技術(shù)支持等. 技術(shù)討論QQ群:428622099
          隨筆 - 238, 文章 - 3, 評(píng)論 - 117, 引用 - 0
          數(shù)據(jù)加載中……

          JPA annotation 筆記

          @Id 顧名思義,就不多說(shuō)了。

          @GeneratedValue:主鍵的產(chǎn)生策略,通過(guò)strategy屬性指定。
          默認(rèn)情況下,JPA自動(dòng)選擇一個(gè)最適合底層數(shù)據(jù)庫(kù)的主鍵生成策略,如SqlServer對(duì)應(yīng)identity,MySql對(duì)應(yīng)auto increment。
          在javax.persistence.GenerationType中定義了以下幾種可供選擇的策略:
          1) IDENTITY:表自增鍵字段,Oracle不支持這種方式;
          2) AUTO: JPA自動(dòng)選擇合適的策略,是默認(rèn)選項(xiàng);
          3) SEQUENCE:通過(guò)序列產(chǎn)生主鍵,通過(guò)@SequenceGenerator注解指定序列名,MySql不支持這種方式;
          4) TABLE:通過(guò)表產(chǎn)生主鍵,框架借由表模擬序列產(chǎn)生主鍵,使用該策略可以使應(yīng)用更易于數(shù)據(jù)庫(kù)移植。

          這里我重點(diǎn)來(lái)說(shuō)下GenerationType.TABLE的情況。
          把庫(kù)表的主鍵auto_increment去掉
          CREATE TABLE `t_creditcard` (   
            `id` int(11) NOT NULL,   
            `cardName` varchar(20) NOT NULL,   
            PRIMARY KEY  (`id`)   
          ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

          CREATE TABLE `id_gen` (
            `gen_name` varchar(80) NOT NULL default '',
            `gen_val` int(11) default NULL,
            PRIMARY KEY  (`gen_name`)
          ) ENGINE=InnoDB DEFAULT CHARSET=gbk;

          @Entity
          @Table(name="t_creditcard")
          public class CreditCard{
              @TableGenerator(name = "CardPkGen",
                        table = "ID_GEN",
                        pkColumnName = "GEN_NAME",
                        pkColumnValue = "Card_Gen",
                        valueColumnName = "GEN_VAL",
                        allocationSize = 1
              )
              @Id
              @GeneratedValue(strategy=GenerationType.TABLE,generator="CardPkGen")
              private Long id;


          @GeneratedValue:定義主鍵生成策略,這里因?yàn)槭褂玫氖荰ableGenerator,所以,主鍵的生成策略為GenerationType.TABLE,生成主鍵策略的名稱(chēng)則為前面定義的"CardPkGen”。
          @TableGenerator各屬性含義如下:
          name:表示該表主鍵生成策略的名稱(chēng),這個(gè)名字可以自定義,它被引用在@GeneratedValue中設(shè)置的"generator"值中
          table:表示表生成策略所持久化的表名,說(shuō)簡(jiǎn)單點(diǎn)就是一個(gè)管理其它表主鍵的表,本例中,這個(gè)表名為ID_GEN
          pkColumnName:表生成器中的列名,用來(lái)存放其它表的主鍵鍵名,一般來(lái)說(shuō)一個(gè)主鍵鍵名對(duì)應(yīng)一張其他表要獲取主鍵值對(duì)應(yīng)的key。這個(gè)值要與數(shù)據(jù)庫(kù)的列對(duì)應(yīng),比如GEN_NAME對(duì)應(yīng)id_gen中的主鍵名稱(chēng)
          pkColumnValue:該實(shí)體所要訪問(wèn)對(duì)應(yīng)主鍵生成表的主鍵的key值
          valueColumnName:表生成器所要對(duì)應(yīng)pkColumnName主鍵的下一個(gè)值,這個(gè)值也要和表生成器中的列名對(duì)應(yīng)
          allocationSize:表示每次主鍵值增加的大小,例如設(shè)置成1,則表示每次創(chuàng)建新記錄后自動(dòng)加1,默認(rèn)為50

          按照以上結(jié)構(gòu),如果我們執(zhí)行:
          CreditCard cc = new CreditCard();
          cc.setCardName("測(cè)試卡");
          cc = ccDao.persist(cc);



          表id_gen內(nèi)的數(shù)據(jù)為

          GEN_NAME GEN_VALUE
          Card_Gen  2

          表t_creditcard內(nèi)的數(shù)據(jù)為

          ID CARDNAME
          1   測(cè)試卡

          再執(zhí)行一次程序
          表id_gen內(nèi)的數(shù)據(jù)為

          GEN_NAME GEN_VALUE
          Card_Gen  3

          表t_creditcard內(nèi)的數(shù)據(jù)為

          ID CARDNAME
          1   測(cè)試卡
          2   測(cè)試卡

          把實(shí)體類(lèi)的annation改寫(xiě)為:
          @Entity
          @Table(name="t_creditcard")
          public class CreditCard{
              @TableGenerator(name = "CardPkGen",
                        table = "ID_GEN",
                        pkColumnName = "GEN_NAME",
                        pkColumnValue = "Card_Gen2",
                        valueColumnName = "GEN_VAL",
                        allocationSize = 1
              )
              @Id
              @GeneratedValue(strategy=GenerationType.TABLE,generator="CardPkGen")
              private Long id;


          注意看,pkColumnValue已經(jīng)被改為Card_Gen2。

          執(zhí)行程序,插入數(shù)據(jù)失敗,拋出t_creditcard表主鍵重復(fù)的異常,因?yàn)檫@次去名為Card_Gen2的這個(gè)主鍵生成器去拿來(lái)的id為1,t_creditcard表之前已經(jīng)插入過(guò)一條主鍵為1的數(shù)據(jù)了。

          表id_gen內(nèi)的數(shù)據(jù)為

          GEN_NAME GEN_VALUE
          Card_Gen  3
          Card_Gen2  2

          表t_creditcard內(nèi)的數(shù)據(jù)還是為

          ID CARDNAME
          1   測(cè)試卡
          2   測(cè)試卡

          結(jié)論:在有些應(yīng)用中,我們可以適用@TableGenerator來(lái)統(tǒng)一管理我們數(shù)據(jù)庫(kù)中的各個(gè)表的主鍵生成,如果我們的應(yīng)用中有10個(gè)實(shí)體需要使用自動(dòng)生成的主鍵,只需在每個(gè)實(shí)體中使用@TableGenerator并給出不同的pkColumnValue值就可以了。

          @Id還有一些另類(lèi)的用法:

          1.使用系統(tǒng)毫秒數(shù)作為主鍵
          @Id
          private Long id = System.currentTimeMillis();
          CreditCard cc = new CreditCard();
          cc.setCardName("測(cè)試卡");
          cc = ccDao.persist(cc);


          2.使用UUID作為主鍵
          @Id
          private String id;;

          CreditCard cc = new CreditCard();
          cc.setId(UUID.randomUUID().toString());
          cc.setCardName("測(cè)試卡");
          cc = ccDao.persist(cc);



          別忘了修改庫(kù)表中主鍵字段的大小和對(duì)應(yīng)的類(lèi)型.

          posted on 2009-02-22 22:08 草原上的駱駝 閱讀(1664) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): JAVA框架

          主站蜘蛛池模板: 樟树市| 台州市| 成都市| 平定县| 泰兴市| 赣榆县| 玉树县| 盐亭县| 西青区| 潜山县| 泾阳县| 伊春市| 和政县| 石家庄市| 定安县| 克山县| 绍兴县| 洛扎县| 区。| 五家渠市| 木里| 壶关县| 河津市| 定襄县| 三都| 湾仔区| 潮州市| 黄冈市| 东丰县| 黄陵县| 民县| 萝北县| 永善县| 泰安市| 特克斯县| 丰城市| 江川县| 昌平区| 嵊泗县| 五华县| 师宗县|