Hibernate 生成策略和缓存策略
主键生成策略
一、主键分类
1. 自然主键
主键本身就是表中的一个字段,实体中一个具体的属性,对象本身唯一的特性
比如:创建一个学生表:姓名、年龄、身份证号(自然主键)
2. 代理主键
主键本身不是表中必须的一个字段
同样创建一个学生表:姓名、年龄 、身份证号、SID(代理主键)
在实际开发当中尽量要使用代理主键
- 设计以学生身份证号为主键
- 在业务上添加学生身份证号,不小心录入错误
- 主键修改是如果两个相同是允许修改的。所以一旦参于业务,就可能存在一些问题
- 主键一般只作为条件,查询,不参与修改,使用代理主键就和表当中的业务信息没有关系
开发中为什么要使用代理主键
- 一旦自然主键参与到业务逻辑当中,后期有可能修改源代码
- 一个好的程序设计要满足开闭原则(Open Closed Principle)
- 对程序的扩展是open开放的
- 对修改源码是close的
二、主键的生成策略
- 在使用代理主键的过程当中,尽量要做到自动生成主键,不能让用户手动设置主键
- 一般交给数据库自动增长,让程序生成唯一的标识
- 在hibernate当中,为了减少程序的编写,内部提供了多种的主键生成策略
1. increment
自动增加策略(long、short、int)
原理
- 首先先发送一条语句:select max(id) from 表
- 然后让id加1
在单线程中使用,不要在多线程中使用
- 两个线程同时对数据库当中的id字段查询
- 两个人查询的内容都是1
- 其中一个肯定会报错
2. identity
- 自动增长
- 原理
- 使用是数据库底层的增长策略
- 适用于有自动增长机制的数据库
- Mysql有自动增长
- Oracle是没有自动增长的:通过序列来完成这种效果的
3. sequence
- 自动增长
- 原理
- 采用序列的方式
- 必须得要支持序列
- Oracle支持序列
- Mysql不支持序列
4. uuid
- 适用于字符串类型的主键
- 使用hibernate中随机生成字符串的主键
5. native
- 本地策略
- 在 identity 和 sequence 自动切换
6. assigned
- hibernate不会帮你管理主键
- 自己手动调用或通过程序来去生成主键
持久化
一、什么是持久化
- 将内存中的一个对象持久化到(存储到)数据库的过程
- hibernate框架就是一个持久化的框架
二、什么是持久化类
- 一个Java类与数据库建立的映射关系
- 持久化类 = Java类 + 映射文件
三、持久化类编写规则
1.对持久化类提供一个无参的构造方法
- 底层会通过反射创建对象
- 如果没有无参构造,反射是无法创建对象的
2.对内部私有的字段要提供get与set方法
- 不提供的话。hibernate就无法获取对象的值
3.对象持久化类提供一个OID与数据库表当中的主键对应
- Java中通过对象的地址来区别是否为同一个对象
- 数据库中通过主键来区别是否是同一条记录
- Hibernate中通过持久化类的OID属性来区分是否是同一个对象
4.持久化类中的属性尽量使用包装类型
- 包装类型的默认值为NULL
- 基本数据类型的默认值为数字
5.持久化类不要使用final修饰
- 跟延时加载有关系
- 延时加载是Hibernate优化的手段
- 返回的是一个代理对象
- 使用动态代理 ,低层使用的是字节码增强技术,继承这个类来进行代理。
- 如果使用了final,就不能被继承,不能被继承,代理对象就无法创建,延时加载就无效了。
持久化类的划分
- Hibernate是持久层的框架,通过持久化类完成ORM操作
- 持久化类:Java类+映射文件
Hibernate为了更好的管理持久化类,将持久化类对象分为三种状态
1. 瞬时态
- 没有唯一的OID
- 没有被session管理
- 这种对象我们称为瞬时态对象
2.持久态
- 有唯一的OID
- 有被session管理
- 这种对象我们称为持久态对象
3.游离态/托管态/离线态
- 有唯一的OID
- 没有被session管理
三种状态区分
1. 瞬时态
刚new出对象时,还没有设置id,还没有被session所管理。
2. 持久态
已经有了id,调用session方法,把对象给session,才被session所管理 。
添加到session之后, 对象一直处理持久态。当对象处理持久态时, 可以自动更新数据库。
持久态对象特征
- 自动更新数据,只要成为持久态对象,不用调用update也会自动更新数据
- 如果值和数据库当中的值一样, 就不会发送update
- 原理:依赖了hibernate当中的一级缓存
3. 游离态
把session关闭掉时close时,对象处理游离态。
代码演示
三种状态之间的转换
一级缓存
一、什么是缓存
- 缓存是一种优化的方式,分为一级缓存和二级缓存。
- 将数据存入到内存当中,使用的时候直接从缓存中获取,不用直接到存储源中取数据了。
二、一级缓存
- session级别的缓存
- 生命周期与Session一致:一级缓存是由Session中的一系列Java集合构成的
- 是自带的, 不可卸载
三、二级缓存
- SessionFactory级别的缓存
- 需要自己去配置,默认是开启的,在企业当中一般都不用了,现在都 redis。
四、一级缓存特点
当应用程序用Session接口的Save(),update(),saveOrUpdate()时,如果session缓存中没有相应的对象,就会自动的从数据库查询相应的信息,写到缓存当中。
当调用Session接口的load,get()方法,以及Query接口的list iterator方法时, 会判断缓存中是否存在该对象,有则返回, 不会查询数据库,如果缓存中没有要查询的对象,再到数据库当中查询对应的对象,并添加到一级缓存中。
当调用session.close方法时,缓存会被清空。
代码:
五、一级缓存内部结构
一级缓存当中有一个区域:快照区
- 使用id进行查询数据库,将查询得到的结果放置到session一级缓存中,同时复制一份数据,放置到session的快照中
- 当使用tr.commit()的时候,同时清理session的一级缓存(flush)
- 当清理session一级缓存的时候,会使用OID判断一级缓存中对象和快照中的对象进行比对
- 如果2个对象(一级缓存的对象和快照的对象)中的属性发生变化,则执行update语句,此时更新数据库,更新成一级缓存中的数据
- 如果2个对象中的属性不发生变化,此时不执行update语句
目的:确保和数据库中的数据一致
清空一级缓存
- clear():清空所有缓存
- evict(obj):清空一个对象
事务管理
一、事务
- 逻辑上的一组操作
- 要么全都成功,要么全都失败
二、事务特性
1. 原子性
事务不能分隔
2. 隔离性
执行一个事务时, 不应受到其它事务的干扰
- 脏读:一个事务读取某一个事务未提交的数据
- 不可重复读:一个事务读取取另一个事务已经提交的update数据,导致在前一个事务多次查询的结果不一样
- 幻读:一个事务读取到别一个事务已经提交的insert数据,导致在前一个事务多次查询的结果不一样
3. 持久性
事务完成后, 数据就持久到数据库当中
4. 一致性
事务执行前后 ,数据的完整性要保持一致
三、事务的隔离级别
- Read uncommitted
- 所有问题都会发生
- Read committed
- 解决脏读问题
- Repeatable read
- 解决脏读和不可重复读
- Serializable
- 解决所有问题,效率较低
四、Hibernate设置事务的隔离级别
- 在核心配置文件hibernate.cfg.xml当中
- 通过数字来代表不同的隔离级别
<property name="hibernate.connection.isolation">4</property>
五、事务业务层连接
在业务层使用事务时,必须得要保证获取事物的连接和dao层操作的连接是同一个,否则就管理了不对应的操作
1. 使用jdbc当中事务业务层处理方法
(1)向下传递
就开始在业务层先创建好一个连接,传给dao层,让dao层使用这个连接执行操作
(2)使用ThreadLocal对象
在service方法当中把创建的连接绑定到对应的threadLocal当中,在dao方法当中,通过当前的线程获得连接对象
2. hibernate当中处理方法
- Hibernate框架,内部已经绑定好了ThreadLocal
- 在SessionFactory中,提供了一个方法,getCurrentSession() 方法,获取当前线程中的session
- 此方法默认不能用,要通过配置完成
- 在核心配置文件(hibernate.cfg.xml)当中配置
<property name="current_session_context_class">thread</property>
- 创建一个session绑定到当前线程
- 通过它来操作时, 不需要 close,执行结束后, 会自动的close()
Hibernate 生成策略和缓存策略的更多相关文章
- 三大框架 之 Hibernate生成策略与缓存策略(主键生成策略、持久化、持久化类划分、一级缓存、事物管理)
目录 Hibernate生成策略与缓存策略 主键生成策略 主键分类 主键的生成策略 持久化 什么是持久化 什么是持久化类 持久化类编写规则 持久化类的划分 三种状态区分 持久态对象特征 一级缓存 什么 ...
- iOS 使用AFNetWorking监听APP网络状态变化(可用于更改缓存策略、提示网络等)
前言 我们知道在APP开发过程中.监听手机当前的网络状态还是一个非经常常使用的方法,这里我来为大家接受一种使用AFNetWorking来监听当前的网络状态的方法:网络监听对程序开发的帮助有非常多:比方 ...
- Hibernate缓存策略(一级缓存和EHcache二级缓存)
如何配置二级缓存: 第一步:导入EHcache依赖 1)Maven项目: <!--此处使用hibernate4--> <dependency> <groupId>o ...
- Hibernate学习笔记(三)Hibernate生成表单ID主键生成策略
一. Xml方式 <id>标签必须配置在<class>标签内第一个位置.由一个字段构成主键,如果是复杂主键<composite-id>标签 被映射的类必须定义对应数 ...
- Hibernate(四)——缓存策略+lazy
Hibernate作为和数据库数据打交道的框架,自然会设计到操作数据的效率问题,而对于一些频繁操作的数据,缓存策略就是提高其性能一种重要手段,而Hibernate框架是支持缓存的,而且支持一级和二级两 ...
- Hibernate学习笔记二:Hibernate缓存策略详解
一:为什么使用Hibernate缓存: Hibernate是一个持久层框架,经常访问物理数据库. 为了降低应用程序访问物理数据库的频次,从而提高应用程序的性能. 缓存内的数据是对物理数据源的复制,应用 ...
- Hibernate第十二篇【二级缓存介绍、缓存策略、查询缓存、集合缓存】
Hibernate二级缓存介绍 前面我们已经讲解过了一级缓存,一级缓存也就是Session缓存,只在Session的范围内有效-作用时间就在Session的作用域中,范围比较小 Hibernate为我 ...
- Hibernate的二级缓存策略
Hibernate的二级缓存策略的一般过程如下: 1) 条件查询的时候,总是发出一条select * from table_name where …. (选择所有字段)这样的SQL语句查询数据库,一次 ...
- Hibernate缓存策略
Hibernate的一级缓存又称为Session缓存,其适用范围是在当前的会话之中,其生命周期和Session相同,随着Session的销毁,一级缓存也会随之销毁.一级缓存是不能取消的,Hiberna ...
随机推荐
- BASIS小问题汇总1
try to start SAP system but failed 2019-04-04 Symptom: when i tried to start SAP system, using the c ...
- java线程中如何使用spring依赖注入
实现一个线程继承了Thread或实现Runnable接口,想在run方法中使用spring依赖注入(操作数据库),此时报错为空指针,就是说没有注入进来. 实验了几种方式,分别说一下优缺点. 1:写了工 ...
- java包装类的自动装箱及缓存
首先看下面一段代码 public static void main(String[] args) { Integer a=1; Integer b=2; Integer c=3; Integer d= ...
- 四、DDL常见操作汇总
DDL: Data Define Language 数据定义语言,主要用来对数据库.表进行一些管理操作.如:建库.删库.建表.修改表.删除表.对列的增删改等. 一.库的管理 1.创建库 create ...
- 100行代码打造属于自己的代理ip池
经常使用爬虫的朋友对代理ip应该比较熟悉,代理ip就是可以模拟一个ip地址去访问某个网站.我们有时候需要爬取某个网站的大量信息时,可能由于我们爬的次数太多导致我们的ip被对方的服务器暂时屏蔽(也就是所 ...
- MySql 学习之 一条查询sql的执行过程
相信大家都接触过Mysql数据库,而且也肯定都会写sql.我不知道大家有没有这样的感受,反正我是有过这样的想法.就是当我把一条sql语句写完了,并且执行完得到想要的结果.这时我就在想为什么我写这样的一 ...
- URLErro和HTTPError
url error URLError 产生的原因主要有: 没有网络连接 服务器连接失败 找不到指定的服务器 我们可以用try except语句来捕获相应的异常 from urllib import r ...
- SecureCRT和SecureFX的安装和破解
1.SecureCRT & SecureFX 介绍 1.1 SecureCRT SecureCRT 是一款终端仿真软件,和 Putty 的功能类似. 不过相比Putty比较简单的功能,Secu ...
- brew install thrift
➜ ~ brew install thriftUpdating Homebrew...Warning: You are using macOS 10.11.We (and Apple) do not ...
- jupyter notebook在启动时kernel一直在busy , 无法print
转: https://blog.csdn.net/loovelj/article/details/82184223 一. 问题: 内核一直显示忙碌,连简单的print都不能执行了.然后看后台,最后说” ...