Hibernate

1、Hibernate概念

Hibernate是一种ORM框架,全称为 Object_Relative DateBase-Mapping,在Java对象与关系数据库之间建立某种映射,以实现直接存取Java对象!
也就是我们MVC中的数据持久层->在编写程序中的DAO层…
Hibernate可以帮我们自动生成sql语句。

2、实体对象的三种状态,对应的转换关系

最新的Hibernate文档中为Hibernate对象定义了四种(原来是三种,以前没有移除态,以前把移除态视为瞬时态):瞬时态(new,or transient)、持久态(managed,or persistent)、游状态(detached)、移除态(removed)。
1.瞬时态:当new一个实体对象后,这个对象处于瞬时态,即这个对象只是一个保存临时数据的内存区域,如果变量没有引用这个对象,则会被JVM垃圾回收机制回收。这个对象所保存的数据与数据库没有任何关系,除非通过Session的save()、saveOrUpdate()、persist()、merge()方法把瞬时态对象与数据库关联,并把数据插入或者更新到数据库,这个对象才转为持久态对象。
2.持久态:持久态对象的实例在数据库中有对应的记录,并拥有一个持久化标识(ID)。对持久态对象进行delete操作后,数据库中对应的记录将被删除,那么持久态对象与数据库记录不再存在对应关系,持久态对象变成了移除态(可以视为瞬时态)。持久态对象被修改更改后,不会马上同步到数据库,直到数据库事务提交。
3.游离态:当Session进行了close()、clear()、evict()或flush()后,实体对象从持久态变成游离态,对象虽然拥有持久和与数据库对应记录一致的标识值,但是因为对象已经从会话中清除了,对象不在持久化管理中,所以处于游离态。游离态的对象与临时状态的对象十分相似,只是他还含有持久化标识。

3、锁机制的作用?Hibernate的悲观锁和乐观锁机制?

锁机制:有些业务逻辑在执行过程中要求对数据进行排他性的访问,于是需要通过一些机制保证在此过程中数据被锁住不会被外界修改,这就是所谓的锁机制。
Hibernate支持乐观锁和悲观锁两种锁机制。
1.悲观锁:认为在数据处理过程中极有可能存在修改数据的并发事务(包括本系统的其他事务或来自外部系统的事务),于是将处理的数据设置为锁定状态。悲观锁必须依赖数据库本身的锁机制才能真正的保证数据访问的排他性。
2.乐观锁:认为对数据的并发操作不会经常发生,通过更加宽松的锁机制来解决由于悲观锁排他性的数据访问对系统性能造成的影响。
最常见的乐观锁是通过数据版本标识来实现的,读取数据时获得数据的版本号,更新数据时将此版本号加1,然后和数据库表对应记录的当前版本号进行比较,如果提交的数据版本号大于数据库此前记录的当前版本号则更新数据,否则认为是过期数据无法更新。Hibernate中通过Session的get()和load()方法从数据库中加载对象时可以通过参数指定使用悲观锁;而乐观锁可以通过给实体类型加整型的版本字段再通过XML或@version注解进行配置。
使用乐观锁会增加了一个版本字段,很明显需要额外的空间来存储这个字段,浪费空间,但是乐观锁会让系统具有更好的并发性,这是对时间的节省。因此乐观锁也是典型的空间换时间的策略。

4、Hibernate常见的优化策略

1.指定合理的缓存机制(二级缓存、查询缓存)。
2.采用合理的Session管理机制。
3.尽量使用延迟加载特性。
4.设定合理的批处理参数。
5.如果可以,选用基于版本号的乐观锁替代悲观锁。
6.在开发过程中,开启hibernate.show_sql选项查看生成的SQL,从而了解底层的状况;开发完成后关闭此选项。
7.考虑数据库本身的优化,合理的索引、恰当的数据分区策略都会对持久层的性能带来可观的提升。

5、hibernate的延迟加载机制?延迟加载与Session关闭的矛盾如何处理

