-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
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 }