Hibernate Gossip: 多对一

转载 2006年06月07日 14:50:00
一個實體簡單的說就是在資料庫中擁有一個表格,並擁有自已的資料庫識別(Database identity)。

一個簡單的實體與實體間之關係為多對一的關係,例如在學校宿舍中,使用者與房間的關係就是多對一的關係,多個使用者可以居住於一個房間。


如上圖所示的,可以藉由room_id讓使用者與房間產生關聯,您可以如下建立userroom表格:
CREATE TABLE user (
    id INT(11) NOT NULL auto_increment PRIMARY KEY,
    name VARCHAR(100) NOT NULL default '',
    room_id INT(11)
);

CREATE TABLE room (
    id INT(11) NOT NULL auto_increment PRIMARY KEY,
    address VARCHAR(100) NOT NULL default ''
);


用程式來表示的話,首先看看User類別:
  • User.java
package onlyfun.caterpillar;

public class User {
    private Integer id;
    private String name;
    private Room room;

    public User() {
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Room getRoom() {
        return room;
    }

    public void setRoom(Room room) {
       this.room = room;
    }  
}

User
類別中有一room屬性,將參考至Room實例,多個User實例可共同參考一個Room實例,Room類別設計如下:
  • Room.java
package onlyfun.caterpillar;

public class Room {
    private Integer id;
    private String address;
   
    public Room() {
    }
   
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }   
   
    public String getAddress() {
        return address;
    }
   
    public void setAddress(String address) {
        this.address = address;
    }
}

在映射文件方面,先來看看Room.hbm.xml
  • Room.hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping
    PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

    <class name="onlyfun.caterpillar.Room" table="room">
        <id name="id" column="id">
            <generator class="native"/>
        </id>

        <property name="address"
                  column="address"
                  type="java.lang.String"/>
    </class>

</hibernate-mapping>

沒什麼,很簡單的一個映射文件,而在User.hbm.xml中,使用<many-to-one>標籤來映射多對一關係:
  • User.hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping
    PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

    <class name="onlyfun.caterpillar.User" table="user">
        <id name="id" column="id" type="java.lang.Integer">
            <generator class="native"/>
        </id>

        <property name="name" column="name" type="java.lang.String"/>
       
        <many-to-one name="room"
                     column="room_id"
                     class="onlyfun.caterpillar.Room"
                     cascade="all"
                     outer-join="true"/>     
   
    </class>

</hibernate-mapping>

<many-to-one>的設定中,cascade表示主控方(User)進行save-updatedelete等相關操作時,被控方(Room)是否也一併進行相關操作,簡單的說,也就是您儲存或更新User實例時,當中的Room實例是否一併對資料庫發生儲存或操作,設定為 all,表示主控方任何操作,被控方也進行對應操作。

一個儲存的例子如下:
Room room1 = new Room();
room1.setAddress("NTU-M8-419");
Room room2 = new Room();
room2.setAddress("NTU-G3-302");
       
User user1 = new User();
user1.setName("bush");
user1.setRoom(room1);
       
User user2 = new User();
user2.setName("caterpillar");
user2.setRoom(room1);
       
User user3 = new User();
user3.setName("momor");
user3.setRoom(room2);

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
       
session.save(user1); //
主控方操作,被控方也會對應操作
session.save(user2);
session.save(user3);
       
tx.commit();
session.close();

資料庫中將儲存以下的內容:
mysql> select * from user;
+----+-------------+-----------+
| id    | name        | room_id |
+----+-------------+-----------+
|  1    | bush         |  1 |
|  2    | caterpillar |  1 |
|  3    | momor      |  2 |
+----+-------------+-----------+
3 rows in set (0.00 sec)

mysql> select * from room;
+----+-------------------+
| id    | address     |
+----+-------------------+
|  1    | NTU-M8-419  |
|  2    | NTU-G3-302    |
+----+-------------------+
2 rows in set (0.00 sec)

在查詢時的例子如下:
Session session = sessionFactory.openSession();
User user = (User) session.load(User.class, new Integer(1));
System.out.println(user.getName());
System.out.println(user.getRoom().getAddress());
session.close();

