【Hibernate那点事儿】—— Hibernate知识总结
前言:
上一篇简单的讲解了下Hibernate的基础知识。这里对Hibernate比较重要的一些知识点,进行总结和归纳。
手码不易,转载请注明!——xingoo
总结的知识点:
1 关于hibernate映射的实体类标识符访问权限
2 关于对象描述标识符OID及其生成策略
3 Session缓存——清理缓存
4 Session中的状态变更
5 Session中的常用方法
首先简单的看下整理的思维导图,还没有整理完,所以仅仅是一部分而已。
关于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的一大块重点!
关于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拷贝对象。
这次的总结,大致就是以上内容。后续还会继续总结常用的知识点。
【Hibernate那点事儿】—— Hibernate知识总结的更多相关文章
- 【Hibernate那点事儿】—— Hibernate应该了解的知识
前言: 最近由于有点时间,就像深入的学习一下Hibernate.之前只是简单的使用,并没领会它的妙处.这里就趁着分享的机会,好好整理一下. 这篇主要讲到了下面几个部分: Hibernate框架 Hib ...
- Hibernate 系列 03 - 使用Hibernate完成持久化操作
引导目录: Hibernate 系列教程 目录 康姆昂,北鼻,来此狗.动次打次,Hibernate继续走起. 目录: 使用Hibernate实现按主键查询 使用Hibernate实现数据库的增.删.改 ...
- hibernate学习一(hibernate简介与准备)
一.hibernate简介 Hibernate是一个开放源代码的对象-关系映射(Object/Relational Mapping 即 ORM)框架,它对JDBC进行了非常轻量级的对象封装,它将POJ ...
- hibernate学习笔记之四 Hibernate的增删改查
采用JUnit测试,继承TestCase import java.util.Date; import junit.framework.TestCase; import org.hibernate.Se ...
- 新手上路之Hibernate:第一个Hibernate例子
一.Hibernate概述 (一)什么是Hibernate? Hibernate核心内容是ORM(关系对象模型).可以将对象自动的生成数据库中的信息,使得开发更加的面向对象.这样作为程序员就可以使用面 ...
- [原创]java WEB学习笔记93:Hibernate学习之路---Hibernate 缓存介绍,缓存级别,使用二级缓存的情况,二级缓存的架构集合缓存,二级缓存的并发策略,实现步骤,集合缓存,查询缓存,时间戳缓存
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- 使用hibernate时出现 org.hibernate.HibernateException: Unable to get the default Bean Validation factory
hibernate 在使用junit测试报错: org.hibernate.HibernateException: Unable to get the default Bean Validation ...
- 【hibernate】<第二节>hibernate的一对多映射(基本类型)
所需工具与前文一致! 第一部分内容:基本类型的一对多(one to many) 以部门表与员工表为例: 目录结构: hibernate.cfg.xml内容 <?xml version=" ...
- 【hibernate】<第一节>hibernate简单入门
所需工具: ide:eclipse or myeclipse jdk:1.7 jar包:hibernate-distribution-3.6.0.Final 和对应mysql的驱动类(对应jar包如图 ...
- [原创]java WEB学习笔记89:Hibernate学习之路-- -Hibernate检索方式(5种),HQL介绍,实现功能,实现步骤,
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
随机推荐
- pyspider的基本操作
一.安装 pip install pyspider 1.修改 pyspider/webui/webdav.py 第209行:否则启动会报错 把: 'domaincontroller': NeedAut ...
- PIE SDK文本元素的绘制
1. 功能简介 在数据的处理中会用到文本元素的绘制,利用ITextElement文本元素接口进行绘制,目前PIE SDK支持ITextSymbol符号接口,TextSymbol对象是用于修饰文字元素对 ...
- yum安装git
此方法对于RHEL.Fedora.CentOS有效: 1.yum install git 2.yum istall git-svn git-email git-gui gitk
- Kubernetes系列:(1) 初探
1. 背景 在部门内容组织了一次K8s的培训,普及了下K8s的概念.框架.操作等,为便于后期查阅,也为了进一步深究K8s,因此开展K8s系列,周期不定- 2. 概念 (1) 含义:来自希腊语,意为&q ...
- Js内存泄漏的几种情况
想解决内存泄露问题,必须知道什么是内存泄露,什么情况下出现内存泄露,才能在遇到问题时,逐个排除.这里只讨论那些不经意间的内存泄露. 一.什么是内存泄露 内存泄露是指一块被分配的内存既不能使用,又不能回 ...
- 在 Visual Studio 中调试 XAML 设计时异常
在 Visual Studio 中进行 WPF, UWP, Silverlight 开发时,经常会遇到 XAML 设计器由于遭遇异常而无法正常显示设计器视图的情况.很多时候由于最终生成的项目在运行时并 ...
- WCF寄宿在C#控制台,并用命令行启动
公司运用wcf比较多,所以自己研究一下寄宿做个笔记,wcf寄宿在控制台有两种方式 第一种,直接在控制台程序内添加wcf服务. 第二种分别添加控制台程序和wcf服务应用程序,前者引用后者,并在app.c ...
- 关闭Windows 系统当前连接的Wifi以及判断物理\虚拟网卡,有线\无线网卡
1.关闭wifi ,调用Api [DllImport("Wlanapi.dll", SetLastError = true)] public static extern uint ...
- Java 条件语句
1.if...else 一个 if 语句包含一个布尔表达式和一条或多条语句. if(布尔表达式) { //如果布尔表达式为true将执行的语句 }else{ //如果布尔表达式为false将执行的语句 ...
- 插入排序——Java实现
一.排序思想 从数组第一个元素开始(0下标),该元素可以认为已经被排序: 取出待排序列中第一个元素,然后从“有序”序列中,从后往前扫描: 如果该元素(有序序列)大于待插入元素(待排序列),将该元素后移 ...