Hibernate是一个开源,轻量级的ORM(对象关系映射)工具。
ORM工具简化了数据创建,数据处理和数据访问。它是将对象映射到数据库中存储的数据(表)的编程技术。

Hibernate框架有很多优点。

开源和轻量级: Hibernate框架是根据LGPL许可证和轻量级的开源工具。

快速性能: Hibernate框架的性能很快,因为缓存在Hibernate框架内部使用。

hibernate框架中有两种类型的缓存:一级缓存和二级缓存。一级缓存默认是启用的。
数据库独立查询: HQL(Hibernate查询语言)是面向对象的SQL版本。它生成数据库独立查询。 所以你不需要编写数据库特定的查询语句。

在Hibernate之前,如果项目更改了数据库,我们需要更改SQL查询,从而导致维护变得非常复杂。

自动创建表: Hibernate框架提供了自动创建数据库表的功能。 因此,无需手动在数据库中创建表。

简化复杂连接: 在hibernate框架中可轻松获取多个表中的数据。
提供查询统计和数据库状态:

Hibernate支持查询缓存,并提供有关查询和数据库状态的统计信息。

Hibernate和MyBatis

Hibernate:Hibernate是当前最流行的ORM框架之一,对JDBC提供了较为完整的封装。Hibernate的O/R Mapping实现了POJO 和数据库表之间的映射,以及SQL的自动生成和执行。

Mybatis:Mybatis同样也是非常流行的ORM框架,主要着力点在于 POJO 与 SQL 之间的映射关系。然后通过映射配置文件,将SQL所需的参数,以及返回的结果字段映射到指定 POJO 。相对Hibernate“O/R”而言,Mybatis 是一种“Sql Mapping”的ORM实现。

区别:
Hibernate的DAO层开发比MyBatis简单,Mybatis需要维护SQL和结果映射。
Hibernate对对象的维护和缓存要比MyBatis好,对增删改查的对象的维护要方便。
Hibernate数据库移植性很好,MyBatis的数据库移植性不好,不同的数据库需要写不同SQL。
Hibernate有更好的二级缓存机制,可以使用第三方缓存。MyBatis本身提供的缓存机制不佳。
MyBatis可以进行更为细致的SQL优化,可以减少查询字段。
MyBatis容易掌握,而Hibernate门槛较高。

Hibernate的get和load

get和load的最大区别是,如果在缓存中没有找到相应的对象,get将会直接访问数据库并返回一个完全初始化好的对象,而这个过程有可能会涉及到多个数据库调用;而load方法在缓存中没有发现对象的情况下,只会返回一个代理对象,只有在对象getId()之外的其它方法被调用时才会真正去访问数据库,这样就能在某些情况下大幅度提高性能。

Hibernate中的延迟加载

延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作。

在Hibernate中提供了对实体对象的延迟加载以及对集合的延迟加载,另外在Hibernate3中还提供了对属性的延迟加载。

Hibernate 的延迟加载(lazy load)本质上就是代理模式的应用,我们在过去的岁月里就经常通过代理模式来降低系统的内存开销、提升应用的运行性能。Hibernate 充分利用了代理模式的这种优势,并结合了 Javassist 或 CGLIB 来动态地生成代理对象,这更加增加了代理模式的灵活性。

Hibernate中的查询方式

SQL语句查询、Criteria、Hql

Hibernate中的缓存

一级缓存:

hibernate支持两个级别的缓存,默认只支持一级缓存;
每个Session内部自带一个一级缓存;
某个Session被关闭时,其对应的一级缓存自动清除;
一级缓存实际上保存的是sql查询的结果,这样再进行相同的sql查询就可以之间从缓存中拿到结果了;

二级缓存:

是在SessionFactory这个级别维护的缓存;
针对整个应用而不是某个特定的Session,默认不开启;
可以指定Cache工具,如Ehcache(默认)、OSCache、JBossCache
原理:条件查询的时候,选择所有字段,一次获得所有的数据对象并根据id放入二级缓存。当Hibernate根据ID访问数据对象的时候,首先从Session一级缓存中查,查不到,如果配置了二级缓存,那么从二级缓存中查,查不到,再查询数据库,把结果按照ID放入到缓存。

查询缓存:

Hibernate的二级缓存策略,是针对于ID查询的缓存策略,对于条件查询则毫无作用。为此,Hibernate提供了针对条件查询的Query缓存。

Hibernate首先根据这些信息组成一个Query Key,Query Key包括条件查询的请求一般信息:SQL, SQL需要的参数,记录范围等。

Hibernate根据这个Query Key到Query缓存中查找对应的结果列表。如果存在,那么返回这个结果列表;如果不存在,查询数据库,获取结果列表,把整个结果列表根据Query Key放入到Query缓存中。

Query Key中的SQL涉及到一些表名,如果这些表的任何数据发生修改、删除、增加等操作,这些相关的Query Key都要从缓存中清空。

Session和SessionFactory

SessionFactory就是一个用于创建Hibernate的Session对象的工厂。SessionFactory通常是在应用启动时创建好的,应用程序中的代码用它来获得Session对象。作为一个单个的数据存储,它也是 线程安全的,所以多个线程可同时使用同一个SessionFactory。Java JEE应用一般只有一个SessionFactory,服务于客户请求的各线程都通过这个工厂来获得Hibernate的Session实例,这也是为什么SessionFactory接口的实现必须是线程安全的原因。还有,SessionFactory的内部状态包含着同对象关系影射有关的所有元数据,它是 不可变的,一旦创建好后就不能对其进行修改了。

Session代表着Hibernate所做的一小部分工作,它负责维护者同数据库的链接而且 不是线程安全的,也就是说,Hibernate中的Session不能在多个线程间进行共享。虽然Session会以主动滞后的方式获得数据库连接,但是Session最好还是在用完之后立即将其关闭。

Hibernate中Java对象的状态

瞬时态(Transient):不存在持久化标识OID,尚未与Hibernate Session关联对象,被认为处于瞬时态,失去引用将被JVM回收
持久态(Persistent):存在持久化标识OID,与当前session有关联,并且相关联的session没有关闭 ,并且事务未提交
脱管态(Detached):存在持久化标识OID,但没有与当前session关联,脱管状态改变hibernate不能检测到