hibernate是免费开源的框架,是一个OR-Mapping映射工具, 将实体类和数据库表形成映射关系,是一个优秀的持久层解决方案,hibernate对jdbc进行了封装,我们不需要再关心底层实现,只需要关系具体的业务实现即可。
-
- hibernate:核心类和接口
- Configuration类: 加载hibernate.cfg.xml配置文件
- SessionFactory接口:会话工厂,可以得到会话
- Session接口: 会话,操作CRUD增删改查
- Transaction接口: 事务,开启事务,提交事务,关闭事务
2.hibernate工作原理
通过Configuration对象加载hibernate.cfg.xml配置文件,
hibernate.cfg.xml配置文件主要管理数据库连接相关信息与实体类和数据库表的映射关系,所以当加载hibernate.cfg.xml配置文件的时候把实体类和数据库表之间建立了映射关系,然后调用buildSessionFactory()方法得到数据库连接的会话工厂sessionFactory,再通过会话工厂得到session会话,通过session会话开启事务,然后执行CRUD操作,再进行事务提交,最后关闭session会话。
3.为什么要用hibernate
hibernate是一个优秀的持久层解决方案,提供了标准化模版,能够为开发人员提高开发效率。
- 查询效率:jdbc因为直接操作数据库,所以查询效率相比hibernate要高,hibernate要对实体类和数据库表字段之间做映射关系的维护,所以查询效率相对来说要低。
- 开发效率:jdbc相当于手动式,SQL代码和封装都需要手动完成,而hibernate相当于自动化,由于对jdbc进行封装,所以底层代码不需要开发人员编写,所以开发效率hibernate要高。
-
- Hibernate是全自动的ORM框架 而MyBatis是半自动的ORM框架
- MyBatis 是一个基于DAO层处理的ORM框架 SQL语句和实体映射 ,Hibernate 是一个基于DAO层处理的ORM框架 表和实体的映射
- Hibernate是一个重量级框架 适用于大中型项目,MyBatis是一个轻量级框架 适用于中小型项目 尤其是当下的互联网项目
- Hibernate封装的比较好,而MyBatis比较灵活
6.主键查询
- get查询和load查询的区别?
- get: session.get(Users.class, new Short("4"));
- load:session.load(Users.class, new Short("4"));
区别:- get查询不到数据会返回null 而load查询不到会抛出异常ObjectNotFoundException
- hibernate默认使用懒加载,在缓存中不存在查询数据时,get会直接到数据库中查找,而load不会
- load只会产生一个代理对象,只有在其后进行除get之外的其他操作才会真正的查询数据库
7.Hibernate中java对象的三种状态
Hibernate框架通过Session来管理Java对象的状态
-
- 瞬时状态 new对象/delete 通过new创建对象后,没有存储到数据库,此时java对象的状态为瞬时状态。
-
- 持久状态 get、load/save/update ,当对象与Session关联,被Session管理时,他就处于持久状态
- 游离状态 evict、clear、close ,处于持久状态的对象,脱离与其关联的Session管理后,对象就处于游离状态。
Session管理后,对象就处于游离状态。 Session提供两个方法(update() merge())将处于游离状态的对象与一个新的Session发生关联
对象与Session关联:
-
- 通过Session查询接口,或者get()|load()
- 通过调用Session的save()|SaveOrUpdate()
瞬时状态转换为持久状态
使用Session对象的save()或saveOrUpdate()方法保存对象后,该对象的状态由瞬时状态转换为持久状态使用Session对象的get()或load()方法获取对象,该对象的状态是持久状态
执行Session对象的delete()方法后,对象由原来的持久状态变为瞬时状态,因为此时该对象没有与任何的数据库数据关联
持久状态转为游离状态
执行了Session对象的evict()、clear()或close()方法,对象由原来的持久状态转为游离状态
重新获取Session对象,执行Session对象的update()或saveOrUpdate()方法,对象由游离状态转为持久状态,该对象再次与Session对象关联
游离状态转为瞬时状态
执行Session对象的delete()方法,对象由游离状态转为瞬时状态。
处于瞬时状态或游离状态的对象不再被其他对象引用时,会被Java虚拟机安装垃圾回收机制处理。
9.脏检查和刷新缓存
- 脏检查:session中的对象信息与数据库不一致
- 刷新缓存:解决session中的对象信息与数据库不一致的情况
实现:flush()、commit()
Session是Hibernate向应用程序提供的操纵数据库的主要接口,它提供了基本的保存、更新、删除和加载Java对象的方法。Session具有一个缓存,可以管理和跟踪所有持久化对象,对象和数据库中的相关记录对应。在某些时间点,Session会根据缓存中对象的变化来执行相关SQL语句,将对象包含的编号数据更新到数据库中,这一过程称为刷新缓存,换句话说就是将Session缓存同步刷新为与数据库一致。
脏检查
在Hibernate中,状态前后发生变化的对象,称为脏对象。当事务提交时,Hibernate会对Session中持久状态的对象进行检测,判断对象的数据时候发生了改变,这种判断称为脏检查。
Hibernate为什么要进行脏检查呢?
因为如果对象发生了改变,就需要将改变更新到数据库中,以确保内存中的对象与数据库中的数据保持一致。
Session是如何进行脏检查的呢?
当一个Dept对象被加入到Session缓存中时,Session会为Dept对象的值类型的属性复制一份快照。当Session刷新缓存是,会先进行脏检查,即比较Dept对象的当前属性与它的快照,来判断Dept对象的属性是否发生了变化。如果发生了变化,Session会根据脏对象的最新属性值来执行相关的SQL语句,将变化更新到数据库中。
刷新缓存机制
当Session缓存中对象的属性每次发生变化时,Session并不会立即刷新缓存和执行相关的SQL语句,而是在特定的时间点才刷新缓存。这使得Session能够把几条相关的SQL语句合并为一条或者一批SQL语句,减少了访问数据库的次数,从而提高应用程序的数据访问性能。
Session在何时刷新缓存呢?
当应用程序调用Transcation的commit()方法时,commit()方法先调用Session的刷新缓存方法flush(),然后向数据库提交事务。Hibernate之所以把刷新缓存时间点安排在事务快结束时,一方面是因为可以减少访问数据库的频率,林一方面是因为可以尽可能缩短当前事务对数据库中相关资源的锁定时间。
当应用程序显示调用Session的flush()方法时,刷新缓存。
Session的flush()方法和Transaction的commit()方法的区别?
flush()方法进行刷新缓存的操作,执行一系列的SQL语句,但不会提交事务;commit()方法会先调用flush()方法,然后提交事务。提交事务意味着对数据库所做的更新被永久保存下来。