延迟加载就是并不是在读取的时候就把数据加载进来,而是等到使用的时候再加载。hibernate使用了虚拟代理机制来实现延迟加载,我们使用Session的load()方法加载数据或者一对多关联映射在使用延迟加载的情况下,从一的一方加载多的一方,得到的都是虚拟代理,返回给用户的并不e是’s实体h对象本省而是实体对象的代理。代理对象在用户调用getter方法时才会去数据库加载数据。但加载数据就需要数据库连接。而当我们把会话关闭,数据库连接同时关闭了。
怎么处理:
1.关闭延迟加载特性:因为hibernate的延迟加载特性是可以通过映射文件或者注解进行配置的,但有缺陷,首先,出现“no session or session was closed”说明系统中已经存在主外键关联,如果延迟加载,每次查询的开销很大。
2.再session关闭之前先获取需要查询的数据,可以使用工具方法hibernate.isInitialized()判断对象是否被加载,如果没有被加载,用hibernate.initialize()方法加载对象。
3.使用拦截器或者过滤器延长Session的生命周期直到视图获得数据。Spring整合Hibernate提供的OpenSessionInViewFilter和OpenSessionInViewInterceptor就是这种做法。

6、Hibernate中Session的load方法和get方法的区别

1.如果没有找多符合条件的记录,get方法返回null,load方法抛出异常。
2.get方法直接返回实体类对象,load方法返回实体类对象的代理。
3.再hibernate 3之前,get方法只能在一级缓存中进行数据查找,如果没有找到对应的数据则越过二级缓存,直接发出SQL语句完成数据读取;load方法则可以从二级缓存中获取数据;get方法不再时对二级缓存只写不读,他也可以访问二级缓存了。
对于load()方法 hibernate让那位该数据在数据库中一定存在可以放心使用代理来实现延迟加载,如果没有数据就抛出异常,而通过get方法获取的数据可以不存在。

7、hibernate中SessionFactory和Session是线程安全的吗?这两个线程能否共享同一个Session?

SessionFactory对应Hibernate的一个数据存储的概念,他是线程安全的,可以被多个线程并发访问。Session Factory一般只会在启动的时候创建。对于应用程序,最好将SessionFactory通过单例模式封装以便访问。Session是一个轻量级非线程安全的对象(线程之间不能共享Session),他表示与数据库进行交互的一个工作单元。Session是由SessionFActory创建的,在任务完成后他会被关闭。Session是持久层服务对外提供的主要接口。Session会延迟获取数据库连接(也就是在需要的时候再连接)。为了避免创建太多的Session,可以使用ThreadLocal将Session和当前线程绑定在一起,这样可以让同一个线程获得的总是同一个session。SessionFactory的getCurrentSession()方法就可以做到。

8、hibernate如何实现分页查询?

通过hibernate实现分页查询:
1.只需要提供HQL语句(调用Session的createQuery()方法)或查询条件(调用Session的createCriteria()方法)。
2.设置查询起始行数(调用Query或Criteria接口的setFirstResult()方法)和最大查询行数(调用Query或Criteria接口的setMaxResults()方法),并调用query或Criteria接口的list()方法,hibernate会自动生成分页查找的SQL语句。

9、Hibernate的一级缓存、二级缓存以及查询缓存

hibernate的Session提供了一级缓存的功能默认是有效的,当应用程序保存持久化实体,修改持久化实体时,Session并不会立即把这种改变提交到数据库,而是缓存在当前的Session中,除非显示调用了Session的flush()方法或者通过close()方法关闭Session。通过一级缓存,可以减少程序和数据库的交互,从而提高数据库访问性能。
SessionFactory级别的二级缓存时全局性的,所有的Session可以共享这个二级缓存。不过二级缓存默认是关闭的,需要显示开启并指定需要使用那种二级缓存实现类。一旦开启了二级缓存并设置了需要使用二级缓存的实体类,SessionFactory就会缓存访问过的该实体类的每一个对象,除非缓存的数据超出了指定的缓存空间。一级缓存和二级缓存都是对整个实体进行缓存,不会缓存普通属性,如果想缓存普通属性,可以使用查询缓存。查询缓存就是将HQL或SQL语句以及它们的查询结果作为键值对进行缓存,对于同样的查询也可以直接从缓存中获取数据。查询缓存默认也是关闭的,需要显示开启。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值