1.Set映射
DDL:
1.CREATE TABLE user (
2. id INT(11) NOT NULL auto_increment PRIMARY KEY,
3. name VARCHAR(100) NOT NULL default ''
4. );
5.
6.CREATE TABLE email (
7. id INT(11) NOT NULL,
8. address VARCHAR(100) NOT NULL
9.);
User.java
1.package com.hb3.pack_11.model;
2.
3.import java.util.Set;
4. 5.public class User {
6. 7. private Integer id;
8. private String name;
9. private Set<String> emails;
10. 11. public User() {
12. }
13. 14. public Integer getId() {
15. return id;
16. }
17. public void setId(Integer id) {
18. this.id = id;
19. }
20. public String getName() {
21. return name;
22. }
23. public void setName(String name) {
24. this.name = name;
25. }
26. public Set<String> getEmails() {
27. return emails;
28. }
29. public void setEmails(Set<String> emails) {
30. this.emails = emails;
31. }
32. public void addEmail(String email) {
33. this.emails.add(email);
34. }
35. public void removeEmail(String email) {
36. this.emails.remove(email);
37. }
38.}
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_11.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. <set name="emails" table="email"> 17. <key column="id" /> 18. <element type="java.lang.String" column="address" /> 19. </set> 20. </class> 21.</hibernate-mapping>
測試代碼:
1.package com.hb3.pack_11;
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_11.model.User;
13. 14.public class BusinessService {
15. 16. public static void main(String[] args) throws IOException, SQLException {
17.
18. Configuration config = new Configuration().configure();
19. SessionFactory sessionFactory = config.buildSessionFactory();
20. Session session = sessionFactory.openSession();
21. 22.
23. User user1 = new User();
24. user1.setEmails(new HashSet<String>());
25. user1.setName("shenbin");
26. user1.addEmail("[email protected]");
27. user1.addEmail("[email protected]");
28.
29. User user2 = new User();
30. user2.setEmails(new HashSet<String>());
31. user2.setName("chenyan");
32. user2.addEmail("[email protected]");
33. 34. Transaction tx = session.beginTransaction();
35. session.save(user1);
36. session.save(user2);
37. tx.commit();
38.
39.
40. session.close();
41. sessionFactory.close();
42. }
43.}
Set的特點就是不能放置相同的物件在Set中。
也就是說,上述例子中,同一個User雖然可以對應多個emails,但是emails卻不能有相同的(對同一個人而言)。
2.List映射
DDL:
1.CREATE TABLE user (
2. id INT(11) NOT NULL auto_increment PRIMARY KEY,
3. name VARCHAR(100) NOT NULL default ''
4.);
5.
6.CREATE TABLE item (
7. id INT(11) NOT NULL,
8. position INT(11) NOT NULL,
9. name VARCHAR(100) NOT NULL default ''
10.);
User.java
1.package com.hb3.pack_12.model;
2.
3.import java.util.List;
4.
5.public class User {
6. 7. private Integer id;
8. private String name;
9. private List<String> items;
10. 11. public User() {
12. }
13. 14. public Integer getId() {
15. return id;
16. }
17. public void setId(Integer id) {
18. this.id = id;
19. }
20. public String getName() {
21. return name;
22. }
23. public void setName(String name) {
24. this.name = name;
25. }
26. public List<String> getItems() {
27. return items;
28. }
29. public void setItems(List<String> items) {
30. this.items = items;
31. }
32. public void addItem(String item) {
33. items.add(item);
34. }
35. public void removeItem(String item) {
36. items.remove(item);
37. }
38.}
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_12.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. <list name="items" table="item">
17. <key column="id"/>
18. <index column="position"/>
19. <element type="java.lang.String" column="name"/>
20. </list>
21.
22. </class>
23.</hibernate-mapping>
測試代碼:
1.package com.hb3.pack_12;
2.
3.import java.io.IOException;
4.import java.sql.SQLException;
5.import java.util.ArrayList;
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_12.model.User;
13. 14.public class BusinessService {
15. 16. public static void main(String[] args) throws IOException, SQLException {
17.
18. Configuration config = new Configuration().configure();
19. SessionFactory sessionFactory = config.buildSessionFactory();
20. Session session = sessionFactory.openSession();
21. 22.
23. User user1 = new User();
24. user1.setItems(new ArrayList<String>());
25. user1.setName("shenbin");
26. user1.addItem("DC");
27. user1.addItem("CF Card");
28.
29. User user2 = new User();
30. user2.setItems(new ArrayList<String>());
31. user2.setName("chenyan");
32. user2.addItem("CD");
33. 34. Transaction tx = session.beginTransaction();
35. session.save(user1);
36. session.save(user2);
37. tx.commit();
38. 39.
40. session.close();
41. sessionFactory.close();
42. }
43.}
List是有序的結構。他在存儲物品的時候還對物品所處的位置進行了記錄。
3.Bag映射
DDL:
1.CREATE TABLE user (
2. id INT(11) NOT NULL auto_increment PRIMARY KEY,
3. name VARCHAR(100) NOT NULL default ''
4.);
5.
6.CREATE TABLE item (
7. id INT(11) NOT NULL,
8. name VARCHAR(100) NOT NULL
9.);
User.java
1.package com.hb3.pack_13.model;
2.
3.import java.util.List;
4. 5.public class User {
6. 7. private Integer id;
8. private String name;
9. private List<String> items;
10. 11. public User() {
12. }
13. 14. public Integer getId() {
15. return id;
16. }
17. public void setId(Integer id) {
18. this.id = id;
19. }
20. public String getName() {
21. return name;
22. }
23. public void setName(String name) {
24. this.name = name;
25. }
26. public List<String> getItems() {
27. return items;
28. }
29. public void setItems(List<String> items) {
30. this.items = items;
31. }
32. public void addItem(String item) {
33. items.add(item);
34. }
35. public void removeItem(String item) {
36. items.remove(item);
37. }
38.}
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_12.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. <bag name="items" table="item">
17. <key column="id"/>
18. <element column="name" type="java.lang.String"/>
19. </bag>
20.
21. </class>
22.</hibernate-mapping>
測試代碼:
1.package com.hb3.pack_13;
2.
3.import java.io.IOException;
4.import java.sql.SQLException;
5.import java.util.ArrayList;
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_12.model.User;
13. 14.public class BusinessService {
15. 16. public static void main(String[] args) throws IOException, SQLException {
17.
18. Configuration config = new Configuration().configure();
19. SessionFactory sessionFactory = config.buildSessionFactory();
20. Session session = sessionFactory.openSession();
21. 22.
23. User user1 = new User();
24. user1.setItems(new ArrayList<String>());
25. user1.setName("shenbin");
26. user1.addItem("Java Gossip");
27. user1.addItem("Java Gossip");
28. user1.addItem("Caxxx A80");
29.
30. User user2 = new User();
31. user2.setItems(new ArrayList<String>());
32. user2.setName("chenyan");
33. user2.addItem("Snoppy world");
34.
35. Transaction tx = session.beginTransaction();
36. session.save(user1);
37. session.save(user2);
38. tx.commit();
39. 40.
41. session.close();
42. sessionFactory.close();
43. }
44.}
Bag是Hibernate自己提供的集合,他和Set的區別是它允許重復,他和List的區別是他不去管List容器中的順序。
然而,倘若要做下面的更新處理:
1.Session session = sessionFactory.openSession();
2.Transaction tx = session.beginTransaction();
3.User user = (User) session.load(User.class, new Integer(1));
4.user.removeItem("Java Gossip");
5.tx.commit();
6.session.close();
運行的SQL文為:
Hibernate: delete from item where id=?
Hibernate: insert into item (id, name) values (?, ?)
Hibernate: insert into item (id, name) values (?, ?)
由於Bag集合允許重復,當更新數據時,他無法知道需要更改的是重復數據中的哪比數據,所以采取全部刪除後重新寫入的方式。
然後,這顯然是種沒有效率的做法。
幸運的是,Hibernate提供idbag。借由在定義Bag映射時加上"collection-id",讓Hibernate能確定需要更改的那條記錄從而提高效率。
新建表格:
1.CREATE TABLE user (
2. id INT(11) NOT NULL auto_increment PRIMARY KEY,
3. name VARCHAR(100) NOT NULL default ''
4.);
5.
6.CREATE TABLE item (
7. cid CHAR(32) NOT NULL,
8. id INT(11) NOT NULL,
9. name VARCHAR(100) NOT NULL
10.);
改寫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_12.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. <idbag name="items" table="item">
17. <collection-id column="cid" type="java.lang.String"> 18. <generator class="uuid.hex"/> 19. </collection-id> 20. <key column="id"/>
21. <element column="name" type="java.lang.String"/>
22. </idbag> 23.
24. </class> 25.
26.</hibernate-mapping>
測試代碼:
1.package com.hb3.pack_13;
2.
3.import java.io.IOException;
4.import java.sql.SQLException;
5.import java.util.ArrayList;
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_12.model.User;
13. 14.public class BusinessService {
15. 16. public static void main(String[] args) throws IOException, SQLException {
17.
18. Configuration config = new Configuration().configure();
19. SessionFactory sessionFactory = config.buildSessionFactory();
20. Session session = sessionFactory.openSession();
21.
22.
23. User user1 = new User();
24. user1.setItems(new ArrayList<String>());
25. user1.setName("shenbin");
26. user1.addItem("Java Gossip");
27. user1.addItem("Java Gossip");
28. user1.addItem("Caxxx A80");
29.
30. User user2 = new User();
31. user2.setItems(new ArrayList<String>());
32. user2.setName("chenyan");
33. user2.addItem("Snoppy world");
34.
35. Transaction tx = session.beginTransaction();
36. session.save(user1);
37. session.save(user2);
38. tx.commit();
39. 40.
41. session.close();
42. session = sessionFactory.openSession();
43.
44.
45. tx = session.beginTransaction();
46. User user = (User) session.load(User.class, new Integer(1));
47. user.removeItem("Java Gossip");
48. tx.commit();
49.
50.
51.
52. session.close();
53. sessionFactory.close();
54. }
55.}
SQL文的Log:
13:32:16,187 WARN ConfigurationFactory:127 - No configuration found. Configuring ehcache from ehcache-failsafe.xml found in the classpath: jar:file:/D:/Java/MyEclipse%206.0/workspace/hb3demo/ehcache-1.2.3.jar!/ehcache-failsafe.xml
13:32:16,609 WARN EhCacheProvider:93 - Could not find configuration [org.hibernate.cache.UpdateTimestampsCache]; using defaults.
13:32:16,640 WARN EhCacheProvider:93 - Could not find configuration [org.hibernate.cache.StandardQueryCache]; using defaults.
Hibernate: insert into user (name) values (?)
Hibernate: insert into user (name) values (?)
Hibernate: insert into item (id, cid, name) values (?, ?, ?)
Hibernate: insert into item (id, cid, name) values (?, ?, ?)
Hibernate: insert into item (id, cid, name) values (?, ?, ?)
Hibernate: insert into item (id, cid, name) values (?, ?, ?)
Hibernate: select user0_.id as id0_0_, user0_.name as name0_0_ from user user0_ where user0_.id=?
Hibernate: select items0_.id as id0_, items0_.name as name0_, items0_.cid as cid0_ from item items0_ where items0_.id=?
Hibernate: delete from item where cid=?
4.Map映射
DDL:
1.CREATE TABLE user (
2. id INT(11) NOT NULL auto_increment PRIMARY KEY,
3. name VARCHAR(100) NOT NULL default ''
4.);
5.
6.CREATE TABLE item (
7. id INT(11) NOT NULL,
8. name VARCHAR(100) NOT NULL,
9. price decimal(10,2) NOT NULL
10.);
User.java
1.package com.hb3.pack_14.model;
2.
3.import java.math.BigDecimal;
4.import java.util.Map;
5.
6.public class User {
7. 8. private Integer id;
9. private String name;
10. private Map<String, BigDecimal> items;
11. 12. public User() {
13. }
14. 15. public Integer getId() {
16. return id;
17. }
18. public void setId(Integer id) {
19. this.id = id;
20. }
21. public String getName() {
22. return name;
23. }
24. public void setName(String name) {
25. this.name = name;
26. }
27. public Map<String, BigDecimal> getItems() {
28. return items;
29. }
30. public void setItems(Map<String, BigDecimal> items) {
31. this.items = items;
32. }
33. public void addItem(String key, BigDecimal value) {
34. items.put(key, value);
35. }
36. public void removeItem(String key) {
37. items.remove(key);
38. }
39.}
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_14.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. <map name="items" table="item"> 17. <key column="id"/> 18. <map-key column="name" type="java.lang.String"/> 19. <element column="price" type="java.math.BigDecimal"/> 20. </map> 21.
22. </class> 23.
24.</hibernate-mapping>
測試代碼:
1.package com.hb3.pack_14;
2.
3.import java.io.IOException;
4.import java.math.BigDecimal;
5.import java.sql.SQLException;
6.import java.util.HashMap;
7. 8.import org.hibernate.Session;
9.import org.hibernate.SessionFactory;
10.import org.hibernate.Transaction;
11.import org.hibernate.cfg.Configuration;
12. 13.import com.hb3.pack_14.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.setItems(new HashMap<String, BigDecimal>());
27. user1.setName("shenbin");
28. user1.addItem("DC", new BigDecimal(100));
29. user1.addItem("CF Card", new BigDecimal(80));
30.
31. User user2 = new User();
32. user2.setItems(new HashMap<String, BigDecimal>());
33. user2.setName("chenyan");
34. user2.addItem("CD", new BigDecimal(180));
35. 36. Transaction tx = session.beginTransaction();
37. session.save(user1);
38. session.save(user2);
39. tx.commit();
40.
41.
42. session.close();
43. sessionFactory.close();
44. }
45.}
注意:正常運行代碼,需要修改hibernate.cfg.xml文件。
關於容器映射,還有如下說明。
1.內含 Component 的容器
DDL:
1.CREATE TABLE user (
2. id INT(11) NOT NULL auto_increment PRIMARY KEY,
3. name VARCHAR(100) NOT NULL default ''
4.);
5.
6.CREATE TABLE email (
7. id INT(11) NOT NULL,
8. address VARCHAR(100) NOT NULL
9.);
MailAddress.java
1.package com.hb3.pack_15.model;
2.
3.public class MailAddress {
4.
5. private String address;
6. 7. public MailAddress() {
8. }
9.
10. public String getAddress() {
11. return address;
12. }
13. public void setAddress(String address) {
14. this.address = address;
15. }
16. 17. public void sendMail() {
18. System.out.println("Send mail to " + address);
19. }
20.}
User.java
1.package com.hb3.pack_15.model;
2.
3.import java.util.Set;
4.
5.public class User {
6. 7. private Integer id;
8. private String name;
9. private Set<MailAddress> emails;
10. 11. public User() {
12. }
13. 14. public Integer getId() {
15. return id;
16. }
17. 18. public void setId(Integer id) {
19. this.id = id;
20. }
21. 22. public String getName() {
23. return name;
24. }
25. 26. public void setName(String name) {
27. this.name = name;
28. }
29. 30. public Set<MailAddress> getEmails() {
31. return emails;
32. }
33. 34. public void setEmails(Set<MailAddress> emails) {
35. this.emails = emails;
36. }
37.
38. public void addEmail(MailAddress mailAddress) {
39. this.emails.add(mailAddress);
40. }
41.
42. public void removeEmail(MailAddress mailAddress) {
43. this.emails.remove(mailAddress);
44. }
45.}
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_15.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. <set name="emails" table="email"> 17. <key column="id" /> 18. <composite-element class="com.hb3.pack_15.model.MailAddress">
19. <property name="address" column="address"/>
20. </composite-element> 21. </set> 22. </class> 23.</hibernate-mapping>
測試代碼:
1.package com.hb3.pack_15;
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_15.model.MailAddress;
13.import com.hb3.pack_15.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 user = new User();
26. user.setName("shenbin");
27.
28. user.setEmails(new HashSet<MailAddress>());
29. MailAddress mailAddress = new MailAddress();
30. mailAddress.setAddress("[email protected]");
31. user.addEmail(mailAddress);
32.
33. mailAddress = new MailAddress();
34. mailAddress.setAddress("[email protected]");
35. user.addEmail(mailAddress);
36.
37. Transaction tx = session.beginTransaction();
38. session.save(user);
39. tx.commit();
40.
41.
42. session.close();
43. sessionFactory.close();
44. }
45.}
1.Session session = sessionFactory.openSession();
2.
3.User user = (User) session.load(User.class, new Integer(1));
4.Iterator iterator = user.getEmails().iterator();
5.while(iterator.hasNext()) {
6. MailAddress mailAddress = (MailAddress) iterator.next();
7. mailAddress.sendMail();
8.}
9.session.close();
注意:當容器中所放置的物品為自定義的類型時需要使用Component容器。
2.容器的排序
我們知道,Set、Map、Bag是無序的,而List是有序的(所謂有序,就是存入容器的順序會被反映到數據庫中,與入庫的順序一致)。
實現請參照:http://www.javaworld.com.tw/confluence/pages/viewpage.action?pageId=3180
3.容器的延遲初始(Lazy Initialization)
參考資料:http://www.javaworld.com.tw/confluence/pages/viewpage.action?pageId=3181
特別留意Hibernate.initialize()的用法。