hibernate的关联与级联

本文介绍了如何在Java项目中使用Hibernate和SpringDataJPA进行订单(Order)与订单项(OrderItem)的一对多和多对一关系设置,包括级联新增、查询和删除,以及懒加载策略的运用。
摘要由CSDN通过智能技术生成

initOrderItems = 0;//0代表懒加载 1代表立即加载

在订单项的实体类中需要添加一个属性:Order order

定义一对多的关系时需要采用接口方式

1、在Order.hbm.xml中需要添加(建立订单对订单项的一对多的关系)

2、在OrderItem.hbm.xml中需要添加(建立订单项对订单多对一的关系)

三、级联新增、级联查询,普通删除

pom.xml

org.springframework.data

spring-data-jpa

2.1.5.RELEASE

org.hibernate

hibernate-core

5.3.7.Final

org.springframework

spring-test

5.1.5.RELEASE

junit

junit

4.12

mysql

mysql-connector-java

5.1.47

com.mchange

c3p0

0.9.5.2

org.springframework

spring-aspects

5.1.5.RELEASE

com.querydsl

querydsl-jpa

4.1.4

方法:

package com.four.dao;

import java.util.List;

import org.hibernate.Hibernate;

import org.hibernate.Session;

import org.hibernate.Transaction;

import com.four.entity.Order;

import com.four.entity.OrderItem;

import com.two.util.SessionFactoryUtil;

public class OrderDao {

//订单项新增

public Integer addOrderItem(OrderItem orderItem) {

Session session = SessionFactoryUtil.getSession();

Transaction transaction = session.beginTransaction();

Integer otid = (Integer) session.save(orderItem);

transaction.commit();

session.close();

return otid;

}

//订单新增

public Integer addOrder(Order order) {

Session session = SessionFactoryUtil.getSession();

Transaction transaction = session.beginTransaction();

Integer otid = (Integer) session.save(order);

transaction.commit();

session.close();

return otid;

}

//查单个

public Order getOrder(Order order) {

Session session = SessionFactoryUtil.getSession();

Transaction transaction = session.beginTransaction();

Order o = session.get(Order.class, order.getOrderId());

if(o != null && new Integer(1).equals(order.getInitOrderItems())) {

Hibernate.initialize(o.getOrderItems());

}

transaction.commit();

session.close();

return o;

}

//查所有

public List getOrderList(){

Session session = SessionFactoryUtil.getSession();

Transaction transaction = session.beginTransaction();

List list = session.createQuery(“from Order”).list();

transaction.commit();

session.close();

return list;

}

//删除(hibernate需要先删从表(订单项)再删主表(订单))

public void delOrder(Order order) {

Session session = SessionFactoryUtil.getSession();

Transaction transaction = session.beginTransaction();

Order o = session.get(Order.class, order.getOrderId());

for (OrderItem ot : o.getOrderItems()) {

session.delete(ot);

}

session.delete(o);

transaction.commit();

session.close();

}

}

JUnit测试

package com.four.dao;

import java.util.Iterator;

import java.util.List;

import org.junit.Test;

import com.four.entity.Order;

import com.four.entity.OrderItem;

public class OrderDaoTest {

private OrderDao orderDao = new OrderDao();

/**

  • Repeated column in mapping for entity:

  • com.zking.four.entity.OrderItem column: oid

  • (should be mapped with insert=“false” update=“false”)

  • 同一个字段被映射了两次

*/

@Test

public void testAddOrderItem() {//订单项新增

OrderItem orderItem = new OrderItem();

// orderItem.setOid(7);//普通新增

orderItem.setProductId(89);

orderItem.setQuantity(78);

Order order = new Order();

order.setOrderId(5);

orderItem.setOrder(order);

this.orderDao.addOrderItem(orderItem);

}

//提交一个具有6个订单项的订单

// addOrder 1

// addOrderItem 6

@Test

public void testAddOrder() {//订单新增

Order order = new Order();

order.setOrderNo(“P8”);

OrderItem orderItem;

for (int i = 1; i < 7; i++) {

orderItem = new OrderItem();

orderItem.setProductId(i);

orderItem.setQuantity(i);

order.getOrderItems().add(orderItem);

orderItem.setOrder(order);

}

this.orderDao.addOrder(order);

}

@Test

public void testGetOrder() {//查单个

Order order = new Order();

order.setOrderId(8);

order.setInitOrderItems(1);

Order o = this.orderDao.getOrder(order);

System.out.println(o.getOrderNo());

System.out.println(o.getOrderItems().size());

for (OrderItem ot : o.getOrderItems()) {

System.out.println(ot.getProductId());

}

}

@Test

public void testGetOrderList() {//查所有

List list = this.orderDao.getOrderList();

for (Order o : list) {

System.out.println(o.getOrderNo());

System.out.println(o.getOrderItems().size());

for (OrderItem ot : o.getOrderItems()) {

System.out.println(ot.getProductId());

}

}

}

@Test

public void testDelOrder() {//删除

Order order = new Order();

order.setOrderId(8);

this.orderDao.delOrder(order);

}

}

