Hibernate常见面试题
无论多复杂,hibernate终究是一个和数据库打交道的框架,与jdbc功能一样。所以没有理由畏惧hibernate. hibernate的难点我觉得有两方面:一是性能优化,二是session管理。性能优化是个经验活; 关于session管理,单纯的hibernate可以使用ThreadLocal来解决, 如果和spring结合,使用spring提供的session管理方案很不错。
hibernate常见面试题:
---------------------------------------------------
http://topic.csdn.net/u/20081207/22/6d6b75f8-3988-484c-ab4f-f388869b2f00.html
http://lpcjrflsa.javaeye.com/blog/325932
Hibernate工作原理及为什么要用?
原理:
1.读取并解析配置文件
2.读取并解析映射信息,创建SessionFactory
3.打开Sesssion
4.创建事务Transation
5.持久化操作
6.提交事务
7.关闭Session
8.关闭SesstionFactory
为什么要用:
.对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码。
.Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现。他很大程度的简化DAO层的编码工作
.hibernate使用Java反射机制,而不是字节码增强程序来实现透明性。
.hibernate的性能非常好,因为它是个轻量级框架。映射的灵活性很出色。它支持各种关系数据库,从一对一到多对多的各种复杂关系。
2.Hibernate是如何延迟加载?
. Hibernate2延迟加载实现:a)实体对象 b)集合(Collection)
. Hibernate3 提供了属性的延迟加载功能
当Hibernate在查询数据的时候,数据并没有存在与内存中,当程序真正对数据的操作时,对象才存在与内存中,就实现了延迟加载,他节省了服务器的内存开销,从而
提高了服务器的性能。
3.Hibernate中怎样实现类之间的关系?(如:一对多、多对多的关系)
类与类之间的关系主要体现在表与表之间的关系进行操作,它们都市对对象进行操作,我们程序中把所有的表与类都映射在一起,它们通过配置文件中的many-to-one、
one-to-many、many-to-many、
4. 说下Hibernate的缓存机制
. 内部缓存存在Hibernate中又叫一级缓存,属于应用事物级缓存
. 二级缓存:
a) 应用及缓存
b) 分布式缓存
条件:数据不会被第三方修改、数据大小在可接受范围、数据更新频率低、同一数据被系统频繁使用、非关键数据
c) 第三方缓存的实现
5. Hibernate的查询方式
Session.get Session.load
Sql、Criteria,object comptosition
Hql:
1、 属性查询
2、 参数查询、命名参数查询
3、 关联查询
4、 分页查询
5、 统计函数
6. 如何优化Hibernate?
.使用双向一对多关联,不使用单向一对多
.灵活使用单向一对多关联
.不用一对一,用多对一取代
.配置对象缓存,不使用集合缓存
.一对多集合使用Bag,多对多集合使用Set
.继承类使用显式多态
.表字段要少,表关联不要怕多,有二级缓存撑腰
7. get和load区别;
1)get如果没有找到会返回null, load如果没有找到会抛出异常。
2)get会先查一级缓存, 再查二级缓存,然后查数据库;load会先查一级缓存,如果没有找到,就创建代理对象, 等需要的时候去查询二级缓存和数据库。
8. N+1问题。
Hibernate中常会用到set,bag等集合表示1对多的关系, 在获取实体的时候就能根据关系将关联的对象或者对象集取出。
解决方法一个是延迟加载, 即lazy=true;
一个是预先抓取, 即fetch=join;
9. inverse的好处。
在关联关系中用inverse在控制由哪一端来控制关联关系。这样做有什么好处呢?举customer和order的例子来说。他们是一对多的关系,如果只单向关联,且由customer控制关联关系,则如果我想添加一个order,则先取customer, 然后getOrders得到所有的order集合,然后往集合里面多加入一个order,然后save(customer), 这样开销太大。 如果改双向关联且由order主控关系,则如果想为customer增加一个order, 则new一个order,然后给order设置customer,然后save(order)即可。
10 merge的含义:
http://cp3.iteye.com/blog/786019 这里写的好;
如果session中存在相同持久化标识(identifier)的实例,用用户给出的对象的状态覆盖旧有的持久实例
如果session没有相应的持久实例,则尝试从数据库中加载,或创建新的持久化实例
最后返回该持久实例
用户给出的这个对象没有被关联到session上,它依旧是脱管的
11 persist和save的区别
persist不保证立即执行,可能要等到flush;persist不更新缓存;
12 cascade,用来指示在主对象和它包含的集合对象的级联操作行为,即对住对象的更新怎么影响到子对象;
save-update: 级联保存(load以后如果子对象发生了更新,也会级联更新). 但它不会级联删除
delete: 级联删除, 但不具备级联保存和更新
all-delete-orphan: 在解除父子关系时,自动删除不属于父对象的子对象, 也支持级联删除和级联保存更新.
all: 级联删除, 级联更新,但解除父子关系时不会自动删除子对象.
delete-orphan:删除所有和当前对象解除关联关系的对象
13 session.commit 和flush区别, commit会先调用flash执行session清理,然后提交事物; flash执行session,但不一定提交事物(因为事物可能被委托给外围的aop代理来做);
14 session清理的顺序: insert -> update -> delete -> 对集合进行delete -〉对集合的insert;
15 检索策略: 立即检索,lazy=false;延迟加载:lazy=true;预先抓取: fetch=“join”;
16 主键生成 策略有哪些?identity,increment, sequence, assigned, uuid.hex, foreign; foreign是一对一主键关联的情况下使用。