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

时间:2023-03-08 16:35:04

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

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

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

微博:伊直都在0221

QQ:951226918

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

1.一对多关联关系

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

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

    - 单向关联

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

    - 双向关联

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

2.单向 n-1

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

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

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

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

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

3.代码

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

 package com.jason.hibernate.entities.n21;

 public class Customer {

     private Integer customerId;
private String customerName; public Integer getCustomerId() {
return customerId;
} public void setCustomerId(Integer customerId) {
this.customerId = customerId;
} public String getCustomerName() {
return customerName;
} public void setCustomerName(String customerName) {
this.customerName = customerName;
} @Override
public String toString() {
return "Customer [customerId=" + customerId + ", customerName="
+ customerName + "]";
} }

Customer

 package com.jason.hibernate.entities.n21;

 public class Order {

     private Integer orderId;
private String orderName; private Customer customer; public Integer getOrderId() {
return orderId;
} public void setOrderId(Integer orderId) {
this.orderId = orderId;
} public String getOrderName() {
return orderName;
} public void setOrderName(String orderName) {
this.orderName = orderName;
} public Customer getCustomer() {
return customer;
} public void setCustomer(Customer customer) {
this.customer = customer;
} @Override
public String toString() {
return "Order [orderId=" + orderId + ", orderName=" + orderName
+ ", customer=" + customer + "]";
} }

Order

 <?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2016-10-5 17:43:02 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping> <class name="com.jason.hibernate.entities.n21.Customer" table="CUSTOMERS"> <id name="customerId" type="java.lang.Integer">
<column name="CUSTOMER_ID" />
<generator class="native" />
</id> <property name="customerName" type="java.lang.String">
<column name="CUSTOMER_NAME" />
</property> </class> </hibernate-mapping>

Customer.hbm.xml

 <?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2016-10-5 17:43:02 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping package="com.jason.hibernate.entities.n21">
<class name="Order" table="ORDERS"> <id name="orderId" type="java.lang.Integer">
<column name="ORDER_ID" />
<generator class="native" />
</id> <property name="orderName" type="java.lang.String">
<column name="ORDER_NAME" />
</property> <!-- 映射 多对一 关联关系 --> <!--
name: 'n'端 关联 '1'端的属性的名字
class: '1'端 属性对应的类名
colum: '1'端 在 'n'端 对应的数据表中的外键的名字
-->
<many-to-one name="customer" class="Customer">
<column name="CUSTOMER_ID" />
</many-to-one> </class> </hibernate-mapping>

Order.hbm.xml

 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- hibernate 连接数据库的基本信息 -->
<property name="connection.username">root</property>
<property name="connection.password">zhangzhen</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql:///hibernate</property> <!-- 配置hibernate 的节本信息 -->
<!-- hibernate 所使用的数据库方言 -->
<!--<property name="dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>-->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 执行操作时是否在控制台打印SQL -->
<property name="show_sql">true</property> <!-- 是否都SQL 进行格式化 -->
<property name="format_sql">true</property> <!-- 指定自动生成数据表的策略 -->
<property name="hbm2ddl.auto">update</property> <!-- 设置hibernate 的事务隔离级别 -->
<property name="connection.isolation">2</property> <!-- 配置c3p0 -->
<property name="hibernate.c3p0.max_size">10</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="c3p0.acquire_increment">2</property>
<property name="c3p0.idle_test_period">2000</property>
<property name="c3p0.timeout">2000</property>
<property name="c3p0.max_statements">10</property> <mapping resource="com/jason/hibernate/entities/n21/Customer.hbm.xml"/>
<mapping resource="com/jason/hibernate/entities/n21/Order.hbm.xml"/> </session-factory> </hibernate-configuration>

hibernate.cfg.xml

 package com.jason.hibernate.entities.n21;

 import hibernate.helloworld.News;