“一方” 保存示意图:

=========================================================================

在这里插入图片描述

关于 “一方” 多方 保存的简单总结:

=================================================================================

在这里插入图片描述

级联保存的简单总结:

========================================================================

在这里插入图片描述

案例

================================================================

一对多


首先我们先理解一对多的什么意思,在数据库A表上的一条数据,可以映射B表的多条数据库,也就是站在A表的角度,就被B表的都跳数据引用,

hiberante就认为A表拥有一个B表的集合,所以配置如下

package com.xingxue.entity;

import java.util.Date;

import java.util.HashSet;

import java.util.Set;

import javax.persistence.Column;

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.GenerationType;

import javax.persistence.Id;

import javax.persistence.JoinColumn;

import javax.persistence.OneToMany;

import javax.persistence.Table;

//关联我们的表

@Entity //该类被hibernate当做实体给管理

@Table(name=“xx_plat_role”) //对应数据库的表

public class Role {

@Id //配置主键

@GeneratedValue(strategy=GenerationType.IDENTITY) //自增策略

@Column(name=“role_id”) //关联字段名和数据类型

private int id;

@Column(name=“role_name”) //关联字段名和数据类型

private String name;

@Column(name=“role_status”) //关联字段名和数据类型

private String status;

@Column(name=“createdate”, columnDefinition=“DATETIME”) //关联字段名和数据类型

private Date createdate;

@OneToMany //一对多配置,

@JoinColumn(name=“admin_role”) // 外键的名字

private Set admins = new HashSet();

}

此处一对多配置,只配置1端,多端不用管理,所以Admin不需要任何配置

测试代码:

public boolean add(Admin param, int roleId) {

Session session = this.sessionFactory.openSession();

//开启事务

Transaction t = session.beginTransaction();

//get我们的role对象,让hibernate管理起来

Role role = (Role) session.get(Role.class, roleId);

//关联role和admin的关系

role.getAdmins().add(param);

int result = (Integer) session.save(param);

//提交事务

t.commit();

//关闭回话

session.close();

return result > 0;

}

结果如下

在这里插入图片描述

根据测试结果我们发现,如果我们想要关联两张表的关系,:

1、hibernate配置了关联关系

2、当操作数据的时候,两个关联对象被hibernate管理起来,

3、两个对象之间必须建立关联关系

查询数据测试

@Override

public List list() {

Session session = this.sessionFactory.openSession();

String SQL = “select * from xx_plat_role”;

List list = session.createSQLQuery(SQL).addEntity(Role.class).list();

return list;

}

在这里插入图片描述我们发现在查询role的时候,实际上hibernate自动帮我们查询了当前role下面的所有admin信息,并且封装到了set里面,也就是数据已经包装好了。省去了我们以前的链接查询的操作。

但是通过测试我们发现,在查admin的时候没有把admin相关的role给查询出来,那是因为admin没有配置映射关系,多对一,所以admin无效果,

懒加载设置

其实有的时候我们不需要查询admin信息,所以关联数据hiberante默认使用懒加载机制,所谓的懒加载就是我们需要使用这个数据他 才去查询,你不使用,H就不查询,但是必须建立在session不关闭的情况下,

@OneToMany(fetch=FetchType.EAGER) //没有懒加载,

@OneToMany(fetch=FetchType.LAZY) //使用懒加载,

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Java)

最后

Java架构学习技术内容包含有:Spring,Dubbo,MyBatis, RPC, 源码分析,高并发、高性能、分布式,性能优化,微服务 高级架构开发等等。

还有Java核心知识点+全套架构师学习资料和视频+一线大厂面试宝典+面试简历模板可以领取+阿里美团网易腾讯小米爱奇艺快手哔哩哔哩面试题+Spring源码合集+Java架构实战电子书+2021年最新大厂面试题。
在这里插入图片描述

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**[外链图片转存中…(img-wv0t7tlJ-1713854903978)]

[外链图片转存中…(img-Dogb1szz-1713854903979)]

[外链图片转存中…(img-tOy6ibwQ-1713854903979)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Java)

[外链图片转存中…(img-W1cjEc4F-1713854903979)]

最后

Java架构学习技术内容包含有:Spring,Dubbo,MyBatis, RPC, 源码分析,高并发、高性能、分布式,性能优化,微服务 高级架构开发等等。

还有Java核心知识点+全套架构师学习资料和视频+一线大厂面试宝典+面试简历模板可以领取+阿里美团网易腾讯小米爱奇艺快手哔哩哔哩面试题+Spring源码合集+Java架构实战电子书+2021年最新大厂面试题。
[外链图片转存中…(img-LaL5Evd1-1713854903980)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 16
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值