程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> hibernate3學習筆記(十八)|關系映射:一對多

hibernate3學習筆記(十八)|關系映射:一對多

編輯:關於JAVA

接上例:http://blog.csdn.net/kunshan_shenbin/archive/2008/09/03/2873943.aspx

User對Room是多對一的關系,那麼反過來Room對User就是一對多的關系了。

User.java:

1.package com.hb3.pack_17.model;
2.
3.public class User {
4. 5. private Integer id;
6. private String name;
7.
8. public User() {
9. }
10. 11. public Integer getId() {
12. return id;
13. }
14. public void setId(Integer id) {
15. this.id = id;
16. }
17. public String getName() {
18. return name;
19. }
20. public void setName(String name) {
21. this.name = name;
22. }
23.}

Room.java:

1.package com.hb3.pack_17.model;
2.
3.import java.util.Set;
4. 5.public class Room {
6. 7. private Integer id;
8. private String address;
9. private Set<User> users;
10.
11. public Room() {
12. }
13.
14. public Integer getId() {
15. return id;
16. }
17. public void setId(Integer id) {
18. this.id = id;
19. }
20. public String getAddress() {
21. return address;
22. }
23. public void setAddress(String address) {
24. this.address = address;
25. }
26. public Set<User> getUsers() {
27. return users;
28. }
29. public void setUsers(Set<User> users) {
30. this.users = users;
31. }
32. public void addUser(User user) {
33. users.add(user);
34. }
35. public void removeUser(User user) {
36. users.remove(user);
37. }
38.}

Room.hbm.xml:

1.<?xml version="1.0" encoding="utf-8"?>
2.<!DOCTYPE hibernate-mapping
3. PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
4. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 5. 6.<hibernate-mapping> 7. 8. <class name="com.hb3.pack_17.model.Room" table="room">
9.
10. <id name="id" column="id">
11. <generator class="native"/>
12. </id>
13.
14. <property name="address"
15. column="address"
16. type="java.lang.String"/>
17.
18. <set name="users" table="user" cascade="all"> 19. <key column="room_id"/> 20. <one-to-many class="com.hb3.pack_17.model.User"/> 21. </set> 22.
23. </class>
24.</hibernate-mapping>

User.hbm.xml:

1.<?xml version="1.0" encoding="utf-8"?>
2.<!DOCTYPE hibernate-mapping
3. PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
4. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 5. 6.<hibernate-mapping>
7. 8. <class name="com.hb3.pack_17.model.User" table="user"> 9.
10. <id name="id" column="id" type="java.lang.Integer">
11. <generator class="native"/>
12. </id>
13. 14. <property name="name" column="name" type="java.lang.String"/>
15.
16. </class>
17. 18.</hibernate-mapping>

測試代碼:

1.package com.hb3.pack_17;
2.
3.import java.io.IOException;
4.import java.sql.SQLException;
5.import java.util.HashSet;
6. 7.import org.hibernate.Session;
8.import org.hibernate.SessionFactory;
9.import org.hibernate.Transaction;
10.import org.hibernate.cfg.Configuration;
11. 12.import com.hb3.pack_17.model.Room;
13.import com.hb3.pack_17.model.User;
14. 15. 16.public class BusinessService {
17. 18. public static void main(String[] args) throws IOException, SQLException {
19.
20. Configuration config = new Configuration().configure();
21. SessionFactory sessionFactory = config.buildSessionFactory();
22. Session session = sessionFactory.openSession();
23. 24.
25. User user1 = new User();
26. user1.setName("yangye");
27. User user2 = new User();
28. user2.setName("shenbin");
29. User user3 = new User();
30. user3.setName("chenyan");
31. 32. Room room1 = new Room();
33. room1.setUsers(new HashSet<User>());
34. room1.setAddress("NTU-M8-419");
35. room1.addUser(user1);
36. room1.addUser(user2);
37. Room room2 = new Room();
38. room2.setUsers(new HashSet<User>());
39. room2.setAddress("NTU-G3-302");
40. room2.addUser(user3);
41.
42. Transaction tx = session.beginTransaction();
43. session.save(room1);
44. session.save(room2);
45. tx.commit();
46. 47.
48. session.close();
49. sessionFactory.close();
50. }
51.}