在設定outer-jointrue的情況下,Hibernate將使用以下的SQL一次查詢所有的資料:
Hibernate: select user0_.id as id1_, user0_.name as name0_1_, user0_.room_id as room3_0_1_, room1_.id as id0_, room1_.address as address1_0_ from user user0_ left outer join room room1_ on user0_.room_id=room1_.id where user0_.id=?

在不設定outer-jointrue的情況下,Hibernate則使用以下的SQL分別查詢userroom表格:
Hibernate: select user0_.id as id0_, user0_.name as name0_0_, user0_.room_id as room3_0_0_ from user user0_ where user0_.id=?
Hibernate: select room0_.id as id0_, room0_.address as address1_0_ from room room0_ where room0_.id=?
 

hibernate——多对一和一对多映射浅析

首先应该清楚多对一和一对多只是站在不同的角度看待问题,其本质是一样的。在思考这个问题的时候,不要把这两个概念混在一起,这样不容易理解,而要分开,站在不同的角度去解决同一个问题。 就拿员工和部门的例子...
  • hackerain
  • hackerain
  • 2011年11月27日 18:56
  • 9251

hibernate多对一单向配置

下面对hibernate多对一单向配置做好笔记。 多对一就比较简单了,先建立 Group 类和 User 类,因为这次是 多对一,所以在 多的一方做设置即可,在 User 类中加个对 Group的引...
  • u010702229
  • u010702229
  • 2013年10月27日 15:51
  • 1535

hibernate中的一对多与多对一的详细配置解析

1.Employee package cn.itcast.b_one2Many; public class Employee { private int empId; private St...
  • miachen520
  • miachen520
  • 2016年08月10日 09:04
  • 4287

hibernate 一对多 多对一 关系的理解

1、单向多对一和双向多对一的区别? 只需要从一方获取另一方的数据时 就使用单向关联 双方都需要获取对方数据时 就使用双向关系 部门--人员 使用人员时 如果只需要获取对应部门信息(u...
  • l55iuming
  • l55iuming
  • 2015年10月20日 20:58
  • 2742

hibernate多对一关联和一对多关联

1. 多对一的单向关联 从订单(order)到客户(customer)的单向关联 (多个订单对应一个客户) JavaBean: Customer public class Customer{ pr...
  • zdp072
  • zdp072
  • 2016年04月13日 20:20
  • 1733

【hibernate】多对一,一对多关系

多对一映射:在说一对一外键单向映射中,在“主”端维护的时候用的是 标签,里面添加的unique=”true” 属性来约束的。这里不添加unique属性的时候就变成多对一的映射关系了。 “主”端...
  • sinat_36164818
  • sinat_36164818
  • 2017年04月23日 21:58
  • 2036

hibernate 多对一 存id就可以了

比如多个客户对应一个用户 public class Company{ private SysUser sysUser; } 在add.jsp页面   我当时想的是 save(){...
  • wyxz126
  • wyxz126
  • 2013年02月19日 20:38
  • 1041

Hibernate单向多对一级联删除引发的问题

Hibernate单向多对一在级联删除时,会出现一些问题。 下面模拟我遇到的问题: 这次模拟与之前的一次模拟方法一直,博客:http://blog.csdn.net/openjdk8/article/...
  • u012356022
  • u012356022
  • 2014年08月11日 21:41
  • 2601

Hibernate单向多对一映射下的增删改查

Hibernate单向多对一映射下的增删改查 注:作为初学者,本文仅为了巩固自己学习的知识亦或帮助初学者,如有缺漏,请见谅 在软件开发中,类与类之间最普遍的关系就是关联关系,而且关...
  • youyou_yo
  • youyou_yo
  • 2015年05月29日 15:56
  • 1157

【SSH进阶之路】Hibernate映射——多对一单向关联映射(四)

基本映射是对一个实体进行映射,关联映射就是处理多个实体之间的关系,将关联关系映射到数据库中,所谓的关联关系在对象模型中有一个或多个引用。...
  • jiuqiyuliang
  • jiuqiyuliang
  • 2014年10月22日 08:15
  • 31417
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Hibernate Gossip: 多对一
举报原因:
原因补充:

(最多只允许输入30个字)