首页 > 其他分享 >重量级ORM框架--持久化框架Hibernate【关系映射详解】

重量级ORM框架--持久化框架Hibernate【关系映射详解】

时间:2022-09-30 11:02:03浏览次数:78  
标签:session hibernate 框架 lisi -- private 级联 Hibernate id


hibernate

​ Hibernate是一款重量级的持久层框架,目前市面上的我很少见还有项目在开发时候使用他,之所以要学习这个,因为公司最近有一个系统升级的项目,之前的老系统用到了Hibernate。​

重量级ORM框架--持久化框架Hibernate【关系映射详解】_后端

同样还是老套路,学习一个新技术或者新知识,首先去他的官网看

【官网】:​​https://hibernate.org/orm/​​​ 【官方教程】:h​​ttps://hibernate.org/orm/documentation/getting-started/​​ 【github地址】:​​https://github.com/hibernate​


目前hibernate已经更新到了6的版本,这里使用的5的版本

重量级ORM框架--持久化框架Hibernate【关系映射详解】_外键_02

注意: Hibernate5.1;5.2官方推荐使用JDK1.8以及JDBC4

文章目录


一、generator主键策略

重量级ORM框架--持久化框架Hibernate【关系映射详解】_后端_03


generator配置:代表hibernate主键生成策略

【我们可以将其分为三大类】:

  1. 由数据库维护
  • identity:Mysql的​​auto_increment​​维护主键自增策略
  • sequence:Oracle使用​​sequence​​序列维护主键自增策略
  • native:本地策略,由hibernate自己根据数据库选择最优策略
  1. 由hibernate维护
  • uuid:生成32位16进制的无效​​字符串​​【记住是一个字串】
  • increment:生成递增的数值类型(每次先查当前的最大的id值+1)
  1. 由开发者维护
  • asigned:必须要有程序员给定id的值,否则报错

二、对象关系映射:一对多映射

需求案例:客户 与 订单的需求关系:典型的一对多的关系

2.1 测试准备

这里我们需要在创建一张表t_order

CREATE TABLE `t_order` (
`id` INT(10) NOT NULL AUTO_INCREMENT,
`order_no` VARCHAR(20) NULL DEFAULT NULL COMMENT '订单编号' COLLATE 'utf8mb4_general_ci',
`product_name` VARCHAR(20) NULL DEFAULT NULL COMMENT '产品名称' COLLATE 'utf8mb4_general_ci',
`cust_id` INT(10) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `t_order_id_uindex` (`id`) USING BTREE,
INDEX `t_order_t_customer_c_id_fk` (`cust_id`) USING BTREE,
CONSTRAINT `t_order_t_customer_c_id_fk` FOREIGN KEY (`cust_id`) REFERENCES `hibernate_db`.`t_customer` (`c_id`) ON UPDATE NO ACTION ON DELETE NO ACTION
)
COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=2;

2.2 创建实体

注意事项:

  1. 需要在Custom实体中先给一个​​List<Order>​​来关联多方的实体信息
  2. order实体表也需要给一个Custom的JavaBean对其进行关联

重量级ORM框架--持久化框架Hibernate【关系映射详解】_后端_04

【Order】

public class Order implements Serializable {
private static final long serialVersionUID = 1L;

private String id; // 订单表主键
private String orderNo; // 订单编号
private String prodName; // 产品名称

private Integer custId; // 外键客户id

/*一个订单对一个客户,一个客户对多个订单*/
private Customer customer;
}

2.3 hbm.xml文件修改

【customer.hbm.xml】
在Custom.hbm.xml文件里,我们需要做的是将order进行关联用set标签

<class name="com.wei.domain.Customer" table="t_customer">
<id name="id" column="c_id">
<generator class="identity"></generator>
</id>
<property name="name" column="c_name"></property>
<property name="age" column="c_age"></property>
<property name="gender" column="c_gender"></property>
<property name="level" column="c_level"></property>

<!--一对多配置-->
<!--name设置本实体类(customer)关联的属性字段名-->
<set name="orders" >
<!--外键的字段名称-->
<key column="cust_id"></key>
<!--关联的实体对象的完整类路径-->
<one-to-many class="com.wei.domain.Order"/>
</set>
</class>

