Hibernate框架详解2

Hibernate的持久化编写规则

  • 什么是持久化类?

持久化:就是将内存中的对象持久化到数据库中的过程。Hibernate框架就是用来持久化的orm框架
持久化类:一个java对象与数据库建立了用映射关系,那么这个类在Hibernate中成为持久化类
持久化类=java+映射文件

  • 持久化类的编写规则
  1. 要有无参的构造函数 :Hibernate底层需要使用反射生成实例
  2. 属性私有,提供公共的get set方法: Hibernate中获取和设置属性的值
  3. 对持久化类提供一个唯一的OID与主键对应:java中,通过对象的地址来识别是否为同一个对象,数据库中通过主键是否一样来确定是否为同一个记录。在Hibernate中通过持久类的OID属性区分是否是同一个对象
  4. 属性尽量使用包装类: 基本类型的变量的默认值为0 ,有些时候0有些歧义。包装类的类型是null
  5. 不要使用final修饰:
    延迟加载(get 和 load)本身是Hibernate的一个优化手段,返回的是一个代理对象(javassist),可以对没有实现接口的类产生代理—使用的是一个非常底层的字节码增强技术,继承这个类进行代理。如果使用final,get和load一致

Hibernate的主键生成策略

主键分类:自然主键,代理主键(推荐使用)

  • 自然主键

主键本身就是表中的一个字段,(实体中的一个属性)
比如:创建一个人员表,每个人员都有一个身份证号(唯一不可重复的),使用身份证号作为主键,就是自然主键。

  • 代理主键(推荐使用)

代理主键本身不是表中的一个字段,(不是实体中具体的某个属性)
比如:创建一个人员表,没有使用人员表中分身份证号作为主键,而是使用与这个表不相关的字段id,这种主键称为代理主键。

在实际的开发中,尽量使用代理主键。

  1. 一旦主键参与到业务逻辑当中,后期了能需要改源代码
  2. 好的程序满足的原则应该是ocp,程序对外是课扩展open,对修改源码是close的

主键的生成策略:

在实际的开发中,主键一般不让自己手动设置,一般将主键交给数据库,或者用代码编写。在Hibernate中,为了减少代码量,提供了很多的主键生成机制。

  1. increment :使用的是Hibernate提供的自动增长机制,适用于主键类型是short,int,long类型的主键。在单线程中使用。
    (首先发送一条语句 select max(id) from 表,然后让id+1 ,作为下一条记录的主键)
  2. identity:使用的是数据库提供的自动增长机制,适用于主键类型是short,int,long类型的主键。(Mysql)
    sequence:适用于主键类型是short,int,long类型的主键。采用的是序列的方式。(Oracle支持序列,像Mysql就不能用该机制)
    uuid:使用与字符串类型的主键。使用Hibernate中随机生成字符串的方式使用主键
    native:本地策略,可以在identity和sequence之间自动来回切换。
    assigned:Hibernate放弃主键管理,需要手动编写程序自己设置
    foreign(了解):外部的,一般一对 一关联映射下使用(表之间的主键相同 。了解 )

Hibernate持久化类的三种状态

瞬时态

瞬时态:没有唯一标识的ID,没有被session管理

持久态(可以自动更新数据库)

持久态:有唯一标识的ID,被session管理

持久化类的持久态对象,可以自动更新数据库

托管态

脱管态:有唯一标识的ID,没有被session管理

状态的转换:(了解)

 @Test
    public void demo1(){
        Session session= HibernateUtils.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        
        Customer customer = new Customer(); //瞬时态对象
        customer.setCust_name("张三");

        Serializable id = session.save(customer); //持久态对象

        transaction.commit();
        session.close();
        System.out.println("客户名称:"+customer.getCust_name()); //脱管态对象
    }

  • 状态转换图

这里是引用
瞬时态:

  1. 创建:new Customer()
  2. 转换:
    瞬时---->持久:session.save(), session. saveOrUpdate()
    瞬时---->脱管: customer.setCust_id(12l);

持久态:

  1. 创建:调用session.get(Customer.class,1l), session.load(Customer.class,2l),方法
  2. 转换:
    持久---->瞬时:session.delete()
    持久---->瞬时:session.close(),session.clear()

脱管态:

  1. 创建:Customer customet = new Customer(); customer.setCust_id(1l);
  2. 转换:
    脱管---->瞬时:customer.setCust_id(null);
    脱管---->持久:session.update(Object obj),session.clear(Object obj)

Hibernate的一级缓存

  • 什么是缓存?

是一种优化方式,将数据存在内存中去 ,使用的时候直接从内存中取,不用通过数据源。

Hibernate的一级缓存

一级缓存,Hibernate的优化手段,缓存和抓取策略。Hibernate中提供了一级缓存和二级缓存。
一级缓存:也是session级别的缓存,生命周期和session一致。(一级缓存是有java中一系列的集合组成的),是不可卸载的,就是用Hibernate的时候就自带一级缓存。
二级缓存,要自己设置配置文件才可以使用,一般不用,都用redis代替
在这里插入图片描述

这里是引用

一级缓存的特殊区域:快照区

  • 持久态对象为什么能够自动保存和更新,就是依靠一级缓存的快照区。当进行查询的时候,先看一下缓存中是否有该对象,有,直接取数据,没有,再查询数据库。
  • 当一级缓存区没有的时候,查询数据库,然后将数据保存一份到缓存中的Map集合中的key上去(缓存其实就是一系列的集合),然后复制一份保存在Map集合的value上(快照区),当修改了缓存区的值的时候,进而提交commit,就会判断缓存区和快照区的值是否一致,一致,不更新,不一致,就会更新数据库。
  • 一级缓存区就是一系列的集合,有一个特殊区域快照区,对应Map集合中的value。
    缓存区和快照区统称为一级缓存区。

在这里插入图片描述

Hibernate的事物管理

配置文件Hibernate.cfg.xml中设置事物的隔离级别

在这里插入图片描述

银行转账,保证是同一个连接(业务逻辑层包含两个单一逻辑的Dao层)

使用session.getCurrentSession()获得session对象,绑定在了该线程上,在持久层使用连接对象session的时候,只需要从当前的线程中获取就可以,也就是session.getCurrentSession()获得,但是默认不能用,必须在Hibernate.cfg.xml文件中配置。

  • 配置如下

这里是引用

在这里插入图片描述
在这里插入图片描述

HIbernate的其他的API

Query : HQL 面向对象方式的查询

在这里插入图片描述

Criteria: : 完全面向对象化

在这里插入图片描述

SQLQuery:SQL查询,

用于非常复查的条件查询语句,就是用SQL语句查询。

发布了60 篇原创文章 · 获赞 16 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44142032/article/details/90243655