关于Hibernate的一些常规问题

1、Session的概念.

a)        Session只是对connection做了近一部封装,虽然做了封装,但是当你open,它不一定openconnection,而是从连接池里获取了一个connection.

b)        Session还负责管理了缓存.

c)        Session用完之后必须关闭,一般一个业务对应一个session,而且session不是线程安全的.

2、给我谈谈OpenSessionInView?

a)        OpenSessionInView最主要的功能就是使Session一直打开(使lazy失效),如果不这样的话,lazy的实现机制就是当用到数据时才去真正的加载数据,如果此时session已经关闭的话,Hibernate会抛出异常,当你使用了OpenSessionInView它会使Session一直打开的.

b)        OpenSessionInView的实现是采用Filter,在处理请求时候打开session,当请求全部处理完成,服务器返回给客户端信息时候,关闭session.

3、如何解决懒加载抛出异常的问题?

a)        方法一:偷懒的做法就是使用OpenSessionInView,这样可以使Session一直被打开.

b)        方法二:例如我们现在在呈现层要显示人员列表信息,只需要显示人员的姓名,年龄,职位,但是不幸,数据库的字段却有100,当然,我们可以使用from Person,在页面使用,但是这样性能会大大的消耗.最实际的做法,就是需要什么就查询什么,在页面直接显示出来即可,这样完全可以不使用OpenSessionInView.

4、谈谈为什么会产生N+1?

a)        产生N+1的问题是因为使用query.iterator()使用的不当.

b)        IteratorLoad对象时,会发出n+1SQL语句,第一条会加载所有对象的主键,然后根据主键加载对应的实体,当然,有多少个主键,它就会发送多少条SQL.

5、谈谈query.list() query.iterator().

a)        list每次都会发出sql语句,list不会使用缓存的数据,但是它会把查询的数据存储进缓存.

b)        iterator在默认情况下,它会利用缓存,但是如果缓存不存在数据,有可能出现N+1问题.

6、谈谈inverse / lazy / cacsde.

a)        inverse,一般在one-to-many双向关联的情况下使用,一般都会在一的一方加上inverse关键字,inverse就代表把关系交给多的一方来维护,这样可以大大的提高性能.

例如:现在有班级和学生,关系为1对多.现在如果要加入1个班级和2个学生,它会出现一些问题,你插入多少个学生,它就会发出多少条update语句,因为你insert学生的时候,它并不知道自己属于哪个班级的,首先将该字段的值默认为null,然后最后来更新.所以一般都要使用inverse,使1的一方维护权失效,交给多的一方来维护.

如果不使用inverse就相当于让姚明记13Y中国人的名字一样,所以我们最好采用13Y人来记姚明.

b)        lazy,延迟加载,使用lazy可以大大的维护系统的性能,使用了lazy以后,只有当我真正的使用时,它才会发出SQL来加载对象.

                        i.              例如:现在有班级和学生,当我查询班级时,此时我并不想查询班级对应的学生,如果在这里,不使用lazy的话,它会直接帮你把班级对应的学生也加载上来, 如果现在有1万个学生呢?它会理所当然的帮你全部加载上来,这样的话,性能就可向而知了.

c)        cascade级联操作,加上cascade会产生连锁上的反应.

                        i.              举个最简单的例子:还是班级和学生,我现在要删除一个班级,如果我没使用cascade关键字的话,必须亲自去先删除和班级关联的学生,再来删除班级,不然的话,Hibernate会直接抛出异常,因为还有表在引用它,如果加了cascade的话,它会首先根据加载主键的id,删除对应这个班级的这个学生,然后在删除班级.

7、请谈谈你对一级缓存,二级缓存,以及查询缓存的看法.

a)        一级缓存:可以称为session级缓存或者事物级缓存,它的声明周期主要是跟随session存在而存在,session消逝即消逝.

                        i.              从两个方面来说明一级缓存.

                      ii.              查询实体对象:Iterator查询时,首先会看一级缓存里到底有没有,List不会使用一级缓存,但是结果会存在在一级缓存里.

                    iii.              查询普通属性:Iterator查询时,你查询多少次,它会发送多少次SQL语句,不会使用一级缓存,查询结果也不会存放在一级缓存里.

                    iv.              结论:一级缓存主要就是存放实体对象的,只有查询,迭代实体对象时,它才会去看看一级缓存里有没有,普通属性则不会.

b)        二级缓存:可以称为SessionFactory级缓存或者称为进程级缓存,它的声明周期和SessionFactory是一样的,它可以被所有的session共享,它的特性也是只缓存实体对象.

c)        查询缓存:如果当前表发生了任何操作,查询缓存立刻立即消息.它是针对普通结果集的缓存,对待实体对象,只缓存ID.

                        i.              查询缓存对Iterator没有任何效果,Iterator在查询普通属性,没有使用缓存.只对List有效果.

                      ii.              查询实体数据,也是只对List有效果,Hibernate会根据实体对象的id去查询实体,如果缓存中存在相应的实体,则不继续查询,否则发出SQL语句加载对象.

8、谈谈并发控制.

a)        并发控制包括悲观锁定,乐观锁定.

                        i.              悲观锁定,<span style="font-family: 宋体; color: black; font-size: 12pt; mso-ascii-font-family



  转载请标明出处 http://blog.csdn.net/shimiso 

技术交流群:361579846


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值