首页 > 代码库 > [原创]java WEB学习笔记86:Hibernate学习之路-- -映射 n-n 关系,单向n-n,双向n-n

[原创]java WEB学习笔记86:Hibernate学习之路-- -映射 n-n 关系,单向n-n,双向n-n

本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用

内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系。

本人互联网技术爱好者,互联网技术发烧友

微博:伊直都在0221

QQ:951226918

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

1.单向 n-n

  域模型:

      技术分享

  

  关系数据模型

      技术分享

 

2.解决方法

  1)n-n 的关联必须使用连接表

技术分享

  

  2)与 1-n 映射类似,必须为 set 集合元素添加 key 子元素,指定 CATEGORIES_ITEMS 表中参照 CATEGORIES 表的外键为 CATEGORIY_ID 

    3)与 1-n 关联映射不同的是,建立 n-n 关联时, 集合中的元素使用 many-to-many. many-to-many 子元素的 class 属性指定 items 集合中存放的是 Item 对象 , column 属性指定 CATEGORIES_ITEMS 表中参照 ITEMS 表的外键为 ITEM_ID

  

 1  <!--  table:指定中间表 --> 2         <set name="items" table="CATEGORYS_ITEMS" > 3             <key> 4                 <column name="C_ID" /> 5             </key> 6             <!-- 使用 many-to-many 指定多对多的关联关系,column 指定 set集合中的 持久化类 在中间表的外键列的名称 --> 7             <many-to-many class="Item"> 8                 <column name="I_ID"></column> 9             </many-to-many>10         </set>

 

 

 

