Hibernate知识总结

news2024/12/23 17:27:41

 关于Hibernate映射

  关于Hibernate的映射要说明的一点就是关于ID的访问权限,property以及field的区别。以前使用的时候根本没有注意过这个问题,这里简单的强调一下。

  表的主键在内存中对应一个OID对象描述标识符,需要在xml的配置文件中要指定对象标识符的生成方式。

assinged是自然主键的方式,这种策略需要用户指定ID才可以,在这个知识点里先忽略。

  其他的方式比如sequence通过序列生成主键。identity,increment等是自动增长。这种方式生成的主键一般是由hibernate完成的,所以我们在编写实体对象的时候,id的get和set方法权限应该注意:

class XXX{
  private long id;
  public long getId();
  private void setId();    
}

复制

这里应该设置get的访问权限是public的,set的访问权限是private的。由于hibernate在访问实体模型时,是不考虑权限的,因此这样就避免了用户指定主键

  另外一个知识点就是,如果不通过property指定一个列,而使用field。那么hibernate就会直接访问属性,而不会通过get set访问属性。

  关于对象映射标识符OID

  这一块相对来说也是hibernate的重点,什么是OID?如何指定OID?OID与主键是什么关系?

  什么是OID?

  OID 全拼是object identifier,也就是对象标识符。因为数据库表中一般都通过主键来识别一个表中的不同行,而JVM中一般使用地址来识别不同的对象。在Session缓存中,当然也需要一个标识符来表示不同的缓存对象。因此,OID也就排上了用场。

  由于涉及到缓存的概念,就先说一下缓存!

  上节说过,SessionFactory是重量级的缓存,里面包含了数据库的连接,预定义的SQL等等。而Session的缓存是轻量级的,里面包含一些增删改查的对象。

  如果同一个JVM中的对象,加入到不同的session中,也是不同的缓存对象。而不同的对象加入到同一个Session中,也需要保证OID不同。因为Session不管你存的是什么,都需要通过对象标识符来检索对象。

  如何指定OID?

  通常分为两种:

  1 自然主键,也就是带有业务含义的,比如学生的学号,工作的编号,通常包含了年份,部门或者班级,专业等等业务上的意义,因此需要手动的合成或者拼接指定。这种情况下就需要使用assinged方式,这种方式如果不指定主键就提交缓存进行更新,会报错!

  2 代理主键,也就是没有业务含义的,通常是通过编码自动生成的。

increment:不依赖于底层数据库,适合单个数据库场合不适合集群,必须为long int short类型。插入式,先选择最大的id值,再加1

identity:依赖底层数据库系统。支持自动增长字段: OID 为long,int,short

sequence:MYSQL不支持序列。依赖底层,必须支持序列。Oracle db2 sap db  postgresql

hilo:计算公式hi*(max_lo+1)+lo 不依赖底层数据库系统,Long,int,short,只能在一个数据库中保持唯一

