Hibernate 多對一關聯查詢


 版權聲明:本文為博主原創文章,如需轉載請標注轉載地址

 博客地址:http://www.cnblogs.com/caoyc/p/5598269.html 

一、單向多對一和雙向多對一的區別

  如果只需要從一方獲取另一方數據,就用單向多對一;如果需要從雙方都獲取對方數據,就用雙向多對一。

  如果有兩個對象,一個為User對象,一個為Department對象,一個用戶只能屬於一個部門,而一個部門可以包含多個用戶。這樣就是多對一關系。如下圖

  

    假設:我們需要通過用戶找到所對應的部門,不需要通過部門查詢該部門有哪些用戶,就采用單向多對一關系

    如果:我們不僅需要通過用戶獲取所對應的部門,還需要通過部門對象獲取該部門下的用戶,那么就采用雙向多對一

 

二、單向多對一關系

  Department.java

 1 package com.proc.pojo;
 2 
 3 import java.io.Serializable;
 4 
 5 public class Department implements Serializable {
 6 
 7     private Integer id;
 8     private String deptname;
 9     
10     //提供構造方法
11     public Department() {
12     }
13     
14     public Department(String deptname) {
15         this.deptname = deptname;
16     }
17 
18     //getter和setter實現
19     public Integer getId() {
20         return id;
21     }
22     public void setId(Integer id) {
23         this.id = id;
24     }
25     public String getDeptname() {
26         return deptname;
27     }
28     public void setDeptname(String deptname) {
29         this.deptname = deptname;
30     }
31 }

  User.java

 1 package com.proc.pojo;
 2 
 3 import java.io.Serializable;
 4 
 5 public class User implements Serializable {
 6 
 7     private Integer id;
 8     private String name;
 9     private Department dept;
10     
11     //提供構造方法
12     public User() {
13     }
14     public User(String name) {
15         this.name = name;
16     }
17     //getter和setter實現
18     public Integer getId() {
19         return id;
20     }
21     
22     public void setId(Integer id) {
23         this.id = id;
24     }
25     public String getName() {
26         return name;
27     }
28     public void setName(String name) {
29         this.name = name;
30     }
31     public Department getDept() {
32         return dept;
33     }
34     public void setDept(Department dept) {
35         this.dept = dept;
36     }
37 }

  Department.hbm.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.proc.pojo">
    <class name="Department" table="department">
        <id name="id" type="int">
            <generator class="native"></generator>
        </id>
        <property name="deptname" length="20" not-null="true"></property>
    </class>
</hibernate-mapping>

  User.hbm.xml

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE hibernate-mapping PUBLIC 
 3     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4     "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 5 <hibernate-mapping package="com.proc.pojo">
 6     <class name="User">
 7         <id name="id" type="int">
 8             <generator class="native"></generator>
 9         </id>
10         <property name="name" length="20" not-null="true"></property>
11         <many-to-one name="dept" column="deptid" class="Department" ></many-to-one>
12     </class>
13 </hibernate-mapping>

    代碼講解:在配置User(多)->Department(一)時,采用外鍵映射,其中

  name="dept":User對象dept屬性

  class="Department":表示該dept屬性的類型是Department類型,因為User和Department在同一個包中,所以直接使用了類名稱

  column="deptid":指定在用user表中,對應department表的中主鍵的列為deptid

  這里並沒有指出user表中deptid對應的值department表中哪一列,默認為主鍵,這里也會自動給deptid列添加一個外鍵約束

  foreign-key="none":不創建外鍵約束,如果將none改成其他的,即為指定外鍵名稱

  測試代碼:

 1 package com.proc.test;
 2 
 3 import org.hibernate.Session;
 4 import org.hibernate.SessionFactory;
 5 import org.hibernate.Transaction;
 6 import org.hibernate.cfg.Configuration;
 7 import org.junit.Test;
 8 
 9 import com.proc.pojo.Department;
10 import com.proc.pojo.User;
11 
12 public class TestOneToMany {
13 
14     private static SessionFactory factory=new Configuration()
15                                 .configure()
16                                 .addClass(User.class)
17                                 .addClass(Department.class)
18                                 .buildSessionFactory();
19     @Test
20     public void set(){
21         
22         Session session=factory.openSession();
23         Transaction tran=session.beginTransaction();
24         Department dept1=new Department("IT部");
25         
26         User user1=new User("caoyc");
27         User user2=new User("zhh");
28         
29         user1.setDept(dept1);
30         user2.setDept(dept1);
31         
32         session.save(dept1);
33         session.save(user1);
34         session.save(user2);
35         
36         tran.commit();
37         session.close();
38     }
39 }

   在控制台輸出SQL語句:

Hibernate: create table department (id integer not null auto_increment, deptname varchar(20) not null, primary key (id))
Hibernate: create table User (id integer not null auto_increment, name varchar(20) not null, deptid integer, primary key (id))
Hibernate: alter table User add constraint FK66lqw6kl2gcxhs44gamc91fbd foreign key (deptid) references department (id)

Hibernate: insert into department (deptname) values (?)
Hibernate: insert into User (name, deptid) values (?, ?)
Hibernate: insert into User (name, deptid) values (?, ?)

 

測試:如果將測試代碼中32-34行代碼改成

session.save(user1);
session.save(user2);
session.save(dept1);

   在控制台輸出SQL語句:

Hibernate: create table department (id integer not null auto_increment, deptname varchar(20) not null, primary key (id))
Hibernate: create table User (id integer not null auto_increment, name varchar(20) not null, deptid integer, primary key (id))
Hibernate: alter table User add constraint FK66lqw6kl2gcxhs44gamc91fbd foreign key (deptid) references department (id)

Hibernate: insert into User (name, deptid) values (?, ?)
Hibernate: insert into User (name, deptid) values (?, ?)
Hibernate: insert into department (deptname) values (?)
Hibernate: update User set name=?, deptid=? where id=?
Hibernate: update User set name=?, deptid=? where id=?

  這里多出了兩行update User代碼,也就是在我們先添加向user表中插入數據時,而還在department總還沒有數據,當插入department數據后,在通過update的方式來修改user表

  總結:在我們插入多對一關系時,需要先保存(一)的一方,然后在保存(多)的一方,這樣可以減少SQL執行語句,如果是單向多對一關系,在添加多對一關系,只需要在(多)的一方的映射文件(.hbm.xml)中添加many-to-one就可以了

 

單向多對一刪除操作:

  a、刪除(多)的一方(User),刪除成功

  b、刪除(一)的一方(Department),如果user表中沒有該部門的用戶,則刪除成功

  c、刪除(一)的一方(Department),如果user表中還有改部門的用戶,則刪除失敗,因為有外鍵約束

 

三、雙向多對一操作

  第一步:在Department.java中添加一個users屬性,並提供get和set方法

1 private Set<User> users;
2 public Set<User> getUsers() {
3     return users;
4 }
5 public void setUsers(Set<User> users) {
6     this.users = users;
7 }

  第二步:在Department.hbm.xml中添加關聯映射

 

既可以通過User的到Department,也可以通過Department得到Set<User>

 

雙向多對一刪除:

  a、刪除(多)的一方,總是成功

  b、刪除(少)的一方,如果inverse=“false”,成功

  c、刪除(少)的一方,如果inverse=“true”,失敗


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM