三大框架 之 Hibernate生成策略与缓存策略(主键生成策略、持久化、持久化类划分、一级缓存、事物管理)

目录

  • Hibernate生成策略与缓存策略

    • 主键生成策略

      • 主键分类
      • 主键的生成策略
    • 持久化
      • 什么是持久化
      • 什么是持久化类
      • 持久化类编写规则
    • 持久化类的划分
      • 三种状态区分
      • 持久态对象特征
    • 一级缓存
      • 什么是缓存
      • 一级缓存
      • 一级缓存特点
      • 一级缓存内部结构
    • 事务管理
      • 什么是事务
      • 事务特性
      • 事务的隔离级别
      • Hibernate设置事务的隔离级别
      • 事务业务层连接

Hibernate生成策略与缓存策略

主键生成策略

主键分类

  • 自然主键

    主键本身就是表中的一个字段

    实体中一个具体的属性,对象本身唯一的特性

    创建一个学生表
      姓名
      年龄
      身份证号(主键)
  • 代理主键
    主键本身不是表中必须的一个字段
      创建一个学生表
              姓名
              年龄
              身份证号
              SID
    这样的主键代理主键
    在实际开发当中尽量要使用代理主键
          设计以学生身份证号为主键
          在业务上添加学生身份证号,不小心录入错误
          主键修改是如果两个相同是允许修改的。所以一旦参于业务,就可能存在一些问题
          主键一般只作为条件,查询,不参与修改,使用代理主键就和表当中的业务信息没有关系
  • 开发中为什么要使用代理主键
    一旦自然主键参与到业务逻辑当中,后期有可能修改源代码
    一个好的程序设计要满足开闭原则(Open Closed Principle)
      对程序的扩展是open开放的
      对修改源码是close的
          oracle
          mysql
          jdbc
          只改配置文件就行

主键的生成策略

  • 在使用代理主键的过程当中,尽量要做到自动生成主键,不能让用户手动设置主键
  • 一般交给数据库自动增长,让程序生成唯一的标识
  • 在hibernate当中,为了减少程序的编写,内部提供了多种的主键生成策略
increment
    自动增加策略
        long
        short
        int
    原理
        在单线程中使用,不要在多线程中使用
            两个线程同时对数据库当中的id字段查询
            两个人查询的内容都是1
            其中一个肯定会报错
        先先发送一条语句
            select max(id) from 表
        然后让id加1
identity
    自动增长
    原理
        使用是数据库底层的增长策略
        适用于有自动增长机制的数据库
            Mysql有自动增长
            Oracle是没有自动增长的,是通过序列来完成这种效果的
sequence
    自动增长
    原理
        采用序列的方式
        必须得要支持序列
            Oracle支持序列
            Mysql不支持序列
uuid
    适用于字符串类型的主键
    使用hibernate中随机生成字符串的主键
native
    本地策略
    在identity和sequence自动切换
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为了更好的管理持久化类,将持久化类对象分为三种状态
瞬时态
    没有唯一的OID
    没有被session管理
    这种对象我们称为瞬时态对象
持久态
    有唯一的OID
    有被session管理
    这种对象我们称为持久态对象
游离态/托管态/离线态
    有唯一的OID
    没有被session管理

三种状态区分

?

瞬时态
    刚new出对象时,还没有设置id,还没有被session所管理
持久态
    已经有了id
    调用session方法,把对象给session,才被session所管理
    添加到session之后, 对象一直处理持久态
    当对象处于持久态时, 可以自动更新数据库
游离态
    把session关闭掉时close时
    对象处理游离态

? 代码演示

持久态对象特征

  • 自动更新数据,只要成为持久态对象,不用调用update也会自动更新数据
  • 如果值和数据库当中的值一样, 就不会发送update

  • 原理是依赖了hibernate当中的一级缓存

一级缓存

什么是缓存

? 是一种优化的方式
? 将数据存入到内存当中,使用的时候直接从缓存中获取
? 不用直接到存储源中取数据了

? 缓存
? 一级缓存
? 二级缓存

一级缓存

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)
? 清空一个对象

事务管理

什么是事务

  • 逻辑上的一组操作
  • 要么全都成功,要么全都失败

事务特性

原子性
    事务不能分隔
隔离性
    执行一个事务时, 不应受到其它事务的干扰
        脏读
            一个事务读取某一个事务未提交的数据
        不可重复读
            一个事务读取取另一个事务已经提交的update数据,导致在前一个事务多次查询的结果不一样
        幻读
            一个事务读取到别一个事务已经提交的insert数据,导致在前一个事务多次查询的结果不一样
持久性
    事务完成后, 数据就持久到数据库当中
一致性
    事务执行前后 ,数据的完整性要保持一致

事务的隔离级别

Read uncommitted
    所有问题都会发生
Read committed
    解决脏读问题
Repeatable read
    解决脏读和不可重复读
Serializable
    解决所有问题,效率较

Hibernate设置事务的隔离级别

? 在核心配置文件hibernate.cfg.xml当中
? 通过数字来代表不同的隔离级别
?

<property name="hibernate.connection.isolation">4</property>

事务业务层连接

为什么要在业务层使用事务

在业务层使用事务时,必须得要保证获取事物的连接和dao层操作的连接是同一个,否则就管理了不对应的操作

使用jdbc当中事务业务层处理方法

    向下传递
        就开始在业务层先创建好一个连接,传给dao层,让dao层使用这个连接执行操作
    使用ThreadLocal对象
        在service方法当中把创建的连接绑定到对应的threadLocal当中
        在dao方法当中,通过当前的线程获得连接对象

hibernate当中处理方法

Hibernate框架,内部已经绑定好了ThreadLocal
在SessionFactory中,提供了一个方法,getCurrentSession()方法
获取当前线程中的session
此方法默认不能用
通过配置完成
    在核心配置文件当中配置
    <property name="current_session_context_class">thread</property>
    创建一个session绑定到当前线程
通过它来操作时, 不需要 close,执行结束后, 会自动的close()

原文地址:https://www.cnblogs.com/mumuyinxin/p/10708263.html

时间: 2024-10-14 11:54:32

三大框架 之 Hibernate生成策略与缓存策略(主键生成策略、持久化、持久化类划分、一级缓存、事物管理)的相关文章

hibernate之主键生成策略

一.主键类型1.自然主键(主键本身就是表中的一个字段,实体中一个具体的属性)表中已经具有某字段,并且该字段具有业务含义作为主键,称之为自然主键. 例如:在person表中的身份证号,既是唯一的,又可以单独标识一个person 2.代理主键(主键不是实体中某个具体的属性,而是一个不相关的字段)表中原本不存在的字段,且不具备业务含义的字段作为主键,称之为代理主键.更合理的方式是使用代理主键. 二.主键生成策略主键生成策略,就是每条记录录入时,主键的生成规则.Hibernate中,提供了几个内置的主键

初学Hibernate主键生成策略

具有业务含义的主键叫自然主键:随机生成,不具备业务含义的字段作为主键,叫代理主键. 在表与POJO类关系映射文件XXX.hbm.xml中,可通过配置id元素下generator节点的class属性指定数据表主键生成策略<generator class="生成策略"></generator>:所谓主键生成策略就是hibernate怎样管理表的主键 主键生成策略:1~4自动增长(1.2.3······),代理主键:5主键为字符串,代理主键:6一般用于自然主键,需要在

3.1 hibernate持久化类及一级缓存

1.持久化类编写规则 Hibernate是持久化层的ORM映射框架,专注于数据的持久化工作. 持久化:所谓的持久化就是讲内存中的数据永久保存到关系型数据库中. 持久化类:其实所谓的持久化类指的是一个Java类与数据库表建立了映射关系,那么这个类称为是持久化类.其实,你可以简单的理解为就是一个Java类,该类通过一个映射文件与数据库的表建立了关系.持久化类的编写规则如下: 1.持久化类提供无参数构造:因为在hibernate的底层需要使用反射生成类的实例: 2.成员变量私有,提供共有get/set

Java三大框架之——Hibernate中的三种数据持久状态和缓存机制

Hibernate中的三种状态   瞬时状态:刚创建的对象还没有被Session持久化.缓存中不存在这个对象的数据并且数据库中没有这个对象对应的数据为瞬时状态这个时候是没有OID. 持久状态:对象经过Session持久化操作,缓存中存在这个对象的数据为持久状态并且数据库中存在这个对象对应的数据为持久状态这个时候有OID. 游离状态:当Session关闭,缓存中不存在这个对象数据而数据库中有这个对象的数据并且有OID为游离状态. 注:OID为了在系统中能够找到所需对象,我们需要为每一个对象分配一个

Hibernate框架的主键生成策略

在Hibernate中,id元素的<generator>子元素用于生成持久化类的对象的唯一标识符,也就是主键.Hibernate框架中定义了许多主键生成策略类,也叫生成器类.所有的生成器类都实现了org.hibernate.id.IdentifierGenerator接口.通过实现IdentifierGenerator接口来创建自己的生成器类.Hibernate框架提供了许多内置的生成器类: assigned increment sequence hilo native identity se

hibernate框架(三)持久化类&amp;主键生成策略

一 持久化类的一个编写规则持久化:将内存中的一个对象持久化到数据库中的过程持久化类:一个Java对象与数据库的表建立了映射关系,那么这个类在hibernate中称为持久化类可以这么理解:持久化类=Java类+映射文件 持久化类的编写规则1 对持久化类提供一个无参的构造方法2 属性需要私有,对私有属性提供get和set方法3 对持久化类提供一个唯一标识Oid与数据库中主键对应4 持久化类中属性尽量使用包装类类型5 持久化类不要使用final进行修饰 二 主键生成策略先介绍一下主键的分类:自然主键和

java框架篇---hibernate主键生成策略

Hibernate主键生成策略 1.自动增长identity 适用于MySQL.DB2.MS SQL Server,采用数据库生成的主键,用于为long.short.int类型生成唯一标识 使用SQL Server 和 MySQL 的自增字段,这个方法不能放到 Oracle 中,Oracle 不支持自增字段,要设定sequence(MySQL 和 SQL Server 中很常用) 数据库中的语法如下: MySQL:create table t_user(id int auto_increment

hibernate框架学习笔记4:主键生成策略、对象状态

创建一个实体类: package domain; public class Customer { private Long cust_id; private String cust_name; private String cust_source; private String cust_industry; private String cust_level; private String cust_linkman; private String cust_phone; private Stri

Hibernate(4)——主键生成策略、CRUD 基础API区别的总结 和 注解的使用

俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及的知识点总结如下: hibernate的主键生成策略 UUID 配置的补充:hbm2ddl.auto属性用法 注解还是配置文件 hibernate注解的基本用法 使用Session API CRUD操作对象,以及对象状态的转换 hibernate缓存的概念 get()/load()的区别到底是什么,源码分析 代理模式实现的懒加载 saveOrUpdate()/merge()的区别 Assigned(常用,一般情况使用很方便):