一表中的关联配置使用的标签是:​​<one-to-many class="所关联的类的全类名"></on-to-mony>​

【order.hbm.xml】

<class name="com.wei.domain.Order" table="t_order">
<id name="id" column="id">
<generator class="native"/>
</id>
<property name="orderNo" column="order_no"/>
<property name="prodName" column="product_name"/>

<!--多对一配置-->
<many-to-one name="customer" column="cust_id" class="com.wei.domain.Customer"></many-to-one>
</class>

多表中所关联的字段是用的标签是​​<many-to-one name="关联的本实体类在的字段名" column="外键字段" class=“所引用的实体类的全类名”></many-to-one>​

2.4 编写测试类

@Test
public void test1() throws HibernateException {
// 准备数据
/*
* 需求:一个客户两个订单
* */
Customer lisi = new Customer();
lisi.setName("里斯");
lisi.setGender("1");
lisi.setAge(32);
lisi.setLevel("至尊VIP,年卡8级");

Set<Order> orders = new HashSet<>();
// 订单1
Order order1 = new Order();
order1.setOrderNo("20220807111");
order1.setProdName("小米Ultr11");
order1.setCustomer(lisi);
// 订单2
Order order2 = new Order();
order2.setOrderNo("20220807134");
order2.setProdName("华为MateBook_Pro 512G+8G");
order2.setCustomer(lisi);
// 客户添加订单
orders.add(order1);
orders.add(order2);
lisi.setOrders(orders);

Session session = HibernateUtil.getConnection();
//4、开启事务
Transaction tx = session.beginTransaction();
//5、执行添加操作
session.save(lisi);
session.save(order1);
session.save(order2);
//6、提交事务
tx.commit();
//7、关闭资源
HibernateUtil.closeSession(session);
}

【订单表】

重量级ORM框架--持久化框架Hibernate【关系映射详解】_java_05


【客户表】

重量级ORM框架--持久化框架Hibernate【关系映射详解】_hibernate_06

为了可以证实是否插入成功,我么可以再写一个方法来查询某一个客户的订单

/**
* 查询用户guan连查询其所的订单
*
* @throws HibernateException
*/
@Test
public void test2() throws HibernateException {

Session session = HibernateUtil.getConnection();
//4、开启事务
Transaction tx = session.beginTransaction();
//5、执行添加操作
Customer customer = session.get(Customer.class, 5);
System.out.println("用户名称:"+customer.getName());
Set<Order> orders = customer.getOrders();
for (Order order : orders) {
System.out.println("订单:"+order.getOrderNo());
}
//6、提交事务
tx.commit();
//7、关闭资源
HibernateUtil.closeSession(session);
}

重量级ORM框架--持久化框架Hibernate【关系映射详解】_hibernate_07

三、casecode和inverse配置

3.1 CaseCade级联操作

级联操作,就是操作一个对象的时候,相同时操作他的关联对象。

  • 级联保存
<set name="orders" cascade="save-update">
<!--外键的字段名称-->
<key column="cust_id"></key>
<one-to-many class="com.wei.domain.Order"/>
</set>

【测试】

@Test
public void test3() throws HibernateException {
// 准备数据
Customer lisi = new Customer();
lisi.setName("马云云");
lisi.setGender("1");
lisi.setAge(34);
lisi.setLevel("至尊VIP,年卡n级");

Set<Order> orders = new HashSet<>();
// 订单1
Order order1 = new Order();
order1.setOrderNo("20220808123");
order1.setProdName("阿里巴巴");
order1.setCustomer(lisi);
// 订单2
Order order2 = new Order();
order2.setOrderNo("20220808141");
order2.setProdName("华强北 只能IPHONE watch");
order2.setCustomer(lisi);
// 客户添加订单
orders.add(order1);
orders.add(order2);
lisi.setOrders(orders);

Session session = HibernateUtil.getConnection();
//4、开启事务
Transaction tx = session.beginTransaction();
//5、执行添加操作
session.save(lisi); // 保存客户
// 级联保存订单数据,所以配置在客户的映射文件中
//6、提交事务
tx.commit();
//7、关闭资源
HibernateUtil.closeSession(session);
}

