首页 > 代码库 > [原创]java WEB学习笔记82:Hibernate学习之路---映射 一对多关联关系,配置,CRUD方法测试及注意点

[原创]java WEB学习笔记82:Hibernate学习之路---映射 一对多关联关系,配置,CRUD方法测试及注意点

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

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

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

微博:伊直都在0221

QQ:951226918

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

1.一对多关联关系

  1)在领域模型中, 类与类之间最普遍的关系就是关联关系.

  2)在 UML 中, 关联是有方向的:以 Customer 和 Order 为例: 一个用户能发出多个订单, 而一个订单只能属于一个客户. 从 Order 到 Customer 的关联是多对一关联; 而从 Customer 到 Order 是一对多关联

    - 单向关联

  技术分享

    - 双向关联

  技术分享

 

2.单向 n-1

  1)单向 n-1 关联只需从 n 的一端可以访问 1 的一端

  2)域模型: 从 Order 到 Customer 的多对一单向关联需要在Order 类中定义一个 Customer 属性, 而在 Customer 类中无需定义存放 Order 对象的集合属性

                                 技术分享

  3)关系数据模型:ORDERS 表中的 CUSTOMER_ID 参照 CUSTOMER 表的主键

               技术分享

 

 

 

 

3.代码

技术分享

技术分享
 1 package com.jason.hibernate.entities.n21; 2  3 public class Customer { 4  5     private Integer customerId; 6     private String customerName; 7  8     public Integer getCustomerId() { 9         return customerId;10     }11 12     public void setCustomerId(Integer customerId) {13         this.customerId = customerId;14     }15 16     public String getCustomerName() {17         return customerName;18     }19 20     public void setCustomerName(String customerName) {21         this.customerName = customerName;22     }23 24     @Override25     public String toString() {26         return "Customer [customerId=" + customerId + ", customerName="27                 + customerName + "]";28     }29 30     31 }
Customer
技术分享
 1 package com.jason.hibernate.entities.n21; 2  3 public class Order { 4  5     private Integer orderId; 6     private String orderName; 7  8     private Customer customer; 9 10     public Integer getOrderId() {11         return orderId;12     }13 14     public void setOrderId(Integer orderId) {15         this.orderId = orderId;16     }17 18     public String getOrderName() {19         return orderName;20     }21 22     public void setOrderName(String orderName) {23         this.orderName = orderName;24     }25 26     public Customer getCustomer() {27         return customer;28     }29     30     public void setCustomer(Customer customer) {31         this.customer = customer;32     }33 34     @Override35     public String toString() {36         return "Order [orderId=" + orderId + ", orderName=" + orderName37                 + ", customer=" + customer + "]";38     }39 40     41 }
Order
技术分享
 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 <!-- Generated 2016-10-5 17:43:02 by Hibernate Tools 3.4.0.CR1 --> 5 <hibernate-mapping> 6  7     <class name="com.jason.hibernate.entities.n21.Customer" table="CUSTOMERS"> 8      9         <id name="customerId" type="java.lang.Integer">10             <column name="CUSTOMER_ID" />11             <generator class="native" />12         </id>13         14         <property name="customerName" type="java.lang.String">15             <column name="CUSTOMER_NAME" />16         </property>17         18     </class>19     20 </hibernate-mapping>
