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

在关联关系的映射中使用得最多的就是一对多的关联,一对多的关联关系分为两种:单向一对多,双向一对多。下面分别对这两种情况进行总结:


首先准备两张表:用户表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; 

接下来才是重点,配置单向一对多之间的关联


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,如以上代码。这样就指定一对多之间的关系由group这个POJO来维护。在单项一对多关联中,这一点很重要,下面我们通过测试来说明。cascade="all"指定级联的之间的等级,它具有如下几种值:


all : 所有情况下均进行关联操作。

none:所有情况下均不进行关联操作。这是默认值。

save-update:在执行save/update/saveOrUpdate时进行关联操作。

delete:在执行delete时进行关联操作。


user.hbm.xml文件的配置与User这个类一样,不需要包含如何关于关联关系的配置:


 




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> 

下面只举单向一对多关联保存一例来说明,其他操作类似:


 




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.               //开启事务
     
  12. Transaction transaction =session.beginTransaction();  
  13. //保存用户组
     
  14.                session.save(group);  
  15.               //将缓冲区中的sql送到数据库中  
  16. session.flush();  
  17.               //提交事务
     
  18. transaction.commit(); 

我们没有显示的插入user1和uesr2两条记录,但是由于我们设置了cascade=all,那么在group表进行任何操作时都会关联到user表,即在保存group时,也会把user1和user2保存,这就是级联为我们带来的好处。


但是,在这里有两点需要说明的是:


1、如果在Group.hbm.xml映射文件中设置了inverse=true,那么说明这个一对多的关联关系由多的一方来维护。而在单向的一对多关联中,“多”的一方完全不知情,所以在保存往user
表中插入的两条数据,其外键group_id这一字段都是为null值。如果user表中group_id是not null的话就会出现如下异常:


 


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这个字段没有设置一个默认值,其实就是我们往group_id这个非空的字段插入了一个null值。


2、如果再Group.hbm.xml映射文件中设置inverse=false,或者不设置该属性,即表示由自身来维护这个关联关系。但在保存group后,会先将user1和user2插入到数据库,并且group_id的值都为null。然后再接着两条update语句,将这两天记录的group_id字段值设置为前面插入的group的id。同样的如果user
表中group_id字段是非空的,仍然会出现上面的异常。


---------------------------------------------单向一对多的关联完毕----------------------------------------------------------


除了一对多双向关联关系的"many"方设为true、多对多双向关联关系的两方设为true之外,其余应均为false


posted on 2012-05-02 16:06 @赵 阅读(299) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航:
 
哥哥最近不是很忙