Hibernate学习教程文档格式.docx

上传人:b****5 文档编号:15690406 上传时间:2022-11-15 格式:DOCX 页数:9 大小:190.27KB
下载 相关 举报
Hibernate学习教程文档格式.docx_第1页
第1页 / 共9页
Hibernate学习教程文档格式.docx_第2页
第2页 / 共9页
Hibernate学习教程文档格式.docx_第3页
第3页 / 共9页
Hibernate学习教程文档格式.docx_第4页
第4页 / 共9页
Hibernate学习教程文档格式.docx_第5页
第5页 / 共9页
点击查看更多>>
下载资源
资源描述

Hibernate学习教程文档格式.docx

《Hibernate学习教程文档格式.docx》由会员分享,可在线阅读,更多相关《Hibernate学习教程文档格式.docx(9页珍藏版)》请在冰豆网上搜索。

Hibernate学习教程文档格式.docx

ORM框架在前后端领域都能看到它的影子,比如Android的greenDAO、iOS的coreData、Node.js的mongoose,这里主要讲解Java中Hibernate我们比较容易忽略和重要的点。

save和get的执行流程

save和get

save:

∙根据对象找到user类(user.getClass)和对应的映射文件User.hbm.xml,并解析出表名t_user

∙使用内省机制操作user对象,获取其中的属性:

id/name

∙解析映射文件,找到属性对应的列名

∙根据主键生成策略,如果是native,此时主键就不出现在SQL语句中,如当前的SQL语句为:

insertintot_user(uname)values(?

)其中?

就对应user.getXxx()方法

get:

∙解析映射文件,找到<

id>

元素对应的列名uid,SQL就拼接成功了

∙处理结果集,把一条数据封装成User对象

o创建User对象

o根据列名找到对应的属性名,调用user.setXxx()后返回对象

get和load方法的区别

先看这段简单的测试代码:

∙get会立即发送select语句,load不会立刻发送,当使用到该对象的非OID属性时才会发送,延迟加载

∙load方法返回的对象永远不为null,即使在数据库中不存在,所以不能使用if-null的方式来判断,而get可以为null,因为load执行的时候没有发送select语句,所以他不知道数据库中有没有对应数据,所以索性返回一个不为null的对象,如果存在,则再把数据设置到对象中去,如果不存在,使用该对象时报错

∙load方法会创建出代理对象,但是代理对象必须在session关闭之前创建出来,否则会报hibernate中最常见的错误,nosession,解决办法为Hibernate.initialize(代理对象)

持久化对象的生命周期

为什么需要关注持久化对象的生命周期?

那我们来回忆使用Hibernate中是否遇到的三个问题:

∙问题一:

主键生成策略不同,save操作时发生INSERT语句的时机不同?

onative:

在执行save方法的时候发送INSERTSQL

oincrement:

在提交事务的时候,才发送INSERTSQL

∙问题二:

删除对象的时候,没有立刻发生DELETE语句,而是在提交事务的时候发送的。

∙问题三:

为什么在事务环境下,通过get方法得到的对象,只要修改了属性值,会发生UPDATE语句。

那么SQL的执行时机和什么有关系呢?

和对象的状态有关系。

那持久化对象的状态有哪一些?

怎么划分的?

划分的规则:

∙当前对象是否有OID(该对象在表中对应有一个id值)

∙对象是否被session所管理(对象是否在一级缓存中)

状态

描述

特点

临时状态/瞬时态(transient)

刚刚用new语句创建,没有被持久化,不处于session中

没有oid,不在session当中

持久化状态(persistent)

已经被持久化,加入到session的缓存中

有oid,在session当中

游离状态(detached)/脱管态

已经被持久化,但不处于session中

有oid,不在session当中

删除状态(removed)

对象有关联的ID,并且在session管理下,但是已经计划被删除

有oid,在session当中,最终的效果是被删除.

持久化对象的状态

对象状态的总结

session中的方法仅仅只是改变对象的状态,不负责发送SQL/默认情况下事务提交的时候发送SQL,那么之前是三个问题就可以迎刃而解了。

∙问题一解答:

save方法仅仅是把临时状态的对象转换为持久化状态,本身不负责发送SQL。

临时状态的对象没有OID,调用save方法之后,变成持久化状态,就必须有OID。

*native:

表示数据库主键的自增长,只有发送SQL,才能获取主键,从而获取OID

先发送SELECT语句查询id(拥有了OID),不需要发送increment来获取OID

∙问题二解答:

delete方法仅仅是改变对象的状态,本身不负责发送SQL。

因此按照默认的方式,提交事务的时候发送SQL

∙问题三解答:

通过get查询操作得到的对象处于持久化状态(有OID,存在于一级缓存中)。

此时,修改了非IOD的属性值,发现一级缓存中的数据和快照区域的数据不同(脏数据),Hibernate就会做比较(一级缓存和快照区),发现不同,就发送UPDATE语句,做数据同步。

session的flush方法,负责把一级缓存中的脏数据同步到数据库中去

二级缓存

要了解二级缓存,我们就必须知道一级缓存是什么。

介绍一级缓存之前,我们先回顾一下Session。

session

∙session对象,通过sessionFactory对象创建而来,包含了connection对象,封装了很多操作方法

∙session不是线程安全的(使用局部变量),所以,session的最大生命周期:

一个线程,在web应用当中,一个session的最大生命周期:

request

∙session中有一个缓存,称为一级缓存。

存放当前工作单元加载的对象。

在一个session的生命周期之内,连续拿相同类型,相同ID的对象,只需要发送一次SQL

原理如图:

一级缓存

虽然一级缓存可以提高性能,但是由于session的作用域有限,因此,提高的性能也是非常有限的,所以这就引出了二级缓存的概念:

∙在整个应用中,有且只需要一个sessionFactory对象即可

∙生命周期为整个应用的缓存(二级缓存是sessionFactory上的缓存,能提供整个应用中所有的session使用)

∙所有的get,load方法,总是先查一级缓存,再查二级缓存,如果都没有,在去数据库里面查询

若想了解Hibernate和Mybatis的缓存对比可以戳这里《Hibernate和Mybaitis缓存》(

事务并发问题

事务并发时,会产生两类丢失更新问题,如图:

∙第一类丢失更新:

A事务撤销时,把已经提交的B事务的更新数据覆盖了。

第一类丢失更新问题

∙第二类丢失更新:

A事务覆盖B事务已经提交的数据,造成B事务所做操作丢失。

第二类丢失更新问题

然而解决的办法有两个,一个称之为悲观锁,一个称之为乐观锁。

悲观锁(PessimisticLock):

悲观地认为每次自己去拿数据的时候别人会修改数据,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。

底层采用的就是SELECT.....FORUPDATE

悲观锁

乐观锁(OptimisticLock):

乐观地认为每次去拿数据的时候别人不会修改数据,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。

乐观锁

在Hibernate中使用乐观锁,推荐使用version方式:

全文完

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 考试认证 > IT认证

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1