Customer.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 <!-- Generated 2016-10-5 17:43:02 by Hibernate Tools 3.4.0.CR1 --> 5 <hibernate-mapping package="com.jason.hibernate.entities.n21"> 6     <class name="Order" table="ORDERS"> 7      8         <id name="orderId" type="java.lang.Integer"> 9             <column name="ORDER_ID" />10             <generator class="native" />11         </id>12         13         <property name="orderName" type="java.lang.String">14             <column name="ORDER_NAME" />15         </property>16         17         <!-- 映射 多对一 关联关系 -->18         19         <!-- 20             name: ‘n‘端 关联 ‘1‘端的属性的名字21             class: ‘1‘端 属性对应的类名22             colum: ‘1‘端  在 ‘n‘端 对应的数据表中的外键的名字23          -->24         <many-to-one name="customer" class="Customer">25             <column name="CUSTOMER_ID" />26         </many-to-one>27         28     </class>29     30 </hibernate-mapping>
Order.hbm.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 <mapping resource="com/jason/hibernate/entities/n21/Customer.hbm.xml"/>42         <mapping resource="com/jason/hibernate/entities/n21/Order.hbm.xml"/>43 44 45 46         47     </session-factory>48     49 </hibernate-configuration>
hibernate.cfg.xml
技术分享
  1 package com.jason.hibernate.entities.n21;  2   3 import hibernate.helloworld.News;  4 import hibernate.helloworld.Pay;  5 import hibernate.helloworld.Worker;  6   7 import java.io.FileInputStream;  8 import java.io.FileNotFoundException;  9 import java.io.InputStream; 10 import java.sql.Blob; 11 import java.sql.Connection; 12 import java.sql.Date; 13 import java.sql.SQLException; 14  15 import org.hibernate.Hibernate; 16 import org.hibernate.Session; 17 import org.hibernate.SessionFactory; 18 import org.hibernate.Transaction; 19 import org.hibernate.cfg.Configuration; 20 import org.hibernate.jdbc.Work; 21 import org.hibernate.service.ServiceRegistry; 22 import org.hibernate.service.ServiceRegistryBuilder; 23 import org.junit.After; 24 import org.junit.Before; 25 import org.junit.Test; 26 import org.omg.CORBA.ORB; 27  28 public class HibernateTest { 29  30     private SessionFactory sessionFactory; 31     private Session session; 32     private Transaction transaction; 33     @Test 34     public void test() { 35  36         // 1. 创建一个SessionFatory 对象 37         SessionFactory sessionFactory = null; 38  39         // 1) 创建Configuration 对象:对应hibernate 的基本配置信息 和 对象关系映射信息 40         Configuration configuration = new Configuration().configure(); 41  42         // 2) 创建一个ServiceRegistry 对象:hibernate 4.x 新天添加的对象。 43         // hibernate 的任何配置 和 服务都需要在该对象中注册后才有效 44         ServiceRegistry serviceRegistry = new ServiceRegistryBuilder() 45                 .applySettings(configuration.getProperties()) 46                 .buildServiceRegistry(); 47  48         // sessionFactory = configuration.buildSessionFactory(); 49         sessionFactory = configuration.buildSessionFactory(serviceRegistry); 50  51         // 2. 创建一个session 对象 52         Session session = sessionFactory.openSession(); 53  54         // 3. 开启事物 55         Transaction transaction = session.beginTransaction(); 56  57         // 4.执行保存操作 58         News news = new News("java", "jason", new Date( 59                 new java.util.Date().getTime())); 60         session.save(news); 61  62         // 5.提交事物 63         transaction.commit(); 64         // 6.关闭session 65         session.close(); 66         // 7.关闭SessionFactory 对象 67         sessionFactory.close(); 68     } 69  70     // 创建上述三个对象 71     @Before 72     public void init() { 73         Configuration configuration = new Configuration().configure(); 74         ServiceRegistry serviceRegistry = new ServiceRegistryBuilder() 75                 .applySettings(configuration.getProperties()) 76                 .buildServiceRegistry(); 77  78         sessionFactory = configuration.buildSessionFactory(serviceRegistry); 79  80         session = sessionFactory.openSession(); 81  82         transaction = session.beginTransaction(); 83     } 84  85     // 关闭上述三个对象 86     @After 87     public void destroy() { 88         transaction.commit(); 89         session.close(); 90         sessionFactory.close(); 91     } 92  93      94     @Test 95     public void testDelete(){ 96         //在不设定级联关系的情况下,且 1 端的对象 有 n端的对象在引用,不能直接删除1 端的对象 97         Customer customer = (Customer) session.get(Customer.class, 1); 98         session.delete(customer); 99     }100     101     @Test102     public void testUpdate(){103         Order order = (Order) session.get(Order.class, 1);104         order.getCustomer().setCustomerName("tom2");105         106     }107     @Test108     public void testManyToOneGet(){109         //1.若查询n 的一端的对象,则默认情况下,只查询了n 的一端的对象,而没有查询关联的1 端的对象110         //延迟加载111         Order order = (Order) session.get(Order.class, 1);112         System.out.println(order);113         114         //2.在需要使用到关联的对象,才发送对应的sql 语句115         Customer customer = order.getCustomer();116         System.out.println(customer);117         118         119         //3.获取order对象,默认情况,其关联的Customer 对象是一个代理对象120     }121     122     123     @Test124     public void testManyToOneSave(){125         Customer customer = new Customer();126         customer.setCustomerName("tom");127         128         Order order1 = new Order();129         order1.setOrderName("order-3");130         131         Order order2 = new Order();132         order2.setOrderName("order-4");133         134         //设定关联关系135         order1.setCustomer(customer);136         order2.setCustomer(customer);137         138         //执行save 操作:先插入 customer,再插入Order, 3条insert语句139         //先出入1的一端,在插入 n 的一端,只有 insert 语句140 //        session.save(customer);141 //        142 //        session.save(order1);143 //        session.save(order2);144         145         146         //先出入 order ,在插入 customer147         //3 条insert,2条update148         //先插入n 的一端,再插入1的一端,会多出update 语句149         //因为在插入n 的一端,无法确定1 的一端的外键,所以只能等1 的一端出入后,再额外的发送update 语句150         151         session.save(order1);152         session.save(order2);153         session.save(customer);154         155         156         157         158     }159     160     161     162     163     164 }
HibernateTest

 

 

 

 

说明:
  1.在 n 端的 .hbm.xml 中映射关联关系
1 <!-- 映射 多对一 关联关系 -->2         <!-- 3             name: ‘n‘端 关联 ‘1‘端的属性的名字4             class: ‘1‘端 属性对应的类名5             colum: ‘1‘端  在 ‘n‘端 对应的数据表中的外键的名字6          -->7         <many-to-one name="customer" class="Customer">8             <column name="CUSTOMER_ID" />9         </many-to-one>

 


  2.方法注意点:
    
 1 @Test 2     public void testManyToOneGet(){ 3         //1.若查询n 的一端的对象,则默认情况下,只查询了n 的一端的对象,而没有查询关联的1 端的对象 4         //延迟加载 5         Order order = (Order) session.get(Order.class, 1); 6         System.out.println(order); 7          8         //2.在需要使用到关联的对象,才发送对应的sql 语句 9         Customer customer = order.getCustomer();10         System.out.println(customer);11         12         13         //3.获取order对象,默认情况,其关联的Customer 对象是一个代理对象14     }
 1 @Test 2     public void testManyToOneSave(){       3         Customer customer = new Customer(); 4         customer.setCustomerName("tom"); 5          6         Order order1 = new Order(); 7         order1.setOrderName("order-3"); 8          9         Order order2 = new Order();10         order2.setOrderName("order-4");11         12         //设定关联关系13         order1.setCustomer(customer);14         order2.setCustomer(customer);15         16         //执行save 操作:先插入 customer,再插入Order, 3条insert语句17         //先出入1的一端,在插入 n 的一端,只有 insert 语句18 //        session.save(customer);19 //        20 //        session.save(order1);21 //        session.save(order2);22         23         24         //先出入 order ,在插入 customer25         //3 条insert,2条update26         //先插入n 的一端,再插入1的一端,会多出update 语句27         //因为在插入n 的一端,无法确定1 的一端的外键,所以只能等1 的一端出入后,再额外的发送update 语句28         29         session.save(order1);30         session.save(order2);31         session.save(customer);32         33     }

 

 

技术分享

 

[原创]java WEB学习笔记82:Hibernate学习之路---映射 一对多关联关系,配置,CRUD方法测试及注意点