Hibernate框架
简介
Hibernate是一个典型的ORM框架。可以实现对象和记录之间的转化,从而完成数据库的访问操作,为应用程序构建一个持久层。
Hibernate框架主要结构
1. hibernate.cfg.xml
主配置文件,用于定义数据库连接参数和框架参数。
2. 实体类
用于实现和数据库表记录的映射,参考表结构编写
3. 映射描述信息
- 可以用XML描述,需要编写hbm.xml文件
- 利用注解描述,直接写在实体类中
4. Hibernate 操作API
- Configuration 对象,用于加载hibernate.cfg.xml配置文件
- SessionFactory对象,用于创建Session对象
- Session对象,提供增删改查方法
注解描述
- @Entity 表实体类
- @Table 与指定数据库表关联
- @Id 主键
- @Column 关联字段
- < mapping class=”cn.xdl.entity.Dept” /> //添加映射实体类地址
对象操作
- session.get查询,等价于findById
- session.save添加
- session.update更新
- session.delete删除
5. 查询操作
HQL语句使用类名和属性名,区分大小写
- HQL语句语法结构和SQL一样
- HQL语句不能使用select *,省略即可
- HQL语句不能使用数据库字符传、日期、数值、SYSDATE等数据库特有函数
- HQL语句不能使用join…on…中的on子句
HQL: from Dept where name like ?
Query query = session.createQuery(hql);
//等价于from Dept
Criteria c = session.createCriteria(Dept.class);
SQL: select * from dept where dname like ? SQLQuery query =
session.createSQLQuery(sql);
延迟加载
1. 简介
在使用一些查询方法时,方法执行了,但是并没有立刻发送SQL语句查询数据库。而是在访问对象的getXxx时才触发SQL执行加载对象数据。
session.load()/query.iterator()/关联映射
2. 使用延迟加载方法时容易产生下面错误(重要)
org.hibernate.LazyInitializationException: could not initialize proxy
- no Session 原因:使用了延迟加载方法,但是session关闭早了。请求–>Action–>Service–>Dao(load)–>Result–>JSP(EL)–>关闭session
在Dao组件中不要关闭session对象,可以使用拦截器、Filter将session关闭插入到JSP解析之后。在Spring中提供了OpenSessionInViewFilter组件,只要在web.xml配置一下即可。
3. 延迟加载原理
动态代理技术。Spring AOP采用技术CGLIB和java Proxy API.
Hibernate采用的是javassist工具
4. 为什么用延迟加载
- 延迟加载主要为后续关联映射提供,避免查找无用的关联数据。
- 可以降低数据库操作的并发率,提升内存资源使用率
缓存
1. 一级缓存(默认开启)
每个Session对象创建出来,就会分配一块缓存空间,可以存储session对象访问的对象信息。session关闭后会自动清除缓存,手动清除可以session.clear(),session.evict(obj)。Session一级缓存是独享。
load/get/save/update/saveorupdate方法处理的对象都会放入缓存中
优点:可以减少查询数据库的次数,加快查询速度。 缺点:在批量操作中容易导致内存溢出问题。
public void batch(){
// ... 开启事务
for(int i=1;i<100000;i++){
session.save(dept);
if(i%100==0){
//提交一次,把缓存清空下
session.flush();
session.clear();
}
}
// ... 提交事务
}
2. 二级缓存(关闭)
SessionFactory对象缓存,可以被创建出的多个Session对象共享。
二级缓存开启过程:
- 导入ehcache工具包和ehcache.xml配置文件
在hibernate.cfg.xml中配置参数开启二级缓存,启用ehcache
name=”hibernate.cache.use_sencond_level_cache”>true
org.hibernate.cache.ehcache.EhCacheRegionFactory- 在要缓存的对象类型中,指定@Cache注解标记
@Entity
@Table(name="DEPT") @Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
public class Dept implements Serializable{
//... ... }
通过上面步骤,Dept对象可以采用二级缓存存储。 注意 :session对象要源于同一个sessionfactory.
3. 查询缓存(关闭)
一级和二级缓存,只能缓存单个对象,如果需要缓存一个结果集,必须使用查询缓存。
查询缓存开启过程:
- 针对于对象要开启二级缓存
- 在hibernate.cfg.xml中开启查询缓存
<property name="hibernate.cache.use_query_cache">trueproperty>
- 在查询执行前,调用query.setCacheable(true);
持久化
- Hibernate框架可以构建一个持久层。持久层是由持久对象构成。
- 持久对象:指的是具有持久性的数据对象。
- 持久性是指当对象数据状态发生改变后,可以与数据库同步。
- 持久对象都存储在一级/二级缓存中
Hibernate有什么缺点
1.HQL最终还是要转换为JDBC,效率降低;
2.Hibernate对JDBC封装的过于厉害。所有失去了对SQL的控制
3.不适合系统中复杂的关联查询,包括多表、复杂查询、大量数据的查询处理都不好。
4.数据量较大时,缓存机制不好使,效率明显降低;
5.对于大批量数据的修改、删除,不适合用Hibernate,这也是ORM框架的弱点。
6.对吸纳规划限制我们的查询。例如,一个持久性类不能映射到多个表。
7.Hibernate带来方便的同时,也使得程序出错排查非常困难。
8.Hibernate是完善的ORM框架,想要Hibernate工作好,数据库设计必须好。数据库结构的变更,需要修改hbm和bean,Hibernate自适应能力为0.
9.setter方法的参数需要自己转换类型。
如何优化Hibernate
1.使用双向一对多关联,不使用单向一对多。
2.灵活使用单向一对多关联。
3.不用一对一,用多对一取代。
4.配饰对象缓存,不使用集合缓存。
5.一对多集合使用bag,多对多集合使用set;
6.继承类使用显示多态。
7.表字段要少,表关联不要怕多,有二级缓存撑腰。
Hibernate是如何延迟加载
1.Hibernate2延迟加载实现:a)实体对象b)集合(Collection );
2.Hibernate3提供了属性的延迟加载功能;
当Hibernate在查询数据的时候,数据并没有存放在内存中,当程序真正对数据操作时,对象才存放在内存中,就实现了延迟加载,他苷省了服务器的内存开销,从而提高了服
务器的性能。
Hibernate有以下五个核心接口:
1.Configuration负责加载主配置文件信息,同时也加载映射关系文件信息。
2.SessionFactory 负责创建Session对象。
3.Session数据库连接会话,负责执行增删改操作。
4.Transaction负责事务控制。
5.Query负责执行特殊査询。
简要描述对对象关系映射(object-relational mapping。简称ORM)的理解,并说明经典实现框架。
对象关系映射(Object-Relational Mapping ,简称ORM)是一种为了解决面向对象与面向关系数据库存在的互不匹配的现象的技术;简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将java程序中的对象自动持久化到关系数据库中;本质上就是将数据从一种形式转换到另外种形式。
经典的ORM实现框架有Hibernate和Mybatis。
简单说说session.load()和session.get()的区别,哪种方式可以使用二级缓存
session.load()和session.get()的区别为:
1.get不支持延迟加载,而load支持。换句话说,get方法一定获取实际的对象, 而load有可能返回代理对象。
2.如果未能发现符合条件的记录,get方法返回null,而load方法会抛出一个 ObjectNotFoundException。 get方法和load方法都可以使用二级缓存。
Hibernate中对象有哪几种状态,有什么规则?
Hibernate中对象可以看做有3种状态,分别是临时态、持久态、游离态,这些状态可以相互转换,转换规则如下图:
具体各个状态的特征为:
1.临时态
1)临时态的对象可以被垃圾回收;
2)临时态的对象未进行过持久化未与session关联。
2.持久态
1)持久态对象垃圾回收器不能回收;
2)持久态的对象进行了持久化,与session相关联,即持久态对象存在于session 缓存中,由session负责管理。
3)持久态对象的数据可以自动更新到数据库中,时机是在调用session.flushO时执 行。而提交事务时会调用session.flushO ,因此提交事务时也会触发同步,可以理解为 tsxommit=sessionilush()+commit。
3.游离态
1)游离态的对象可以被垃圾回收;
2)游离态的对象进行过持久化,但已与session解除了关联。
Hibernate中的关联映射有如下几种:
1)—对一关联
2)—对多关联
3)多对一关联
4)多对多关联
Hibernate有哪几种查询方式
1)使用API查询,如get、load
2)使用HQL查旬
3)使用SQL査询
4 )使用Criteria査询
请简述Hibernate一级缓存和二级缓存的区别和联系?
—级缓存是Session级别的缓存,由Session负责管理,因此一级缓存是Session独享的,即每个Session只能访问自己的一级缓存区。
二级缓存是SessionFactory级别的缓存,由SessionFactory负责管理,因此二级缓 存是Session间共享的,即不同的Session都可以访问二级缓存区。
一级缓存和二级缓存相同的地方是,他们缓存的都是对象数据。