雙向關聯:

以上多對一,一對多的關系都是單向關聯,也就是一方聯系到另一方,而另一方不知道自己被關聯。

如果上方都意識到另一方的存在,則形成雙向關聯。現將上面的代碼改寫如下:

在User類中追加Room類型的字段:

1.package com.hb3.pack_20.model;
2.
3.public class User {
4. 5. private Integer id;
6. private String name;
7. private Room room;
8.
9. public Room getRoom() {
10. return room;
11. }
12. 13. public void setRoom(Room room) {
14. this.room = room;
15. }
16. 17. public User() {
18. }
19. 20. public Integer getId() {
21. return id;
22. }
23. public void setId(Integer id) {
24. this.id = id;
25. }
26. public String getName() {
27. return name;
28. }
29. public void setName(String name) {
30. this.name = name;
31. }
32.}

User.hbm.xml中也同樣追加關於Room的信息:

1.<?xml version="1.0" encoding="utf-8"?>
2.<!DOCTYPE hibernate-mapping
3. PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
4. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 5. 6.<hibernate-mapping>
7. 8. <class name="com.hb3.pack_20.model.User" table="user"> 9.
10. <id name="id" column="id" type="java.lang.Integer">
11. <generator class="native"/>
12. </id>
13. 14. <property name="name" column="name" type="java.lang.String"/>
15.
16. <many-to-one name="room"
17. column="room_id"
18. class="com.hb3.pack_20.model.Room" 19. cascade="save-update" 20. outer-join="true"/>
21.
22. </class>
23.
24.</hibernate-mapping>

這裡我們將Room.hbm.xml文件裡set的cascade屬性也設為save-update:

1.<?xml version="1.0" encoding="utf-8"?>
2.<!DOCTYPE hibernate-mapping
3. PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
4. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 5. 6.<hibernate-mapping> 7. 8. <class name="com.hb3.pack_20.model.Room" table="room">
9.
10. <id name="id" column="id">
11. <generator class="native"/>
12. </id>
13.
14. <property name="address"
15. column="address"
16. type="java.lang.String"/>
17.
18. <set name="users" table="user" cascade="save-update"> 19. <key column="room_id"/> 20. <one-to-many class="com.hb3.pack_20.model.User"/> 21. </set> 22.
23. </class>
24.</hibernate-mapping>

這樣我們可以用多對一的方式來維持管理:

1.package com.hb3.pack_20;
2.
3.import org.hibernate.Session;
4.import org.hibernate.SessionFactory;
5.import org.hibernate.Transaction;
6.import org.hibernate.cfg.Configuration;
7. 8.import com.hb3.pack_20.model.Room;
9.import com.hb3.pack_20.model.User;
10. 11.public class BusinessService {
12. 13. public static void main(String[] args) {
14.
15. Configuration config = new Configuration().configure();
16. SessionFactory sessionFactory = config.buildSessionFactory();
17. Session session = sessionFactory.openSession();
18. 19.
20. User user1 = new User();
21. user1.setName("chenyan");
22.
23. User user2 = new User();
24. user2.setName("shenbin");
25. 26. Room room1 = new Room();
27. room1.setAddress("NTU-M8-419");
28. 29. user1.setRoom(room1);
30. user2.setRoom(room1);
31.
32. Transaction tx = session.beginTransaction();
33. session.save(user1);
34. session.save(user2);
35. tx.commit();
36. 37. 38. session.close();
39. sessionFactory.close();
40. }
41.}

或者反過來由一對多的方式來維持關系:

1.package com.hb3.pack_20;
2.
3.import java.util.HashSet;
4. 5.import org.hibernate.Session;
6.import org.hibernate.SessionFactory;
7.import org.hibernate.Transaction;
8.import org.hibernate.cfg.Configuration;
9. 10.import com.hb3.pack_20.model.Room;
11.import com.hb3.pack_20.model.User;
12. 13.public class BusinessService {
14. 15. public static void main(String[] args) {
16.
17. Configuration config = new Configuration().configure();
18. SessionFactory sessionFactory = config.buildSessionFactory();
19. Session session = sessionFactory.openSession();
20. 21.
22. User user1 = new User();
23. user1.setName("chenyan");
24.
25. User user2 = new User();
26. user2.setName("shenbin");
27. 28. Room room1 = new Room();
29. room1.setUsers(new HashSet<User>());
30. room1.setAddress("NTU-M8-419");
31. room1.addUser(user1);
32. room1.addUser(user2);
33.
34. Transaction tx = session.beginTransaction();
35. session.save(room1);
36. tx.commit();
37. 38.
39. session.close();
40. sessionFactory.close();
41. }
42.}

但是一對多的方式來維持的話,先看一下生成的SQL文:

Hibernate: insert into room (address) values (?)
Hibernate: insert into user (name, room_id) values (?, ?)
Hibernate: insert into user (name, room_id) values (?, ?)
Hibernate: update user set room_id=? where id=?
Hibernate: update user set room_id=? where id=?

可見,如果把一的一方Room作為主控方,多的一方User因為不知道Room的room_id是多少,所以必須等Room和User存儲之後再更新room_id。所以在多對一,一對多形成雙向關聯的時候,應該把控制權交給多的一方,這樣比較有效率。理由很簡單,就像在公司裡一樣,老板記住所有員工的名字來得快,還是每個員工記住老板的名字來得快。

基於這個理由,我們對Room.hbm.xml再稍作修改:

1.<?xml version="1.0" encoding="utf-8"?>
2.<!DOCTYPE hibernate-mapping
3. PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
4. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 5. 6.<hibernate-mapping> 7. 8. <class name="com.hb3.pack_20.model.Room" table="room">
9.
10. <id name="id" column="id">
11. <generator class="native"/>
12. </id>
13.
14. <property name="address"
15. column="address"
16. type="java.lang.String"/>
17.
18. <set name="users" table="user" cascade="save-update" inverse="true"> 19. <key column="room_id"/> 20. <one-to-many class="com.hb3.pack_20.model.User"/> 21. </set> 22.
23. </class>
24.</hibernate-mapping>

如此控制權就交給了多的一方。當直接存儲一的一方前,必須讓多的一方意識的一的一方的存在。

1.package com.hb3.pack_20;
2.
3.import java.io.IOException;
4.import java.sql.SQLException;
5.import java.util.HashSet;
6. 7.import org.hibernate.Session;
8.import org.hibernate.SessionFactory;
9.import org.hibernate.Transaction;
10.import org.hibernate.cfg.Configuration;
11. 12.import com.hb3.pack_20.model.Room;
13.import com.hb3.pack_20.model.User;
14. 15.public class BusinessService {
16. 17. public static void main(String[] args) throws IOException, SQLException {
18.
19. Configuration config = new Configuration().configure();
20. SessionFactory sessionFactory = config.buildSessionFactory();
21. Session session = sessionFactory.openSession();
22. 23.
24. User user1 = new User();
25. user1.setName("bush");
26.
27. User user2 = new User();
28. user2.setName("caterpillar");
29. 30. Room room1 = new Room();
31. room1.setUsers(new HashSet<User>());
32. room1.setAddress("NTU-M8-419");
33. room1.addUser(user1);
34. room1.addUser(user2);
35. 36. //多方必須認識到單方的存在 37. user1.setRoom(room1);
38. user2.setRoom(room1);
39.
40. Transaction tx = session.beginTransaction();
41. session.save(room1);
42. tx.commit();
43. 44. 45. session.close();
46. sessionFactory.close();
47. }
48.}

此時生成的SQL文為:

Hibernate: insert into room (address) values (?)
Hibernate: insert into user (name, room_id) values (?, ?)
Hibernate: insert into user (name, room_id) values (?, ?)

從而提高了效率。

如果把代碼中user1.setRoom(room1);和user2.setRoom(room1);這2行移去,你會發現數據庫中room_id的值為null。這個結果就好比在多對一的關系中沒有分配給User一個Room,那麼理所當然room_id的值為null了。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved