Hibernate学习4--Hibernte的映射关系(一)

Hibernate中最绕的部分莫过于各种映射了,其实大致上就3种,一对一映射onetoone,一对多映射onetomany,多对一映射manytoone,多对多映射manytomany。一对一映射又有一对一主键映射和唯一外键映射。

第一种,一对一主键映射,我们这里用Person和IdCard举例,人和身份证是一对一的关系

其中Idcard的配置如下:

    <class name="com.xiaoming.test.hibernate.personTest.IdCard" table="idcard">
        <id name="id" length="4">
            <generator class="native"></generator>
        </id>
        <property name="cardNo" length="10"></property>
        <one-to-one name="person" ></one-to-one>
    </class>

person的配置如下:

<class name="com.xiaoming.test.hibernate.personTest.Person" table="person">
        <id name="id" length="4">
            <generator class="foreign">
                <param name="property">idCard</param>
            </generator>
        </id>
        <property name="name" length="10"></property>
        <one-to-one name="idCard" constrained="true"></one-to-one>
    </class>

其中person的主键来自idcard,也就是共享idcard的主键。constrained="true"的含义,表明当前主键上存在一个约束,person的主键作为外键参照了idCard,  这里在进行person对象操作时,要求idCard不 能为null 

  IdCard idCard = new IdCard(); 
      idCard.setCardNo("1234567890"); 

      Person person = new Person(); 
      person.setName("张三"); 
      idCard.setPerson(person); 
      session.save(idCard);

这种情况,person是依赖idcard。但是idcard并没有cascade到person,所以这个操作只会保存idcard对象

 IdCard idCard = new IdCard(); 
      idCard.setCardNo("1234567890"); 
      Person person = new Person(); 
      person.setName("张三"); 
      idCard.setPerson(person); 
      session.save(person);

这种情况在保存person的时候,person并没有绑定idcard,而其id又是依赖idcard的id的,所以这样执行会报错。

 IdCard idCard = new IdCard(); 
      idCard.setCardNo("1234567890"); 
      Person person = new Person(); 
      person.setName("张三"); 
      person.setIdCard(idCard); 
      session.save(person);

这种情况是可以正常保存idcard和person的

读取的代码如下:

Person p=(Person)session.load(Person.class, 1); 
      System.out.println(p); 
      System.out.println(p.getIdCard());
        
      IdCard idCard=(IdCard)session.get(IdCard.class, 1); 
      System.out.println(idCard); 
      System.out.println(idCard.getPerson());


第二种映射情况是一对一唯一外键映射, 一对唯一外键关联映射是采用多对一关联映射方法来解决一对一的问题,它就是多对一的一个特例。它是基于这样一种思想:在映射多的一端时采用<many-to-one>标签,并且用属性unique=true来限定它是唯一的,这样就实现了多的一端的多重性为一。但是,它仍保留多対一的痕迹(比如关系模型中增加一个外键字段)。

其中idcard的配置如下:

    <class name="com.xiaoming.test.hibernate.personTest2.IdCard" table="idcard">
        <id name="id" length="4">
            <generator class="native"></generator>
        </id>
        <property name="cardNo" length="10"></property>
        <one-to-one name="person" class="com.xiaoming.test.hibernate.personTest2.Person" property-ref="idCard" cascade="save-update" ></one-to-one>
    </class>

property-ref="idCard"含义,指示加载关联对象时根据关联对象对本对象的引用(即根据person的idCard属性) 测试代码如下:

person的配置如下:

 <class name="com.xiaoming.test.hibernate.personTest2.Person" table="person">
        <id name="id" length="4">
            <generator class="native"></generator>
        </id>
        <property name="name" length="10"></property>
        <!--many-to-one标签的含义,是在本表中增加外键指向另一端。
         unique="true"含义,是本表的本字段加上唯一性约束.
        -->
        <many-to-one name="idCard" class="com.xiaoming.test.hibernate.personTest2.IdCard" unique="true" column="card_id" cascade="save-update"></many-to-one>
    </class>

many-to-one是在本表中增加外键指向另一端,unique=true的含义表示在本表的本字段加上唯一性约束。


 IdCard idCard=new IdCard(); 
      idCard.setCardNo("1234567890"); 
        
      Person person=new Person(); 
      person.setIdCard(idCard); 
      session.save(person);

这种情况是ok的,会同事插入person和idcard两个对象,因为idcard中的onetoone标签有cacade=save-updatre属性

IdCard idCard=new IdCard(); 
      idCard.setCardNo("1234567890"); 
      session.save(idCard); 
        
      Person person=new Person(); 
      person.setName("张三"); 
      person.setIdCard(idCard); 

      session.save(person);

 这种写法也是对的。会同时插入idcard及person属性

 Person person=new Person(); 
      person.setName("奇隆"); 
        
      IdCard idCard=new IdCard(); 
      idCard.setCardNo("1234567890"); 
      idCard.setPerson(person);

如果在IdCard一端没有cascade="save-update",显然这里会只插入idCard,而不会级联插入它的person属性 。如果在IdCard一端有cascade="save-update",则在插入idCard后,会再插入person,但是idCard_id字段会是null,而不会把person的idCard_id更新. 所以像这种情况,应该在"多"的一端插入并级联"一"的一端.

读取操作如下:

  Person p=(Person)session.load(Person.class, 2); 
      System.out.println(p); 
      System.out.println(p.getIdCard()); 
      
      IdCard idCard=(IdCard)session.get(IdCard.class, 5); 
      System.out.println(idCard); 
      System.out.println(idCard.getPerson());

第3中是多对一的映射,我们这里用group和user来举例

Group配置对下:

    <class name="com.xiaoming.test.hibernate.userTest.Group" table="group1">
        <id name="id" length="4">
            <generator class="native"></generator>
        </id>
        <property name="name" length="10"></property>
    </class>

User的配置如下:

 <class name="com.xiaoming.test.hibernate.userTest.User" table="user1">
        <id name="id" length="4">
            <generator class="native"></generator>
        </id>
        <property name="name" length="10"></property>
        <many-to-one name="group" column="group_id" cascade="save-update"></many-to-one>
    </class>

many-to-one含义,会在多的一端加入一个外键指向一的一端,以供加载时使用.外键由column属性指定,默认和实体属性名相同. cascade操作本对象时级联操作它的关联对象

测试方法如下:

 Group group = new Group();
        group.setName("研发组"); 
        User user=new User(); 
        user.setName("奇隆"); 
        user.setGroup(group); 
        session.save(user);

这种操作是ok的,因为user加了casecade属性,所以在插入user之前会插入group

Group group=(Group)session.get(Group.class, 2); 
        User user=new User();     
        user.setName("谢霆锋"); 
        user.setGroup(group); 
        session.save(user);*/

这种情况group是已经在数据库中并加载出来的,所以也能保存成功。

  User user = (User) session.get(User.class, 3);// 只是加载了user对象和它所在组的对象group的id属性,并没有加载group对象 
      System.out.println(user); 
      System.out.println(user.getGroup()); 
      session.save(user); 
      user.setName("郑伊健"); 
      session.save(user);

第一次save的时候由于user没有做update操作,所以不会触发update操作,第二个save操作由于user有变动,所以可以触发update操作

其实每种案例都差不多,无非就是one和many标签及其中属性的配合,另外java代码中注意调用的顺序,就可以正常操作对应的对象属性,这一次这几种映射关系没有介绍完,下一次再学习manytoone,manytomany及符合主键的映射。



你可能感兴趣的:(Hibernate学习4--Hibernte的映射关系(一))