文档章节

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

zimingforever
 zimingforever
发布于 2014/04/18 21:49
字数 1387
阅读 107
收藏 10

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及符合主键的映射。



© 著作权归作者所有

zimingforever
粉丝 142
博文 266
码字总数 315040
作品 0
杭州
程序员
私信 提问
Hibernate学习4--Hibernte的映射关系(二)

上一节我们主要研究下了Hibernate中的一一映射和多对一映射,这节我们看下Hibernate中的其他几种映射,包括一对多映射,多对多映射,复合主键映射及继承映射。 第一种是一对多映射,“一对多...

王小明123
2014/04/20
89
0
Hibernate学习1--SpringMVC+Hibernate集成环境搭建

除了刚毕业那会用了几个月的hibernate好像好久都没有碰过了,正好最近在整理以前的学习笔记就把这块知识系统的学习一下,特别是hibernate和ibatis的对比应该对我现在做的东西有很大的帮助。 ...

王小明123
2014/04/03
2.7K
0
Hibernate学习3--Hibernte的映射关系(基础概念篇)

前两节我们分别从Hibernate的demo和Hibernate的概念上熟悉了Hibernate的使用,这一节我们来了解Hibernate中的映射关系 首先我们了解下Hibernate映射文件中的各种标签的用法 1<hibernate-mapp...

王小明123
2014/04/14
368
0
iBatis和Hibernate浅析

iBatis和Hibernate浅析 Hibernate Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。Hiber...

JAVA__
2012/08/16
158
1
IBatis和Hibernate区别

原文出处:http://www.cnblogs.com/mingyongcheng/p/3588100.html IBatis和Hibernate区别 1. 简介 Hibernate是当前最流行的O/R mapping框架。它出身于sf.net,现在已经成为Jboss的一部分了。...

ponpon_
2014/06/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

如何在Linux中复制文档

在办公室里复印文档过去需要专门的员工与机器。如今,复制是电脑用户无需多加思考的任务。在电脑里复制数据是如此微不足道的事,以致于你还没有意识到复制就发生了,例如当拖动文档到外部硬盘...

老孟的Linux私房菜
54分钟前
23
0
SpringBoot 集成MongoDB

一、MongoDB 简介 MongoDB 如今是最流行的 NoSQL 数据库,被广泛应用于各行各业中,很多创业公司数据库选型就直接使用了 MongoDB,但对于大部分公司,使用 MongoDB 的场景是做大规模数据查询...

zw965
今天
32
0
使用 Envoy 和 AdGuard Home 阻挡烦人的广告

> 原文链接:使用 Envoy 和 AdGuard Home 阻挡烦人的广告 通常我们使用网络时,宽带运营商会为我们分配一个 DNS 服务器。这个 DNS 通常是最快的,距离最近的服务器,但会有很多问题,比如: ...

米开朗基杨
今天
35
0
springboot之全局处理异常封装

springboot之全局处理异常封装 简介 在项目中经常出现系统异常的情况,比如NullPointerException等等。如果默认未处理的情况下,springboot会响应默认的错误提示,这样对用户体验不是友好,系...

Purgeyao
今天
42
0
cookie

cookie: n. 饼干;小甜点 为什么会引入Cookie(在客户端保持http状态) 因为http协议是一种无状态协议,web服务器本身不能识别出哪些请求是同一个服务器发送的,浏览器的每一次请求都是独立...

五公里
今天
41
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部