3.代码

  Category

 1 package com.jason.hibernate.n2n; 2  3 import java.util.HashSet; 4 import java.util.Set; 5  6 public class Category { 7  8     private Integer id; 9     private String name;10 11     private Set<Item> items = new HashSet<>();12 13     public Integer getId() {14         return id;15     }16 17     public void setId(Integer id) {18         this.id = id;19     }20 21     public String getName() {22         return name;23     }24 25     public void setName(String name) {26         this.name = name;27     }28 29     public Set<Item> getItems() {30         return items;31     }32 33     public void setItems(Set<Item> items) {34         this.items = items;35     }36 37 }

 

  

  Item

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

 

  

  Category.hbm.xml

 1 <?xml version="1.0"?> 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 4  5 <hibernate-mapping package="com.jason.hibernate.n2n"> 6  7     <class name="Category" table="CATEGORYS"> 8      9         <id name="id" type="java.lang.Integer">10             <column name="ID" />11             <generator class="native" />12         </id>13         14         <property name="name" type="java.lang.String">15             <column name="NAME" />16         </property>17         18         19         <!--  table:指定中间表 -->20         <set name="items" table="CATEGORYS_ITEMS" >21             <key>22                 <column name="C_ID" />23             </key>24             <!-- 使用 many-to-many 指定多对多的关联关系,column 指定 set集合中的 持久化类 在中间表的外键列的名称 -->25             <many-to-many class="Item">26                 <column name="I_ID"></column>27             </many-to-many>28         </set>29         30     </class>31     32 </hibernate-mapping>

 

 

  Item.hbm.xml

 1 <?xml version="1.0"?> 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 4  5  6 <hibernate-mapping> 7  8     <class name="com.jason.hibernate.n2n.Item" table="ITEMS"> 9     10         <id name="id" type="java.lang.Integer">11             <column name="ID" />12             <generator class="native" />13         </id>14         15         <property name="name" type="java.lang.String">16             <column name="NAME" />17         </property>18         19     </class>20     21 </hibernate-mapping>

 

 

  HibernateTest

 1 package com.jason.hibernate.n2n; 2  3 import java.util.Date; 4 import java.util.Set; 5  6 import org.hibernate.Hibernate; 7 import org.hibernate.Session; 8 import org.hibernate.SessionFactory; 9 import org.hibernate.Transaction;10 import org.hibernate.cfg.Configuration;11 import org.hibernate.service.ServiceRegistry;12 import org.hibernate.service.ServiceRegistryBuilder;13 import org.junit.After;14 import org.junit.Before;15 import org.junit.Test;16 17 public class HibernateTest {18 19     private SessionFactory sessionFactory;20     private Session session;21     private Transaction transaction;22     23 24     // 创建上述三个对象25     @Before26     public void init() {27         Configuration configuration = new Configuration().configure();28         ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()29                 .applySettings(configuration.getProperties())30                 .buildServiceRegistry();31 32         sessionFactory = configuration.buildSessionFactory(serviceRegistry);33 34         session = sessionFactory.openSession();35 36         transaction = session.beginTransaction();37     }38 39     // 关闭上述三个对象40     @After41     public void destroy() {42         transaction.commit();43         session.close();44         sessionFactory.close();45     }46 47     48     49     @Test50     public void testSave(){51         52         Category category1 = new Category();53         category1.setName("C-AA");54         55         Category category2 = new Category();56         category2.setName("C-BB");57     58         Item item1 = new Item();59         item1.setName("I-AA");60         61         Item item2 = new Item();62         item2.setName("I-BB");63         64         //设定关联关系65         category1.getItems().add(item1);66         category1.getItems().add(item2);67         68         69         category2.getItems().add(item1);70         category2.getItems().add(item2);    71         72         73         session.save(category1);74         session.save(category2);75         76         session.save(item1);77         session.save(item2);    78         79     }80     81     82     @Test83     public void testGet(){84         85         Category category = (Category) session.get(Category.class, 1);86         System.out.println(category.getName());87         88         //需要拦截中间表89         Set<Item>  items = category.getItems();90         System.out.println(items.size());91           92     }93     94     95     96     97 }

 

 

hibernate.cfg.xml

 1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE hibernate-configuration PUBLIC 3         "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 4         "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> 5 <hibernate-configuration> 6     <session-factory> 7         <!-- hibernate 连接数据库的基本信息 --> 8         <property name="connection.username">root</property> 9         <property name="connection.password">zhangzhen</property>10         <property name="connection.driver_class">com.mysql.jdbc.Driver</property>11         <property name="connection.url">jdbc:mysql:///hibernate</property>12         13         14         <!-- 配置hibernate 的节本信息 -->15         <!-- hibernate 所使用的数据库方言 -->16         <!--<property name="dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>-->17    <property name="dialect">org.hibernate.dialect.MySQLDialect</property> 18         <!-- 执行操作时是否在控制台打印SQL  -->19         <property name="show_sql">true</property>20         21         <!-- 是否都SQL 进行格式化 -->22         <property name="format_sql">true</property>23         24         25         <!-- 指定自动生成数据表的策略 -->26         <property name="hbm2ddl.auto">update</property>27         28         <!-- 设置hibernate 的事务隔离级别 -->29         <property name="connection.isolation">2</property>30         31         32         <!-- 配置c3p0 -->33         <property name="hibernate.c3p0.max_size">10</property>34         <property name="hibernate.c3p0.min_size">5</property>35         <property name="c3p0.acquire_increment">2</property>36         <property name="c3p0.idle_test_period">2000</property>37         <property name="c3p0.timeout">2000</property>38         <property name="c3p0.max_statements">10</property>39         40         41         <!-- 对于mysql 无效,对于oracle 有效 -->42         <!-- 设定JDBC 的Statement 读取数据的时候每次从数据库中取出的记录的条数 -->43         <property name="hibernate.jdbc.fetch_size">100</property>44         45         <!-- 设置数据库进行批量删除,批量更新和批量插入的时候的大小 -->46         <property name="hibernate.jdbc.batch_size">30</property>47 <mapping resource="com/jason/hibernate/n2n/Category.hbm.xml"/>48         <mapping resource="com/jason/hibernate/n2n/Item.hbm.xml"/>49         50         51     </session-factory>52     53 </hibernate-configuration>

 

 

 

 

 

 

 

4.双向n-n

  域模型: 

    技术分享

  关系数据模型

    技术分享

  1)核心点

    ① 双向 n-n 关联需要两端都使用集合属性

    ② 双向n-n关联必须使用连接表

    ③ 集合属性应增加 key 子元素用以映射外键列, 集合元素里还应增加many-to-many子元素关联实体类

    ④ 在双向 n-n 关联的两边都需指定连接表的表名及外键列的列名. 两个集合元素 set 的 table 元素的值必须指定,而且必须相同

      set元素的两个子元素:key 和 many-to-many 都必须指定 column 属性其中

        key 和 many-to-many 分别指定本持久化类和关联类在连接表中的外键列名,因此两边的 key 与 many-to-many 的column属性交叉相同。

        也就是说,一边的set元素的key的 cloumn值为a,many-to-many 的 column 为b;则另一边的 set 元素的 key 的 column 值 b,many-to-many的 column 值为 a.

                                    技术分享

 

 

    ⑥ 对于双向 n-n 关联, 必须把其中一端的 inverse 设置为 true, 否则两端都维护关联关系可能会造成主键冲突.

 

 