重量级ORM框架--持久化框架Hibernate【关系映射详解】_多对多_08

  • 级联删除
<set name="orders" cascade="save-update,delete" >
<!--外键的字段名称-->
<key column="cust_id"></key>
<one-to-many class="com.wei.domain.Order"/>
</set>

【测试】

@Test
public void test4() throws HibernateException {

Session session = HibernateUtil.getConnection();
//4、开启事务
Transaction tx = session.beginTransaction();
//5、执行添加操作
Customer cus = session.get(Customer.class, 6);// 级联删除
//6、提交事务
session.delete(cus);
tx.commit();
//7、关闭资源
HibernateUtil.closeSession(session);
}

重量级ORM框架--持久化框架Hibernate【关系映射详解】_java_09

如果没有级联删除,则会把外键的值置为空。​​级联删除则会在删除一个对象的同时将其关联的的对象也删除。​


【实现级联操作的注意事项】:

标签:session,hibernate,框架,lisi,--,private,级联,Hibernate,id
From: https://blog.51cto.com/u_14957231/5725634

相关文章

  • sync.map 原理分析
    普通的map普通的map并不是并发安全的,但是在go的1.6之前不会报错,但是会出现问题,1.6之后会直接报错.例如以下代码:packagemainimport( "fmt" "time")fun......
  • MyBaris-ResultMap定制化查询结果
    MyBatis的ResultMap通常来说,数据库的命名规范一般是​​xxx_xxx​​​这样子,而Java的属性命名方式一般是采用的​​小驼峰命名​​​,即eName,empNo…这样的。而MyBatis的自动......
  • 关于multi-statement not allow问题解决
    出现这个问题是因为druid有一个防火墙,默认是不允许批量操作的,目的应该是防止sql注入等风险。如果你在url中设置了allowMultiQueries=true允许批量操作。那么你的配置应该......
  • 高流量下的后起之秀-【RocketMQ消息中间件】
    前言​​大家都知道阿里巴巴每年的天猫双十一,那一晚的流量是十分巨大的,那么我们有没有想过,阿里是如何承载住着么巨大流量冲击,还能够稳定的运行的么?​​​​仰仗着阿里开发......
  • 重量级ORM框架--持久化框架Hibernate【JPA注解开发】
    hibernate​​Hibernate是一款重量级的持久层框架,目前市面上的我很少见还有项目在开发时候使用他,之所以要学习这个,因为公司最近有一个系统升级的项目,之前的老系统用到了Hib......
  • go 语言的 slice 注意点
    前言起因是在编写某个模块时,考虑到slice良好的伸缩性,便使用slice来存储大量的数据,业务是slice的数据会慢慢的弹出减少,理想状态下内存占用会越来越少,结果发现,......
  • Vue面试题27:为什么要使用路由懒加载?(总结自B站up主‘前端杨村长’视频,仅供自用学习)
    这是一道应用题。当打包应用时,JavaScript包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问时才加载对应组件,这样就会更加......
  • 使用福禄克CFP光纤测试仪进行Tier 1和Tier 2光纤测试
    与可通过光损耗测试仪(OLTs)实现的衰减(插入损耗)、长度和极性所需的第1层测试不同,该领域的技术人员很少会面临第2层测试和光时域反射计(OTDR)的需要。但偶尔会有一位客户或顾问指......
  • 计算机保研经验分享
    1.关于保研随着928的结束,2023届轰轰烈烈的保研也就这么结束了。从五六月份开始准备各种材料,包括打印、签名、写推荐信、成绩证明、证书等等,然后是报无数个学校,填无数个报......
  • 福禄克DSX2-5000ch网线认证测试仪为您规避布线错误
    虽然安装、测试和认证网络布线设备的聪明人知道满足标准性能参数和确保应用程序支持的重要性,但即使是我们中最优秀的人也可能犯错误,对底线和客户满意度产生不利影响。让我们......