zoukankan      html  css  js  c++  java
  • [原创]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     @Before
    26     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     @After
    41     public void destroy() {
    42         transaction.commit();
    43         session.close();
    44         sessionFactory.close();
    45     }
    46 
    47     
    48     
    49     @Test
    50     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     @Test
    83     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

  • 相关阅读:
    WPF 进度条
    WPF CPU使用率线性表
    Android annotation
    git 操作
    git 合并指定目录到master
    远程连接mysql报错,ERROR 1045 (28000): Access denied for user 'ODBC'@'localhost' (using password: NO)解决方案
    centos7 安装python2.7.14 并与原版本共存
    pycahrm 断点调试
    ImportError: No module named Crypto.Cipher 报错解决方法
    python操作 rabbitMQ
  • 原文地址:https://www.cnblogs.com/jasonHome/p/5933886.html
Copyright © 2011-2022 走看看