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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[原创]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     @Override
25     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     @Override
35     public String toString() {
36         return "Order [orderId=" + orderId + ", orderName=" + orderName
37                 + ", 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     @Test
102     public void testUpdate(){
103         Order order = (Order) session.get(Order.class, 1);
104         order.getCustomer().setCustomerName("tom2");
105         
106     }
107     @Test
108     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     @Test
124     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 ,在插入 customer
147         //3 条insert,2条update
148         //先插入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 ,在插入 customer
25         //3 条insert,2条update
26         //先插入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方法测试及注意点的主要内容,如果未能解决你的问题,请参考以下文章

[原创]java WEB学习笔记10:GenericServlet

[原创]java WEB学习笔记18:java EE 中的MVC 设计模式

[原创]java WEB学习笔记08:ServletResponse & HttpServletResponse

[原创]java WEB学习笔记20:案例完整实践(part 1)---MVC架构分析

[原创]java WEB学习笔记21:案例完整实践(part 2)---.DAO层设计

[原创]java WEB学习笔记13:JSP介绍(背景,特点,原理)