西沙璞玉
          愛不容易
          posts - 0,comments - 4,trackbacks - 0

          在關(guān)聯(lián)關(guān)系的映射中使用得最多的就是一對多的關(guān)聯(lián),一對多的關(guān)聯(lián)關(guān)系分為兩種:單向一對多,雙向一對多。下面分別對這兩種情況進行總結(jié):


          首先準備兩張表:用戶表user和用戶組表group


           




          Sql代碼


          1. CREATE TABLE  
            `test`.`
            group` (  
          2.    `id` int(10) unsigned NOT NULL auto_increment,  
          3.    `name` varchar(45) NOT NULL,  
          4.   PRIMARY KEY  
            (`id`)  

          5. )  
          6.  
          7.  
          8. CREATE TABLE  
            `test`.`
            user` (
             

          9.    `id` int(10) unsigned NOT NULL auto_increment,  
          10.    `name` varchar(45) NOT NULL,  
          11.    `group_id` int(10) unsigned default
            NULL,  
          12.   PRIMARY KEY  
            (`id`),  

          13.   KEY `FK_users_1` (`group_id`),
             

          14.   CONSTRAINT `FK_users_1` FOREIGN
            KEY (`group_id`) REFERENCES `group`
            (`id`)  

          15. )  

          首先,來看看單向一對多的情況:


          Group類中有如下屬性:


           




          Java代碼


          1. private Integer id;  
          2. private String name;  
          3. private Set users = new
            HashSet(
            0);//用戶的set集合,用于存一對多中的“多”的一方 

          User類只需要有本身的屬性即可:


           




          Java代碼


          1. private Integer id;  
          2. private String name; 

          接下來才是重點,配置單向一對多之間的關(guān)聯(lián)


          Group.hbm.xml文件的配置如下:


           




          Xml代碼


          1. <hibernate-mapping> 
          2.     <class
            name="com.stream.model.Group" table="group"
            catalog="test"> 

          3.         <id
            name="id" type="java.lang.Integer"> 
          4.             <column
            name="id" /> 
          5.             <generator
            class="identity" /> 
          6.         </id> 
          7.         <property
            name="name" type="java.lang.String"> 
          8.             <column
            name="name" length="45" not-null="true"
            /> 
          9.         </property> 
          10.                 <!-- 以下是單向一對多的配置信息--> 
          11.         <set
            name="users" inverse="false"
            cascade="all"> 

          12.             <key> 
          13.                 <!-- 指定user表中引用外鍵的是哪一列--> 
          14.                 <column
            name="group_id"/> 
          15.             </key> 
          16.             <!--配置是與哪一個類之間的一對多 --> 
          17.             <one-to-many class="com.stream.model.User" /> 
          18.         </set> 
          19.     </class> 
          20. </hibernate-mapping> 

          在該配置文件中,inverse可以使用默認false,或者顯示指定false,如以上代碼。這樣就指定一對多之間的關(guān)系由group這個POJO來維護。在單項一對多關(guān)聯(lián)中,這一點很重要,下面我們通過測試來說明。cascade="all"指定級聯(lián)的之間的等級,它具有如下幾種值:


          all : 所有情況下均進行關(guān)聯(lián)操作。

          none:所有情況下均不進行關(guān)聯(lián)操作。這是默認值。

          save-update:在執(zhí)行save/update/saveOrUpdate時進行關(guān)聯(lián)操作。

          delete:在執(zhí)行delete時進行關(guān)聯(lián)操作。


          user.hbm.xml文件的配置與User這個類一樣,不需要包含如何關(guān)于關(guān)聯(lián)關(guān)系的配置:


           




          Xml代碼


          1. <class name="com.stream.model.User" table="user"
            catalog="test"> 

          2.         <id
            name="id" type="java.lang.Integer"> 
          3.             <column
            name="id" /> 
          4.             <generator
            class="identity" /> 
          5.         </id> 
          6.         <property
            name="name" type="java.lang.String"> 
          7.             <column
            name="name" length="45" not-null="true"
            /> 
          8.         </property> 
          9. </class> 

          下面只舉單向一對多關(guān)聯(lián)保存一例來說明,其他操作類似:


           




          Java代碼


          1.                 
          2.                Group group = new Group();  
          3. group.setName("group1");  
          4. User user1   = new User();  
          5. user1.setName("stream");  
          6. User user2 = new User();  
          7. user2.setName("fangqi");  
          8.               //添加用戶
             
          9. group.getUsers().add(user1);  
          10. group.getUsers().add(user2);  
          11.               //開啟事務(wù)
             
          12. Transaction transaction =session.beginTransaction();  
          13. //保存用戶組
             
          14.                session.save(group);  
          15.               //將緩沖區(qū)中的sql送到數(shù)據(jù)庫中  
          16. session.flush();  
          17.               //提交事務(wù)
             
          18. transaction.commit(); 

          我們沒有顯示的插入user1和uesr2兩條記錄,但是由于我們設(shè)置了cascade=all,那么在group表進行任何操作時都會關(guān)聯(lián)到user表,即在保存group時,也會把user1和user2保存,這就是級聯(lián)為我們帶來的好處。


          但是,在這里有兩點需要說明的是:


          1、如果在Group.hbm.xml映射文件中設(shè)置了inverse=true,那么說明這個一對多的關(guān)聯(lián)關(guān)系由多的一方來維護。而在單向的一對多關(guān)聯(lián)中,“多”的一方完全不知情,所以在保存往user
          表中插入的兩條數(shù)據(jù),其外鍵group_id這一字段都是為null值。如果user表中g(shù)roup_id是not null的話就會出現(xiàn)如下異常:


           


          org.hibernate.exception.GenericJDBCException: could not insert:
          [com.stream.model.User]


          ....


          Caused by: java.sql.SQLException: Field 'group_id' doesn't have a default
          value。


          異常信息室group_id這個字段沒有設(shè)置一個默認值,其實就是我們往group_id這個非空的字段插入了一個null值。


          2、如果再Group.hbm.xml映射文件中設(shè)置inverse=false,或者不設(shè)置該屬性,即表示由自身來維護這個關(guān)聯(lián)關(guān)系。但在保存group后,會先將user1和user2插入到數(shù)據(jù)庫,并且group_id的值都為null。然后再接著兩條update語句,將這兩天記錄的group_id字段值設(shè)置為前面插入的group的id。同樣的如果user
          表中g(shù)roup_id字段是非空的,仍然會出現(xiàn)上面的異常。


          ---------------------------------------------單向一對多的關(guān)聯(lián)完畢----------------------------------------------------------


          除了一對多雙向關(guān)聯(lián)關(guān)系的"many"方設(shè)為true、多對多雙向關(guān)聯(lián)關(guān)系的兩方設(shè)為true之外,其余應(yīng)均為false


          posted on 2012-05-02 16:06 @趙 閱讀(304) 評論(0)  編輯  收藏

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


          網(wǎng)站導(dǎo)航:
           
          哥哥最近不是很忙
          主站蜘蛛池模板: 黑水县| 莎车县| 布拖县| 农安县| 红桥区| 库尔勒市| 望城县| 古浪县| 晋州市| 招远市| 乐昌市| 玉树县| 商南县| 萨迦县| 比如县| 图木舒克市| 昭平县| 民权县| 黄浦区| 巴东县| 新干县| 大埔区| 乐昌市| 通榆县| 隆德县| 阳春市| 新源县| 鄄城县| 谢通门县| 黄梅县| 高碑店市| 阜南县| 沐川县| 临夏市| 安新县| 长海县| 泰顺县| 高清| 马边| 墨玉县| 雅安市|