引言:
- 單向“一對多”和“多對一”
- 一對多:將一的主鍵加入到多的一方表中作為外鍵,在一的一方需要加入多的set集合
- 可以通過“一”操作“多”,反之,不可以,比如,添加category目錄,那么其屬性中所有對應的book會自動添加進去
- 多對一:將多一方的主鍵加入到一的表中作為主鍵,在多的一方需要定義一的對象
- 可以通過“多”操作“一”,反之,不可以,比如,添加book,那么其所屬的category會自動添加進來,不需要在去找,然后添加
- 一對多:將一的主鍵加入到多的一方表中作為外鍵,在一的一方需要加入多的set集合
- 雙向多對一:雙方相互添加彼此
要建兩張表:book和category
Book類:
1 public class Book { 2 private Integer bookId; 3 private String bookName; 4 private String author; 5 private double price; 6 7 private Category category; 8 9 /*省略set和get方法*/ 10 11 }
book.hbm.xm
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> 6 7 <!--多對一雙向關聯--> 8 <!--“多”--> 9 <class name="com.ajax.model.Book" table="BOOK" schema="TEST"> 10 <id name="bookId" column="BOOKID"/> 11 <property name="bookName" column="BOOKNAME"/> 12 <property name="author" column="AUTHOR"/> 13 <property name="price" column="PRICE" type="java.lang.Double"/> 14 15 <!--建立多對一關聯映射 16 book(多)映射關鍵點: 17 1.book的哪個屬性映射?name:categoty 18 2.通過什么外鍵字段映射:categoty_id 19 3.映射到哪個實體類?class:com.ajax.model.category 20 --> 21 <!--name 對應 的是book中的對應的多字段--> 22 <many-to-one name="category" column="CATEGORYID" class="com.ajax.model.Category"/> 23 </class> 24 </hibernate-mapping>
category
1 public class Category { 2 3 private Integer categoryId; 4 private String categoryName; 5 private Set<Book> books; 6 7 //省去set和get方法 8 }
category.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> 6 7 <class name="com.ajax.model.Category" table="CATEGORY" schema="TEST"> 8 <id name="categoryId" column="CATEGORYID"/> 9 <property name="categoryName" column="NAME"/> 10 11 <!--一對多關聯隱射配置 12 “一”: 13 1.指定映射的集合屬性:books 14 2.集合屬性對應的集合表:BOOK 15 3.集合表的外鍵字段t_book.category_id 16 4.集合元素的類型 17 --> 18 19 <set name="books" table="BOOK" inverse="true"> 20 <!--column的值category_id與多對一關系中的外鍵值一致 21 雙向關聯用inverse,單向關聯用cascade表示兩張表的級聯,inverse默認為false, 22 表示由當前對象負責維護兩張表之間的級聯關系--> 23 <key column="CATEGORYID"></key> 24 <one-to-many class="com.ajax.model.Book"/> 25 </set> 26 </class> 27 </hibernate-mapping>
hibernate.cfg.xml文件
1 <?xml version='1.0' encoding='utf-8'?> 2 <!DOCTYPE hibernate-configuration PUBLIC 3 "-//Hibernate/Hibernate Configuration DTD//EN" 4 "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> 5 <hibernate-configuration> 6 <session-factory> 7 <property name="connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property> 8 <property name="connection.username">test</property> 9 <property name="connection.password">123456</property> 10 11 <property name="dialect">org.hibernate.dialect.Oracle10gDialect</property> 12 13 <!--顯示生成sql語句--> 14 <property name="show_sql">true</property> 15 <!--格式化sql語句--> 16 <property name="hibernate.format_sql">true</property> 17 <!--如果表不存在,將自動創建--> 18 <!--<property name="hibernate.hbm2ddl.auto">update</property>--> 19 20 <property name="connection.driver_class">oracle.jdbc.OracleDriver</property> 21 22 <mapping resource="com/ajax/model/Book.hbm.xml"/> 23 <mapping resource="com/ajax/model/Category.hbm.xml"/> 24 <!--<mapping resource="com/ajax/model/Book.hbm.xml"/>--> 25 26 <!--以注解方式配置--> 27 <!--<mapping class="com.model.Book"/>--> 28 <!--<mapping class="com.automapping.Book"/>--> 29 30 <!--<mapping resource="com/model/Book.hbm.xml"/>--> 31 </session-factory> 32 </hibernate-configuration>
注:這玩意hibernate.cfg.xml文件的頭部分也有坑:
1 <?xml version='1.0' encoding='utf-8'?> 2 <!DOCTYPE hibernate-configuration PUBLIC 3 "-//Hibernate/Hibernate Configuration DTD//EN" 4 "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
idea自動生成的會提示找不到配置文件:
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"
根據實體隱射關系自動生成表:
- SchemaExport()
- 配置文件:
<property name="hibernate.hbm2ddl.auto">true</property>
1 /* 2 *測試使用SchemaExport根據實體類及映射關系生成表 3 */ 4 @Test 5 public void TestSchemaExport(){ 6 Configuration cfg = new Configuration().configure();//讀取配置文件 7 //SessionFactory sessionFactory = cfg.buildSessionFactory();//根據配置文件創建session工廠 8 SchemaExport export = new SchemaExport(cfg);//創建SchemaExport 9 //執行生成表。參數1:是否顯示sql語句,參數2:是否到數據庫中執行 10 export.create(true,true); 11 } 12 /*
輸出結果:(生成了兩個外鍵,原因是 在配置文件中拼錯了)

測試:
HibernateUtil.java
public class HibernateUtil { private static SessionFactory sessionFactory; private HibernateUtil(){} static{ Configuration configuration = new Configuration().configure(); sessionFactory = configuration.buildSessionFactory(); } public static SessionFactory getSessionFactory(){ return sessionFactory; } public static Session getSession(){ return sessionFactory.openSession(); } public static void closeSession(Session session){ if (null !=session){ session.close(); } } }
測試方法:
1 /* 2 *往數據庫中寫點數據 3 */ 4 @Test 5 public void addData(){ 6 Session session = null; 7 try { 8 session = HibernateUtil.getSession(); 9 10 session.beginTransaction(); 11 Category category = new Category(); 12 category.setCategoryId(1); 13 category.setCategoryName("古典小說"); 14 15 Category category1 = new Category(); 16 category1.setCategoryId(2); 17 category1.setCategoryName("都市言情"); 18 19 Book b1 = new Book(); 20 b1.setBookId(1); 21 b1.setBookName("西游記"); 22 b1.setAuthor("吳承恩"); 23 b1.setPrice(10); 24 25 Book b2 = new Book(); 26 b2.setBookId(2); 27 b2.setBookName("天堂向左,深圳往右"); 28 b2.setAuthor("慕容雪村"); 29 b2.setPrice(20); 30 31 Book b3 = new Book(); 32 b3.setBookId(3); 33 b3.setBookName("封神演義"); 34 b3.setAuthor("xxx"); 35 b3.setPrice(20); 36 37 //保存各自的單表信息 38 session.persist(b1); 39 session.persist(b2); 40 session.persist(b3); 41 42 session.persist(category); 43 session.persist(category1); 44 45 46 //創建表的關聯關系,保存在多的一方 47 b1.setCategory(category); 48 b2.setCategory(category1); 49 b3.setCategory(category); 50 51 // category.getBooks().add(b1); 52 // category1.getBooks().add(b2); 53 // category.getBooks().add(b3); 54 55 session.save(b1); 56 session.save(b2); 57 session.save(b3); 58 session.getTransaction().commit(); 59 }catch (Exception e){ 60 e.printStackTrace(); 61 session.getTransaction().rollback(); 62 63 }finally { 64 HibernateUtil.closeSession(session); 65 System.out.println("成功關閉session!"); 66 } 67 68 } 69 70 @Test 71 public void TestFindBooks(){ 72 Session session = null; 73 session = HibernateUtil.getSession(); 74 session.getTransaction().begin(); 75 76 Category category = (Category) session.get(Category.class,1); 77 System.out.println("目錄id:"+category.getCategoryId()); 78 System.out.println("目錄name:"+category.getCategoryName()); 79 80 //遍歷該目錄下的所有書籍 81 Set<Book> books = category.getBooks(); 82 System.out.println("屬於'"+category.getCategoryName()+"'的書有"); 83 84 for (Iterator<Book> it =books.iterator();it.hasNext();){ 85 Book book = (Book) it.next(); 86 System.out.println("書id:"+book.getBookId()); 87 System.out.println("書名:"+book.getBookName()); 88 System.out.println("作者:"+book.getAuthor()); 89 System.out.println("價格:"+book.getPrice()); 90 System.out.println("----------------------------------"); 91 } 92 }
嘗試在“一”的一方保存關聯關系,把添加數據部分代碼改了:
1 //創建表的關聯關系,保存在多的一方 2 // b1.setCategory(category); 3 // b2.setCategory(category1); 4 // b3.setCategory(category); 5 6 category.getBooks().add(b1); 7 category1.getBooks().add(b2); 8 category.getBooks().add(b3); 9 10 session.save(category); 11 session.save(category1); 12 13 // session.save(b1); 14 // session.save(b2); 15 // session.save(b3);
運行會報錯,因為在配置文件中,已經約定了inverse 屬性,嘗試改變 會報錯的哦!