native:跨平台,自动选择使用哪个策略。

  由于上面的identity,sequence都需要依赖于底层数据库,不同的数据库可能不支持这种方式。那么一般推荐使用native,自动进行选择。

  OID与主键是什么关系?

  一般来说,OID就是一个对象持久化之前是null,持久化的时候hibernate或者我们手动指定一个id,这个ID被插入到数据库当做主键,在session中当做索引。也因为这个原因,需要保证OID与主键的一致性,比如类型啊,长度之类的。

  关于Session缓存——清理缓存

  缓存的概念,一般学过基础理论的都应该理解,就是为了缓冲数据,减少与真实数据库的频繁交互。与计算机的缓存类似,经常访问硬盘效率太低,IO太慢,就把内存当做缓存,CPU每次与内存直接交互,内存中找不到的数据再去读硬盘。内存又觉得慢了,就弄个Cahce当做缓存,经常访问的数据再放到这里,更加快了速度。

  Session缓存也是如此,与Web中的Session也类似。在网页中,也有Session这样一种概念,比如我们登陆淘宝,会记录我们的用户信息,当浏览器关闭或者退出时,Session关闭。这期间就完全通过Session来识别用户的身份,无需每次登陆进行校验。Hibernate中也是如此,我们从SessionFactory中开启这个Session,持久化一个对象,然后提交事务,增删改查,最后关闭Session,就像一个对话一样。

  那么Session缓存具体有什么作用呢?

  比如我们通过Session.get(xxx.class,new Long(1));来获取Session中OID为1的对象,它会首先到缓存中查找,如果找到了就直接用。如果找不到就去读取数据库,然后存储到缓存中!第二次,就可以直接从缓存中获取数据了!

  这样就减少了访问数据库的频率

  另外,我们频繁的修改一个对象,如果这个对象放在缓存中,而且还是用了事务,那么只有事务在commit的时候,才会执行真正的SQL语句!

  这样就对对象与数据库的表进行了动态的映射

 Session缓存又是什么时候提交清理的呢?

  1 当使用事务时,transaction.commit()会触发缓存的清理。

  2 直接调用Session.flush()也会触发缓存的清理。

  3 如果使用的是native,那么在持久化的时候也会清理缓存,也就是session.save()时。

  4 执行查询时。

  这里就不得不提一下commit与Session的flush的区别了:

  当使用flush时,并没有提交事务,只是清理缓存而已。

  而commit的时候,是先调用flush再提交事务。

  Session缓存中的状态变更

  这又是Hibernate的一大块重点!

  临时对象:OID为null、不再Session中、数据库中无记录、

  持久化对象:OID不为Null、在Session中,有相关记录,清理时根据属性变化更新数据库。Session的save load get update saveOrUpdate lock,Query的list()。

  删除对象:OID不为null、从Session中删除、有相关记录、已经计划从数据库中删除、清理缓存就会执行删除、不能再使用。rollback  Session的delete   级联删除时

  游离对象:OID 不为null,不再Session缓存中,Session close清空缓存、evict清除一个持久化对象、clear清除缓存中的所有持久化对象

  关于Session中的方法使用

  save()

  Session调用save时,一般都是创建或者获取到了一个瞬时态的对象,这时对象的OID有可能是空的,session需要指定生成一个OID。再计划生成一条insert语句,这条语句只是简单的缓存起来,当事务提交时才执行。而持久化的对象,OID是不能随便更改的,这也是为什么前面的setId推荐设置成private的访问权限。

  load()和get()

  他们都是加载一个对象,或者从缓存中查找。区别在于,如果使用load,如果数据库中不存在该对象对应的数据,会抛出异常。而get会得到null。

  update()

  这个方法是把一个游离态的对象持久化,比如一个对象如果session清理了,那么session中就找不到这个对象了,但是数据库中仍然存在。我们通过这个对象的引用,可以通过update在Session中创建它的实例。这样,会生成一条update语句。如果此后在修改无论多少次,都只会生成一条update语句。总结起来就是,update方法,会生成一条对应的update语句来同步缓存与数据库中的对象。

  如果数据库中对应的表设置了触发器,那么就蛋疼了、!因为无论你是否修改了数据,都会生成一条update语句,这样就会导致触发了大量无效的触发器。不要担心,可以通过设置select-before-update属性,一看名字就能猜到,是在update前,进行一次select,如果数据一致,就必须要update了,如果数据不一致,才update。

  saveOrUpdate()

  这个方法就给力了,它会自动判断传入的参数是什么类型的,然后采取什么措施!完全的自动化,最喜欢这样的了!跟native一个套路。

  merge()

  对象的复制,它首先获取到OID,然后去session中查找是否存在这样的对象,如果存在直接修改或者使用;如果不存在,就复制这个对象的属性。

  delete()

  如果删除的对象时一个游离态的对象,那么需要先进行持久化,在删除。

  replicate()

  这个方法可以跨Sessionfactory拷贝对象。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/677985.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构——队列的实现

