Hibernate的多表关联关系映射、案例:一对多、多对一查询与删除、cascade级联保存、修改、删除、级联组合、案例:多对多、级联保存与外键维护、fetch、批量加载、检测策略-day03

本文详细讲解了Hibernate中的一对多、多对一的关联关系映射,包括实体类、映射文件的编写,外键维护方式,cascade级联操作,如保存、修改、删除,以及fetch策略,如select、join、subselect。同时,文章还探讨了多对多关系的处理,级联保存和外键维护注意事项,以及实体状态和加载策略。
摘要由CSDN通过智能技术生成

第一节 Hibernate的多表关联关系映射

1.1 多表关系

  • 表之间关系存在3种:一对多、多对多、一对一
    • 一对多:主表的主键从表外键 形成 主外键关系
    • 多对多:提供中间表(从表),提供2个字段(外键)分别对应两个主表
    • 一对一: 主外键关系

在这里插入图片描述

  • 举例:
    • 多对多关系:学生与课程
    • 一对多关系:客户与订单
    • 一对一关系:人与身份证

1.2 案例:一对多、多对一

  • 例如:客户和订单的关系是一对多的关系,订单和客户的关系是多对一的

第一步:实体类的编写

  • Customer.java
package com.it.hibernate.domain;

import java.util.HashSet;
import java.util.Set;

/**
 * @ClassName Customer
 * @Author shuyy
 * @Date 2020/8/29 
 **/
public class Customer {
   

    private Integer customerId;//客户id
    private String customerName;//客户名

    //一对多,一的一方,使用set集合
    private Set<Order> orders = new HashSet<Order>();

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

    public Set<Order> getOrders() {
   
        return orders;
    }

    public void setOrders(Set<Order> orders) {
   
        this.orders = orders;
    }
}

注意:set集合一定要在定义的时候初始化对象,而且需要提供属性的get/set方法

  • Order.java
package com.it.hibernate.domain;

/**
 * @ClassName Order
 * @Author shuyy
 * @Date 2020/8/29 
 **/
public class Order {
   

    private Integer orderId;//订单id
    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;
    }
}

第二步:映射文件的编写

  • Customer.hbm.xml
<!DOCTYPE hibernate-mapping PUBLIC
		"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
		"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.it.hibernate.domain">
	<!--package包名写在这,简化下面书写-->
	<!--  name:模型的全名称-->
	<class name="Customer" table="t_customer"
	dynamic-update="true" dynamic-insert="true">
		<!-- name:模型属性名  -->
		<id name="customerId" column="customerId">
			<!-- generator:id的生成策略
				increment:也会自动增长id,但是它的这种增长是hibernate自己实现的
							执行select max(id)查询,但是这种会有线程并发问题(如果2个数据同时插入,后面的数据插不进去)

				sequence:一般在oracle数据库使用
				hilo:hibernate:自己实现的id规则【一般不用,不学】

				native:【经常常用】【这个自动增长的实现是mysql实现的,mysql它会记录上一条记录的id值然后加1】
						如果是mysql数据库,id会自动增长
						如果是oracle数据库,也会自动增长,一般是与sequence相关
				uuid:【经常常用】一个长字符串,需要把模型的id改成字符串
						保存的时候,不用自己设置id,hibernate会设置id

				assigned:【经常常用】需要手动设置id属性
			 -->
			<generator class="native"></generator>
		</id>

		<!-- 如果模型的属性和数据库的列名一样,就不用写column -->
		<property name="customerName" type="string" length="20"></property>
		<!-- 一个客户可以有多个订单,hibernate可以双向描述一对多的关系,set中name写的是实例的属性-->
		<set name="orders">
			<!--column指的是Order表中的外键-->
			<!--
				one-to-many:一对多,里面写class,写多的一方
			-->
			<key column="customerId"></key>
			<one-to-many class="Order"></one-to-many>
		</set>
	</class>
</hibernate-mapping>
  • Order.hbm.xml
<!DOCTYPE hibernate-mapping PUBLIC
		"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
		"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.it.hibernate.domain">
	<!--package包名写在这,简化下面书写-->
	<!--  name:模型的全名称-->
	<class name="Order" table="t_order"
	dynamic-update="true" dynamic-insert="true">
		<!-- name:模型属性名  -->
		<id name="orderId" column="orderId">
			<!-- generator:id的生成策略
				increment:也会自动增长id,但是它的这种增长是hibernate自己实现的
							执行select max(id)查询,但是这种会有线程并发问题(如果2个数据同时插入,后面的数据插不进去)

				sequence:一般在oracle数据库使用
				hilo:hibernate:自己实现的id规则【一般不用,不学】

				native:【经常常用】【这个自动增长的实现是mysql实现的,mysql它会记录上一条记录的id值然后加1】
						如果是mysql数据库,id会自动增长
						如果是oracle数据库,也会自动增长,一般是与sequence相关
				uuid:【经常常用】一个长字符串,需要把模型的id改成字符串
						保存的时候,不用自己设置id,hibernate会设置id

				assigned:【经常常用】需要手动设置id属性
			 -->
			<generator class="native"></generator>
		</id>

		<!-- 如果模型的属性和数据库的列名一样,就不用写column -->
		<property name="orderName" type="string" length="32"></property>
		<!-- 多个订单对应一个客户,hibernate可以双向描述一对多的关系,set中name写的是实例的属性-->
		<!--
			many-to-one:多对一
			class:写一的一方
			column:外键
		-->
		<many-to-one name="customer" class="Customer" column="customerId"></many-to-one>
	</class>
</hibernate-mapping>

第三步:配置文件添加映射

  • hibernate.cfg.xml
<!DOCTYPE hibernate-configuration PUBLIC
	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
	<session-factory>
		<!-- 1.配置数据库连接的4个参数 -->
		<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
		<property name="hibernate.connection.url">jdbc:mysql:///hibernate_day1?useUnicode=true&amp;characterEncoding=utf8</property>
		<property name="hibernate.connection.username">root</property>
		<property name="hibernate.connection.password">root</property>

		<!-- 2.是否显示sql语句 -->
		<property name="show_sql">true</property>
		
		<!-- 3.是否格式化sql语句 -->
		<property name="format_sql"&
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值