Hibernate 一對多雙向關聯(XML方式配置)


引言:

  1. 單向“一對多”和“多對一”
    • 一對多:將一的主鍵加入到多的一方表中作為外鍵,在一的一方需要加入多的set集合
      •  可以通過“一”操作“多”,反之,不可以,比如,添加category目錄,那么其屬性中所有對應的book會自動添加進去
    • 多對一:將多一方的主鍵加入到一的表中作為主鍵,在多的一方需要定義一的對象
      •  可以通過“多”操作“一”,反之,不可以,比如,添加book,那么其所屬的category會自動添加進來,不需要在去找,然后添加
  2. 雙向多對一:雙方相互添加彼此

要建兩張表: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 屬性,嘗試改變 會報錯的哦!

 


免責聲明!

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



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