队列,又称为伫列(queue),计算机科学中的一种抽象资料类型,是先进先出(FIFO, First-In-First-Out)的线性表。在具体应用中通常用链表或者数组来实现。队列只允许在后端(称为rear&…

Hadoop 集群如何升级?

前言 本文隶属于专栏《大数据技术体系》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和参考文献请见大数据技术体系 正文 升级 Hadoop 集群需要细致的规划,特…

Web安全——JavaScript基础

JavaScript基础 一、概述二、嵌入方法1、内嵌式2、外链式3、行内式 三、语句四、注释五、变量六、JavaScript 保留关键字七、JavaScript 作用域1、JavaScript 局部变量2、JavaScript 全局变量 八、数据类型1、判断类型2、数字类型(Number)3、字符串型&am…

windows第三大结构体--KPCR

前面我们介绍了windows的两大结构体,一个是进程结构体,一个是线程结构体。那么第三个就是KPCR。KPCR是什么呢,是用于描述CPU的结构体。每一个CPU都有一个这样的结构体来描述CPU干了什么事。 1.在当线程切换的时候,也就是线程从3环…

Windows和Linux动态注入

摘要:最近对动态注入有一些兴趣因此搜索了些资料,简单整理了下相关的技术实现。本文只能够带你理解何如注入以及大概如何实现,对注入的方法描述的并不详细。   关键字:dll注入,hook,提权   读者须知&am…

hadoop -- Yarn资源管理

Yarn YARN被设计用以解决以往架构的需求和缺陷的资源管理和调度软件。 Apache Hadoop YARN (Yet Another Resource Negotiator,另一种资源协调者)是一种新的 Hadoop 资源管理器,它是一个通用资源管理系统和调度平台,可…

基于uprobe的调试调优浅析

uprobe与krobe对应,动态附加到用户态调用函数的切入点称为uprobe,相比如kprobe 内核函数的稳定性,uprobe 的函数由开发者定义。uprobe是用户态的探针,它和kprobe是相对应的,kprobe是内核态的探针。uprobe需要制定用户态…

深度学习模型压缩方法综述

深度学习因其计算复杂度或参数冗余,在一些场景和设备上限制了相应的模型部署,需要借助模型压缩、系统优化加速等方法突破瓶颈,本文主要介绍模型压缩的各种方法,希望对大家有帮助。 1,模型压缩技术概述 我们知道,一定程度上,网络越深,参数越多,模型也会越复杂,但其最终…

基于Smb协议实现网络文件传输

文章目录 什么是SMB协议SMB与CIFS区别为什么要使用SMB如何对接SMB服务如何用Java实现Smb文件传输SmbV1的实现基于SmbV1的文件上传基于SmbV1的文件下载基于SmbV1的文件重命名基于SmbV1的文件删除基于SmbV1的文件查询 SmbV2的实现基于SmbV2的文件上传基于SmbV2的文件下载基于SmbV…

面向开发人员的 ChatGPT 提示词教程中文版 - ChatGPT 版

面向开发人员的 ChatGPT 提示词教程中文版 - ChatGPT 版 1. 指南1-1. 提示的指南1-2. 配置1-3. 提示语原则原则 1: 写出清晰而具体的指示技巧 1: 使用分隔符来清楚地表明输入的不同部分技巧 2: 要求提供结构化的输出技巧 3: 要求模型检查条件是否得到满足技巧 4: "少许样本…

QML Canvas 元素(绘制文本)

关于 QML Canvas,我们已经学习了如何绘制基本图形、应用样式和颜色、绘制图像等,现在来看一下如何在 Canvas 中绘制文本。 Canvas 提供了两种方式来渲染文本: fillText(text, x, y) 在指定的 (x,y) 位置填充指定的文本 strokeText(text, x, y) 在指定的 (x,y) 位置绘制文本…

基于t分布变异自适应的改进的黏菌算法(TSMA)

目录 一、基于t分布的自适应黏菌优化算法TSAM 1.1 自适应t分布变异 1.2 建立基于t分布的自适应黏菌优化算法TSAM 二、TSMA伪码表示如下: 三、改进对比 黏菌优化算法灵感来自于黏菌的扩张和觅食行为。主要模拟了黏菌在觅食过程中的行为和形态变化,没…

【网络2】MII MDIO

文章目录 1.MII:ISO网络模型中物理层(phy)和数据链路层(mac)属于硬件,其余都属于软件kernel2.MDC/MDIO:不仅管phy,只要支持mdio协议都可以管2.1 3.RGMII时序调整:下面波形…

BUUCTF——九连环1

听这个名字就不正常,不会加密九次吧 打开也是一张图片 依旧是存在隐藏文件信息 分离出来后有两个文件,和两个压缩包,但是都需要密码 哦看错了,原来binwalk直接把里面的给分离出来了 所以现在就asd一个文件夹 爆破不出来&#xff0…

为什么调试很重要?gdb调试分析问题

为什么调试很重要? 一、引言二、调试的定义和分类2.1、调试的定义2.2.、调试的分类 三、调试的重要性四、调试的步骤和技巧4.1、定位问题4.2、重现问题4.3、分析问题4.4、解决问题4.5、调试技巧 五、简单的GDB调试示例:六、总结 一、引言 💡 …

【基于Django框架的在线教育平台开发-02】用户注册功能开发

用户注册功能开发 文章目录 用户注册功能开发1 模型层开发2 视图层开发3 配置urls.py4 表单验证5 模板层开发6 效果展示 1 模型层开发 用户数据表如下所示: FieldTypeExtraidintPrime Key & Auto Incrementpasswordvarchar(128)last_logindatetime(6)Allow Nu…

缓存雪崩和缓存穿透的解决方案

缓存雪崩 缓存雪崩是指存储在缓存里面的大量数据,在同一时刻全部过期,大部分流量直接到达了数据库,导致数据库压力增加,造成数据库崩溃的情况。 缓存雪崩的解决方案如下: 每个缓存的key设置不同的过期时间采用多级缓…

STM32单片机(九)USART串口----第四节:USART串口实战练习(串口发送+接收)

❤️ 专栏简介:本专栏记录了从零学习单片机的过程,其中包括51单片机和STM32单片机两部分;建议先学习51单片机,其是STM32等高级单片机的基础;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 :适用于想要…

在 K8S 中部署一个应用 下

接着上一篇继续部署应用到 K8S中 之前简单部署的简单集群,三个工作节点是运行在 docker 和 kubelet 的,还有一个是控制节点 ReplicationController , pod 和 service 本次关系 之前有提到 ReplicationController , pod 和 服务…

设计模式之命令模式笔记

设计模式之命令模式笔记 说明Command(命令)目录命令模式示例类图订单类厨师类抽象命令类订单命令类服务员类测试类 说明 记录下学习设计模式-命令模式的写法。JDK使用版本为1.8版本。 Command(命令) 意图:将一个请求封装为一个对象,从而使得可以用不同的请求对客…