import hibernate.helloworld.Pay;
import hibernate.helloworld.Worker; import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.Date;
import java.sql.SQLException; import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.jdbc.Work;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.omg.CORBA.ORB; public class HibernateTest { private SessionFactory sessionFactory;
private Session session;
private Transaction transaction;
@Test
public void test() { // 1. 创建一个SessionFatory 对象
SessionFactory sessionFactory = null; // 1) 创建Configuration 对象:对应hibernate 的基本配置信息 和 对象关系映射信息
Configuration configuration = new Configuration().configure(); // 2) 创建一个ServiceRegistry 对象:hibernate 4.x 新天添加的对象。
// hibernate 的任何配置 和 服务都需要在该对象中注册后才有效
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
.applySettings(configuration.getProperties())
.buildServiceRegistry(); // sessionFactory = configuration.buildSessionFactory();
sessionFactory = configuration.buildSessionFactory(serviceRegistry); // 2. 创建一个session 对象
Session session = sessionFactory.openSession(); // 3. 开启事物
Transaction transaction = session.beginTransaction(); // 4.执行保存操作
News news = new News("java", "jason", new Date(
new java.util.Date().getTime()));
session.save(news); // 5.提交事物
transaction.commit();
// 6.关闭session
session.close();
// 7.关闭SessionFactory 对象
sessionFactory.close();
} // 创建上述三个对象
@Before
public void init() {
Configuration configuration = new Configuration().configure();
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
.applySettings(configuration.getProperties())
.buildServiceRegistry(); sessionFactory = configuration.buildSessionFactory(serviceRegistry); session = sessionFactory.openSession(); transaction = session.beginTransaction();
} // 关闭上述三个对象
@After
public void destroy() {
transaction.commit();
session.close();
sessionFactory.close();
} @Test
public void testDelete(){
//在不设定级联关系的情况下,且 1 端的对象 有 n端的对象在引用,不能直接删除1 端的对象
Customer customer = (Customer) session.get(Customer.class, 1);
session.delete(customer);
} @Test
public void testUpdate(){
Order order = (Order) session.get(Order.class, 1);
order.getCustomer().setCustomerName("tom2"); }
@Test
public void testManyToOneGet(){
//1.若查询n 的一端的对象,则默认情况下,只查询了n 的一端的对象,而没有查询关联的1 端的对象
//延迟加载
Order order = (Order) session.get(Order.class, 1);
System.out.println(order); //2.在需要使用到关联的对象,才发送对应的sql 语句
Customer customer = order.getCustomer();
System.out.println(customer); //3.获取order对象,默认情况,其关联的Customer 对象是一个代理对象
} @Test
public void testManyToOneSave(){
Customer customer = new Customer();
customer.setCustomerName("tom"); Order order1 = new Order();
order1.setOrderName("order-3"); Order order2 = new Order();
order2.setOrderName("order-4"); //设定关联关系
order1.setCustomer(customer);
order2.setCustomer(customer); //执行save 操作:先插入 customer,再插入Order, 3条insert语句
//先出入1的一端,在插入 n 的一端,只有 insert 语句
// session.save(customer);
//
// session.save(order1);
// session.save(order2); //先出入 order ,在插入 customer
//3 条insert,2条update
//先插入n 的一端,再插入1的一端,会多出update 语句
//因为在插入n 的一端,无法确定1 的一端的外键,所以只能等1 的一端出入后,再额外的发送update 语句 session.save(order1);
session.save(order2);
session.save(customer); } }

HibernateTest

说明:
  1.在 n 端的 .hbm.xml 中映射关联关系
 <!-- 映射 多对一 关联关系 -->
<!--
name: 'n'端 关联 '1'端的属性的名字
class: '1'端 属性对应的类名
colum: '1'端 在 'n'端 对应的数据表中的外键的名字
-->
<many-to-one name="customer" class="Customer">
<column name="CUSTOMER_ID" />
</many-to-one>
  2.方法注意点:
    
 @Test
public void testManyToOneGet(){
//1.若查询n 的一端的对象,则默认情况下,只查询了n 的一端的对象,而没有查询关联的1 端的对象
//延迟加载
Order order = (Order) session.get(Order.class, 1);
System.out.println(order); //2.在需要使用到关联的对象,才发送对应的sql 语句
Customer customer = order.getCustomer();
System.out.println(customer); //3.获取order对象,默认情况,其关联的Customer 对象是一个代理对象
}
 @Test
public void testManyToOneSave(){
Customer customer = new Customer();
customer.setCustomerName("tom"); Order order1 = new Order();
order1.setOrderName("order-3"); Order order2 = new Order();
order2.setOrderName("order-4"); //设定关联关系
order1.setCustomer(customer);
order2.setCustomer(customer); //执行save 操作:先插入 customer,再插入Order, 3条insert语句
//先出入1的一端,在插入 n 的一端,只有 insert 语句
// session.save(customer);
//
// session.save(order1);
// session.save(order2); //先出入 order ,在插入 customer
//3 条insert,2条update
//先插入n 的一端,再插入1的一端,会多出update 语句
//因为在插入n 的一端,无法确定1 的一端的外键,所以只能等1 的一端出入后,再额外的发送update 语句 session.save(order1);
session.save(order2);
session.save(customer); }

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