Catogery

 1 package com.jason.hibernate.n2n; 2  3 import java.util.HashSet; 4 import java.util.Set; 5  6 public class Category { 7  8     private Integer id; 9     private String name;10 11     private Set<Item> items = new HashSet<>();12 13     public Integer getId() {14         return id;15     }16 17     public void setId(Integer id) {18         this.id = id;19     }20 21     public String getName() {22         return name;23     }24 25     public void setName(String name) {26         this.name = name;27     }28 29     public Set<Item> getItems() {30         return items;31     }32 33     public void setItems(Set<Item> items) {34         this.items = items;35     }36 37 }

 

 

Item

 1 package com.jason.hibernate.n2n; 2  3 import java.util.HashSet; 4 import java.util.Set; 5  6 public class Item { 7  8     private Integer id; 9     private String name;10 11     private Set<Category> categories = new HashSet<>();12 13     public Set<Category> getCategories() {14         return categories;15     }16 17     public void setCategories(Set<Category> categories) {18         this.categories = categories;19     }20 21     public Integer getId() {22         return id;23     }24 25     public void setId(Integer id) {26         this.id = id;27     }28 29     public String getName() {30         return name;31     }32 33     public void setName(String name) {34         this.name = name;35     }36 37 }

 

 

Category.hbm.xml

 1 <?xml version="1.0"?> 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 4  5 <hibernate-mapping package="com.jason.hibernate.n2n"> 6  7     <class name="Category" table="CATEGORYS"> 8      9         <id name="id" type="java.lang.Integer">10             <column name="ID" />11             <generator class="native" />12         </id>13         14         <property name="name" type="java.lang.String">15             <column name="NAME" />16         </property>17         18         19         <!--  table:指定中间表 -->20         <set name="items" table="CATEGORYS_ITEMS" >21             <key>22                 <column name="C_ID" />23             </key>24             <!-- 使用 many-to-many 指定多对多的关联关系,column 指定 set集合中的 持久化类 在中间表的外键列的名称 -->25             <many-to-many class="Item">26                 <column name="I_ID"></column>27             </many-to-many>28         </set>29         30     </class>31     32 </hibernate-mapping>

 

 

Item.hbm.xml

 1 <?xml version="1.0"?> 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 4  5  6 <hibernate-mapping> 7  8     <class name="com.jason.hibernate.n2n.Item" table="ITEMS"> 9     10         <id name="id" type="java.lang.Integer">11             <column name="ID" />12             <generator class="native" />13         </id>14         15         <property name="name" type="java.lang.String">16             <column name="NAME" />17         </property>18         19         20         21         <set name="categories" table="CATEGORYS_ITEMS">22             <key column="I_ID"></key>23             <many-to-many class="com.jason.hibernate.n2n.Category">24                 <column name="C_ID"></column>25             </many-to-many>26         </set>27         28         29         30     </class>31     32 </hibernate-mapping>

 

hibernate.cfg.xml

hibernateTest

 

[原创]java WEB学习笔记86:Hibernate学习之路-- -映射 n-n 关系,单向n-n,双向n-n