hibernate常见面试题详解

整理hibernate常见面试题

  1. 简述hibernate运行原理或者工作原理
  2. 简述hibernate的get和load方法区别
  3. 简述hibernate数据三种状态
  4. 简述hibernate的缓存机制
  5. 简述hibernate中getCurrentSession和openSession区别
  6. 简述hibernate的乐观锁和悲观锁
  7. 简述hibernate的懒加载机制
  8. 简述hibernate的事务机制

1、hibernate运行原理: 
hibernate里面提供了3个核心接口 
Configuration、SessionFactory、Session 
1、hibernate启动的时候利用Configuration读取xml配置文件 
2、通过配置文件创建SessionFactory对象,初始化hibernate基本信息 
3、获取session然后调用CRUD方法进行数据操作,hibernate会把我们的数据进行三种状态的划分,然后根据状态进行管理我们的数据,对应的发送SQL进行数据操作 
4、关闭session,如果有事务的情况下,需要手动获取事务并开启,然后事务结束后提交事务。 
5、在提交事务的时候,去验证我们的快照里面的数据和缓存数据是否一致,如果不一致,发送SQL进行修改,

2、hibernate的get方法和load方法的区别 
1、get和load都是利用主键策略查询数据, 
2、get默认不使用懒加载机制,load默认要使用懒加载机制,所谓的懒加载就是我们这个数据如果不使用,hibernate就不发送SQL到数据库查询数据。 
3、当查询数据库不存在的数据的时候,get方法返回null,load方法抛出空指针异常, 
原因是因为,load方法采用的动态代理的方式实现的,我们使用load方法的时候,hibernate会创建一个该实体的代理对象,该代理只保存了该对象的ID,当我们访问该实体对象其他属性,hibernate就发送SQL查询数据封装到代理对象,然后在利用代理对象返回给我们实际的数据,

3、hibernate的数据三种状态 
hibernate把他所管理的数据划分为三种状态 
瞬时的(刚new出来的数据–内存有,数据库没有) 
持久的 (从数据查询的,或者刚保存到数据库,session没关闭的, 数据库有,内存也有) 
游离的 、脱管的(数据库有,内存没有) 
这里写图片描述

实际上hibernate对数据划分三种状态,主要是为了管理我们持久的数据,在事务提交的时候,hibernate去对比处于持久状态的数据是否发生改变,(快照区、一级缓存区),当我们会话结束前,对持久状态数据进行了修改的话,快照区的数据会跟着改变。当session提交事务的时候,如果发现快照区和一级缓存的数据不一致,就会发送SQL进行修改。

4. 简述hibernate的缓存机制 
hibernate分为2级缓存 
一级缓存又叫session缓存,又叫事务级缓存,生命周期从事务开始到事务结束,一级缓存是hibernate自带的,暴力使用,当我们一创建session就已有这个缓存了。数据库就会自动往缓存存放, 
二级缓存是hibernate提供的一组开放的接口方式实现的,都是通过整合第三方的缓存框架来实现的,二级缓存又叫sessionFactory的缓存,可以跨session访问。常用的EHcache、OScache,这个需要一些配置。

当我们每次 查询数据的时候,首先是到一级缓存查看是否存在该对象,如果有直接返回,如果没有就去二级缓存进行查看,如果有直接返回,如果没有在发送SQL到数据库查询数据, 
当SQL发送查询回该数据的时候,hibernate会把该对象以主键为标记的形式存储到二级缓存和一级缓存,如果返回的是集合,会把集合打散然后以主键的形式存储到缓存。一级缓存和二级缓存只针对以ID查询的方式生效,get、load方法。

5. 简述hibernate中getCurrentSession和openSession区别 
getCurrentSession和openSession都是通过H的工厂去获取数据库的会话对象, 
1、getCurrentSession会绑定当前线程,而openSession不会,因为我们把hibernate交给我们的spring来管理之后,我们是有事务配置,这个有事务的线程就会绑定当前的工厂里面的每一个session,而openSession是创建一个新session。 
2、getCurrentSession事务是有spring来控制的,而openSession需要我们手动开启和手动提交事务, 
3、getCurrentSession是不需要我们手动关闭的,因为工厂会自己管理,而openSession需要我们手动关闭。 
4、而getCurrentSession需要我们手动设置 绑定事务的机制,有三种设置方式,jdbc本地的Thread、JTA、第三种是spring提供的事务管理机制org.springframework.orm.hibernate4.SpringSessionContext,而且srping默认使用该种事务管理机制,

6. 简述hibernate的乐观锁和悲观锁

   hibernate在管理我们数据的时候的,永远无法避免一个问题,那就是并发,
  • 1
  • 2

并发指的是多个线程同时访问同一个资源,而并发会存在很多问题, 
同步指的是多个线程访问同一资源的时候,当一个线程对该资源的操作完成了以后,才交给下一个线程进行操作,有点像排队 
异步指的是多个线程访问同一资源的时候,所有的线程一起访问这个资源,不需要等待其他线程访问完成,也可以进行访问和操作。有点像挤公交车 
而我们hiberante在并发的时候会存在如下问题: 
1、丢失数据更新 
这里写图片描述
如上图我们可以看出,线程1和线程2都对同一条数据进行更新, 
在T8时间点线程2已经完成了数据的更新,在T9时间点如果线程1回滚age=20,那线程2的更新age=25就丢失, 
另外一种,如果T9时间点 我们线程1提交,那我们线程2的age=25也丢失了 
2、数据脏读 
这里写图片描述
所谓的数据脏读,就是当并发的时候,一个线程进行修改,还未提交事务的时候另一个线程就读取了更新后的数据,但是后面第一个线程回滚,更新无效,那第二个线程读取到的数据就是脏数据 
3、数据虚读或者幻读 
这里写图片描述
此处的线程1修改完age之后,线程2立马进来修改了name,并提交事务,线程1在读取我们的数据,发现被修改了2个字段,这就是虚读或者幻读

4、不可重复读 
这里写图片描述
此处线程1先查询age=20,线程2把age修改Wie30,线程1再次查询的时候发现age=30,所以重复读取两次数据不一致,所以重复读取出错,

以上问题在并发中都可能存在,所以我们hiberante一定要处理线程并发的情况,hibernate就需要进行线程同步,提供的机制是利用锁来完成,

悲观锁 
所谓的悲观锁,就是hibernate心态不好,认为每一次操作都会出现并发,所以当我们查询数据的时候就直接把这一条数据锁住,不让别人操作。底层是利用的数据库的for update来实现的,就是查询数据的时候利用数据库把当前查询的数据给锁住,不让其他线程操作,实现如下:

 
  1. Admin admin1 = (Admin) session.get(Admin.class, 1, LockMode.UPGRADE);

  2. Admin admin2 = (Admin) session.get(Admin.class, 1, LockOptions.UPGRADE);

H4以后就不推荐使用LockMode,而使用LockOptions来实现悲观锁

 
  1. // Admin admin = (Admin) session.get(Admin.class, adminId);

  2.  
  3. Admin admin1 = (Admin) session.get(Admin.class, 1, LockMode.UPGRADE);

  4. // Admin admin2 = (Admin) session.get(Admin.class, 1, LockOptions.UPGRADE);

  5.  
  6. // SQLQuery q = session.createSQLQuery("select * from xx_plat_admin");

  7. // q.setLockOptions(LockOptions.UPGRADE);

  8. //

  9. // Query q1 = session.createQuery("from Admin admin");

  10. // q1.setLockMode("admin", LockMode.UPGRADE);

  11. // q1.setLockOptions(LockOptions.UPGRADE);

  • 7
    点赞
  • 88
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值