Hibernate——数据持久化之利刃

【Hibernate——数据持久化之利刃】在项目开发中如果都是通过JDBC/SQL语句从数据库中访问/操作数据,这种方式有几点会非常痛苦:

1.SQL语句过于繁杂,和数据库的耦合度高。 因为有些SQL会涉及到多表操作,或者有些表非常庞大,以及业务逻辑复杂,这时候写在DAO中的SQL就会非常复杂,同时导致SQL与数据库耦合度高2.不同数据库之间SQL的不同,导致移植困难。 不同数据库虽然SQL语句大致相同,但是还有一些细节上的差别,比如Oracle中的分页方式和mysql中的分页是不同的,所以有代码移植困难的因素。3.二维关系表和对象之间数据结构的不匹配。 我们从数据库取出的数据时结果集(一张表),而我们开发时需要将查询到的结果集封装为对象,然而数据库中二维表的数据结构和内存中Java对象的数据结构是不匹配的(表中的数据需要经过处理才能变为java对象)。

痛苦促进了技术的革新和进步,hibernate的诞生带来了第二个春天:
Hibernate是开源的,用于封装数据访问层的组件,我们称之为数据访问层框架。Hibernate框架基于ORM原理实现.主要思想是将Java对象与关系表进行自动映射,这样可以将对象直接更新到数据库; 查询时,可以自动将数据表记录封装成Java对象.Hibernate是目前主流的ORM工具,此外还有iBATIS,JPA等.
Hibernate主要的体系结构如下:
a.实体类(Entity.java),n个与数据表对应,用于封装数据表的一行记录
b.XML映射文件(Entity.hbm.xml),n个用于描述实体类与数据表之间的对应关系,类属性与表字段之间的对应关系
c.主配置文件(Hibernate.cfg.xml),1个用于指定连接数据库的参数,框架参数等
了解了它的体系结构之后,我们就可以开始在项目中使用hibernate了,
使用步骤如下:
a.引入hibernate框架开发包b.添加Hibernate主配置文件c.根据数据表,编写实体类,映射文件d.利用Hibernate API操作实体对象

Hibernate的优点还不止于此,它提供了两级Cache(高速缓冲存储器),第一级别的缓存是Session(注意:与HTTP的Session没有任何关系)级别的缓存,它是属于事务范围的缓存。这一级别的缓存由hibernate管理的,一般情况下无需进行干预;一级缓存好处是:
当使用同一个Session对象重复查询相同数据对象时,
第一次查询数据库并放入缓存,后续几次从缓存获取.
第二级别的缓存是SessionFactory级别的缓存,它是属于进程范围或群集范围的缓存。这一级别的缓存可以进行配置和更改,并且可以动态加载和卸载。 二级缓存的好处是它的物理介质可以是内存和硬盘,因此可以存放大量的数据。解决了对象被多个不同的Session频繁访问时与数据库交互问题。
但使用hibernate的二级缓存限制也有不少限制。在不了解原理的情况下,可能缓存中的数据频繁的被清空,性能下降,可能会有1+N的问题,在批量insert,update数据时二级缓存会占用大量内存,就算不溢出也会花费长时间来GC,不了解缓存的锁可能会出现死锁、脏数据。所以提醒初学者,请慎用!!
Hibernate还为查询结果提供了一个查询缓存,它依赖于第二级缓存。
查询缓存可以缓存查询语句和结果集.当重复执行同一个查询语句时,只取数据库查询一次,后续都是将缓存中的结果集取出.适用于频繁的执行同一个查询语句,而且查询结果集很少发生变化的情况.
此外,hibernate还有延迟加载,关系映射,锁机制等等特性,
在这里说下最主要的关系映射的特点:
1、QBC语句查询支持用一个表(实体类)的某个属性作为查询另一个表(实体类)一个条件。
2、解决了复杂的表关系,他相当于数据库中的外键关系。
3、支持多个表之间的关联维护关系。只要你删除一个表的某条数据,其他表中含有这条数据的都自动清除。他甚至只要写一条新增sql语句,就能分别插入不同的数据到不同的表中(hibernate中的级联、反转)。
hibernate的延迟加载会对关系映射功能产生不良的影响,比如在页面上获取某个表中另外一个表的数据,就会延时加载的异常。不过这个可以用fetch抓取解决。当然,hibernate关系映射不只这些功能,大家在以后的开发过程中可以慢慢体会。
总结 hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的封装,使得JAVA的开发人员可以使用对象编程思维来操纵数据库。

    推荐阅读