以下内容来自于百度百科。自己觉得比较经典,因此转载过来。这篇文章主要是讲的Hibernate一些概念性的东西。我认为,Hibernate的学习可以分为概念性学习以及操作性学习。所以无论是入门还是准备Hibernate的面试都应该从这两方面入手。
Hibernate
Hibernate 是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的封装,使得Java程序员能够随心所欲地使用对象编程思维来操作数据库。Hibernate可以用在使用任何JDBC的场合,既可以在java客户端程序中使用,也可以在Servlet/JSP的Web应用中使用。最具革命意义的是,Hibenate可以在应用EJB的J2EE框架中取代CMF,完成数据库持久化任务。
核心接口
Hibernate中有6个核心接口一共有6个,分别为Session,SessionFactory,Transaction,Query,Criteria,Configuraion. 这6个对象不仅可以对持久化对象进行存取,还能够进行事务管理。
Hibernate 体系结构概要图
Session: Session负责完成被持久化对象的CRUD操作。Session对象是非线程安全的。而且此Session不同于JSP中的HttpSession, HttpSession称为用户Session。
SessionFactory:SessionFactory 负责初始化Hibernate。它充当数据存储源的代理,并负责创建Session对象。这里用到了工厂模式。需要注意的是SessionFactory并不是轻量级的。因为一般情况下,一个项目只需要一个SessionFactory就够,当需要操作多个数据库时,可以为每一个数据库指定一个SessionFactory。
Transaction:事务管理,由Session创建。
Query:查询,由Session创建。
Criteria:查询条件。
Configuration:配置。
缓存管理
Hibernate 中提供了两级Cache(高速缓冲存储器),第一级别的缓存是Session级别的缓存,它是属于事务范围的缓存。这一级别的缓存由hibernate管理的,一般情况下无需进行干预;第二级别的缓存是SessionFactory级别的缓存,它是属于进程范围或群集范围的缓存。这一级别的缓存可以进行配置和更改,并且可以动态加载和卸载。 Hibernate还为查询结果提供了一个查询缓存,它依赖于第二级缓存。
一级缓存
当
应用程序调用Session的save()、update()、saveOrUpdate()、get()或load(),以及调用查询接口的 list()、iterate()或filter()方法时,如果在Session缓存中还不存在相应的
对象,Hibernate就会把该对象加入到第一级缓存中。当清理缓存时,Hibernate会根据缓存中
对象的状态变化来同步更新
数据库。 Session为
应用程序提供了两个管理缓存的方法: evict(Object obj):从缓存中清除参数指定的持久化对象。 clear():清空缓存中所有持久化
对象。
二级缓存
3.1.
Hibernate的二级缓存策略的一般过程如下
:
1) 条件查询的时候,总是发出一条select * from table_name where …. (选择所有字段)这样的SQL语句查询
数据库,一次获得所有的
数据对象。
2) 把获得的所有
数据对象
根据ID
放入到第二级缓存中。
3) 当Hibernate
根据ID
访问
数据对象
的时候,首先从Session一级缓存中查;查不到,如果配置了
二级缓存
,那么从二级缓存中查;查不到,再查询
数据库
,把结果
按照ID
放入到缓存。
4) 删除、更新、增加数据的时候,同时更新缓存。
Hibernate的二级缓存策略,是针对于ID查询的缓存策略,对于条件查询则毫无作用。为此,Hibernate提供了针对条件查询的Query Cache。
3.2. 什么样的数据适合存放到第二级缓存中? 1 很少被修改的数据 2 不是很重要的数据,允许出现偶尔并发的数据 3 不会被并发访问的数据 4 参考数据,指的是供应用参考的常量数据,它的实例数目有限,它的实例会被许多其他类的实例引用,实例极少或者从来不会被修改。
3.3. 不适合存放到第二级缓存的数据? 1 经常被修改的数据 2 财务数据,绝对不允许出现并发 3 与其他应用共享的数据。
3.4. 常用的缓存
插件 Hibernater 的二级缓存是一个插件,下面是几种常用的缓存插件:
l EhCache:可作为进程范围的
缓存,存放数据的物理介质可以是内存或硬盘,对Hibernate的查询缓存提供了支持。
l OSCache:可作为进程范围的
缓存,存放数据的物理介质可以是内存或硬盘,提供了丰富的缓存数据过期策略,对Hibernate的查询缓存提供了支持。
l SwarmCache:可作为群集范围内的缓存,但不支持Hibernate的查询缓存。
缓 存 插 件
|
支 持 只 读
|
支持非严格读写
|
支 持 读 写
|
支 持 事 务
|
EhCache
|
是
|
是
|
是
| |
OSCache
|
是
|
是
|
是
| |
SwarmCache
|
是
|
是
| | |
JBossCache
|
是
| | |
是
|
它们的提供器列于表9-4中。
缓 存 插 件
|
提供器(Cache Providers)
|
Hashtable(只能测试时使用)
|
org.hibernate.cache.HashtableCacheProvider
|
EhCache
|
org.hibernate.cache.EhCacheProvider
|
OSCache
|
org.hibernate.cache.OSCacheProvider
|
在默认情况下,Hibernate使用EhCache进行JVM级别的缓存。用户可以通过设置Hibernate配置文件中的
hibernate.cache.provider_class
的属性,指定其他的缓存策略,该缓存策略必须实现org.hibernate.cache.CacheProvider接口。
1) 选择需要使用二级缓存的
持久化类,设置它的命名缓存的并发访问策略。这是最值得认真考虑的步骤。
延迟加载
Hibernate与延迟加载
Hibernate
对象关系映射提供延迟的与非延迟的对象初始化。非
延迟加载在读取一个
对象的时候会将与这个对象所有相关的其他对象一起读取出来。这有时会导致成百的(如果不是成千的话)select语句在读取
对象的时候执行。这个问题有时出现在使用双向关系的时候,经常会导致整个
数据库都在初始化的阶段被读出来了。当然,你可以不厌其烦地检查每一个
对象与其他对象的关系,并把那些最昂贵的删除,但是到最后,我们可能会因此失去了本想在ORM工具中获得的便利。
一个明显的解决方法是使用Hibernate提供的延迟加载机制。
这种初始化策略只在一个对象调用它的一对多或多对多关系时才将关系对象读取出来
。这个过程对开发者来说是透明的,而且只进行了很少的
数据库
操作请求,因此会得到比较明显的性能提升。
这项技术的一个缺陷是延迟加载技术要求一个Hibernate会话要在对象使用的时候一直开着
。这会成为通过使用DAO模式将
持久层
抽象出来时的一个主要问题。为了将持久化机制完全地抽象出来,所有的
数据库
逻辑,包括打开或关闭会话,都不能在
应用层
出现。最常见的是,一些实现了简单接口的DAO实现类将
数据库
逻辑完全封装起来了。一种快速但是笨拙的解决方法是放弃DAO模式,将
数据库
连接逻辑加到应用层中来。这可能对一些小的
应用程序
有效,但是在大的系统中,这是一个严重的设计缺陷,妨碍了系统的可扩展性。
在Web层进行延迟加载
幸运的是,Spring框架为Hibernate
延迟加载与DAO模式的整合提供了一种方便的解决方法。以一个Web应用为例,Spring提供了OpenSessionInViewFilter和OpenSessionInViewInterceptor。我们可以随意选择一个类来实现相同的功能。两种方法唯一的不同就在于interceptor在Spring
容器中运行并被配置在web应用的上下文中,而Filter在Spring之前运行并被配置在
web.xml中。不管用哪个,他们都在请求将当前会话与当前(
数据库)线程绑定时打开Hibernate会话。一旦已绑定到线程,这个打开了的Hibernate会话可以在DAO实现类中透明地使用。这个会话会为
延迟加载
数据库中值
对象的
视图保持打开状态。一旦这个逻辑
视图完成了,Hibernate会话会在Filter的doFilter方法或者Interceptor的postHandle方法中被关闭。
<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
</filter-class>
</filter
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
其他
hibernate工作原理:
1、通过Configuration().configure();读取并解析hibernate.cfg.xml
配置文件。
2、由hibernate.cfg.xml中的<mappingresource="com/xx/User.hbm.xml"/>读取解析映射信息。
3、通过config.buildSessionFactory();//得到sessionFactory。
4、sessionFactory.openSession();//得到session。
5、session.beginTransaction();//开启事务。
6、persistent operate;
7、session.getTransaction().commit();//提交事务
8、关闭session;
9、关闭sessionFactory;
hibernate优点:
1、封装了jdbc,简化了很多重复性代码。
3、移植性好,支持各种
数据库,如果换个数据库只要在
配置文件中变换配置就可以了,不用改变hibernate代码。
4、支持透明持久化,因为hibernate操作的是纯粹的(pojo)java类,没有实现任何接口,没有侵入性。所以说它是一个轻量级框架。
1、hibernate2对 实体
对象和集合 实现了
延迟加载
2、hibernate3对 提供了属性的
延迟加载功能
hibernate延迟加载就是当使用session.load(User.class,1)或者session.createQuery()查询
对象或者属性的时候
这个
对象或者属性并没有在内存中,只有当
程序操作数据的时候,才会存在内存中,这样就实现
延迟加载,节省了内存的开销,从而提高了服务器的性能。
Hibernate的缓存机制
一级缓存:session级的缓存也叫事务级的缓存,只缓存实体,生命周期和session一致。不能对其进行管理。
不用显示的调用。
二级缓存:sessionFactory缓存,也叫进程级的缓存,使用第3方
插件实现的,也值缓存实体,生命周期和sessionFactory一致,可以进行管理。
首先配置第3放
插件,我们用的是EHCache,在hibernate.cfg.xml文件中加入
<propertyname="hibernate.cache.user_second_level_cache">true</property>
在映射中也要显示的调用,<cacheusage="read-only"/>
二级缓存之查询缓存:对普通属性进行缓存。如果关联的表发生了修改,那么查询缓存的生命周期也结束了。
在
程序中必须手动启用查询缓存:query.setCacheable(true);
优化Hibernate
1、使用一对多的双向关联,尽量从多的一端维护。
2、不要使用一对一,尽量使用多对一。
4、表字段要少,表关联不要怕多,有二级缓存撑腰。
hibernate 类与类之间关系
关联关系
聚集关系
继承关系
Hibernate继承关系映射策略分为三种:一张表对应一整棵类继承树、一个类对应一张表、每一个具体类对应一张表。