Hibernate框架详解2
作者:互联网
目录
Hibernate的持久化编写规则
- 什么是持久化类?
持久化:就是将内存中的对象持久化到数据库中的过程。Hibernate框架就是用来持久化的orm框架
持久化类:一个java对象与数据库建立了用映射关系,那么这个类在Hibernate中成为持久化类
持久化类=java+映射文件
- 持久化类的编写规则
- 要有无参的构造函数 :Hibernate底层需要使用反射生成实例
- 属性私有,提供公共的get set方法: Hibernate中获取和设置属性的值
- 对持久化类提供一个唯一的OID与主键对应:java中,通过对象的地址来识别是否为同一个对象,数据库中通过主键是否一样来确定是否为同一个记录。在Hibernate中通过持久类的OID属性区分是否是同一个对象
- 属性尽量使用包装类: 基本类型的变量的默认值为0 ,有些时候0有些歧义。包装类的类型是null
- 不要使用final修饰:
延迟加载(get 和 load)本身是Hibernate的一个优化手段,返回的是一个代理对象(javassist),可以对没有实现接口的类产生代理—使用的是一个非常底层的字节码增强技术,继承这个类进行代理。如果使用final,get和load一致
Hibernate的主键生成策略
主键分类:自然主键,代理主键(推荐使用)
- 自然主键
主键本身就是表中的一个字段,(实体中的一个属性)
比如:创建一个人员表,每个人员都有一个身份证号(唯一不可重复的),使用身份证号作为主键,就是自然主键。
- 代理主键(推荐使用)
代理主键本身不是表中的一个字段,(不是实体中具体的某个属性)
比如:创建一个人员表,没有使用人员表中分身份证号作为主键,而是使用与这个表不相关的字段id,这种主键称为代理主键。
在实际的开发中,尽量使用代理主键。
- 一旦主键参与到业务逻辑当中,后期了能需要改源代码
- 好的程序满足的原则应该是ocp,程序对外是课扩展open,对修改源码是close的
主键的生成策略:
在实际的开发中,主键一般不让自己手动设置,一般将主键交给数据库,或者用代码编写。在Hibernate中,为了减少代码量,提供了很多的主键生成机制。
- increment :使用的是Hibernate提供的自动增长机制,适用于主键类型是short,int,long类型的主键。在单线程中使用。
(首先发送一条语句 select max(id) from 表,然后让id+1 ,作为下一条记录的主键)- 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()); //脱管态对象
}
- 状态转换图
瞬时态:
- 创建:new Customer()
- 转换:
瞬时---->持久:session.save(), session. saveOrUpdate()
瞬时---->脱管: customer.setCust_id(12l);持久态:
- 创建:调用session.get(Customer.class,1l), session.load(Customer.class,2l),方法
- 转换:
持久---->瞬时:session.delete()
持久---->瞬时:session.close(),session.clear()脱管态:
- 创建:Customer customet = new Customer(); customer.setCust_id(1l);
- 转换:
脱管---->瞬时: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语句查询。
标签:缓存,持久,框架,session,Hibernate,化类,主键,详解 来源: https://blog.csdn.net/weixin_44142032/article/details/90243655