Hibernate常见面试题汇总

  1.在数据库中条件查询速度很慢时候,如何优化?

  1.建索引

  2.减少表的间关联

  3.优化sql尽量让sql很快定位数据不要让sql做全表查询应该走索引,把数据量大表排在前面

  4.简化查询字段没用字段不要已经对返回结果控制尽量返回少量数据

  2.在Hibernate中进行多表查询,每个表中各取几个字段,也就是说查询出来结果集并没有个实体类和的对应,如何解决这个问题?

  解决方案按照Object数据取出数据然后自己组bean

  解决方案 2对每个表bean写构造比如表要查出field1,field2两个字段那么有个构造就是Bean(type1 filed1,type2 field2) 然后在hql里面就可以直接生成这个bean了具体如何用请看相关文档我说不是很清楚

  session.load和session.get区别

  Session.load/get思路方法均可以根据指定实体类和id从数据库读取记录并返回和的对应实体对象其区别在于:

  如果未能发现符合条件记录get思路方法返回null而load思路方法会抛出个ObjectNotFoundException

  Load思路方法可返回实体代理类例子而get思路方法永远直接返回实体类

  load思路方法可以充分利用内部缓存Cache和 2级缓存Cache中现有数据而get思路方法则仅仅在内部缓存Cache中进行数据查找如没有发现对应数据将越过 2级缓存Cache直接SQL完成数据读取

  Session在加载实体对象时将经过过程:

  首先Hibernate中维持了两级缓存Cache级缓存Cache由Session例子维护其中保持了Session当前所有关联实体数据也称为内部缓存Cache而第 2级缓存Cache则存在于SessionFactory层次由当前所有由本SessionFactory构造Session例子共享出于性能考虑避免无谓数据库访问Session在数据库查询功能的前会先在缓存Cache中进行查询首先在第级缓存Cache中通过实体类型和id进行查找如果第级缓存Cache查找命中且数据状态合法则直接返回

  的后Session会在当前“NonExists”记录中进行查找如果“NonExists”记录中存在同样查询条件则返回null“NonExists”记录了当前Session例子在的前所有查询操作中未能查询到有效数据查询条件(相当于个查询黑名单列表)如此如果Session中个无效查询条件重复出现即可迅速作出判断从而获得最佳性能表现

  对于load思路方法而言如果内部缓存Cache中未发现有效数据则查询第 2级缓存Cache如果第 2级缓存Cache命中则返回

  如在缓存Cache中未发现有效数据则发起数据库查询操作(Select SQL)如经过查询未发现对应记录则将此次查询信息在“NonExists”中加以记录并返回null

  根据映射配置和Select SQL得到ResultSet创建对应数据对象

  将其数据对象纳入当前Session实体管理容器(级缓存Cache)

  执行Interceptor.onLoad思路方法(如果有对应Interceptor)

  将数据对象纳入 2级缓存Cache

  如果数据对象实现了LeCycle接口数据对象onLoad思路方法

  返回数据对象

  Hibernate主键生成机制

  1) assigned

  主键由外部负责生成无需Hibernate参和

  2) hilo

  通过hi/lo 算法实现主键生成机制需要额外数据库表保存主键生成历史状态

  3) seqhilo

  和hilo 类似通过hi/lo 算法实现主键生成机制只是主键历史状态保存在Sequence中适用于支持Sequence数据库如Oracle

  4) increment

  主键按数值顺序递增此方式实现机制为在当前应用例子中维持个变量以保存着当前最大值的后每次需要生成主键时候将此值加1作为主键这种方式可能产生问题是:如果当前有多个例子访问同个数据库那么由于各个例子各自维护主键状态区别例子可能生成同样主键从而造成主键重复异常因此如果同数据库有多个例子访问此方式必须避免使用

  5) identity

  采用数据库提供主键生成机制如DB2、SQL Server、MySQL中主键生成机制

  6) sequence

  采用数据库提供sequence 机制生成主键如Oralce 中Sequence

  7) native

  由Hibernate根据底层数据库自行判断采用identity、hilo、sequence其中种作为主键生成方式

  8) uuid.hex

  由Hibernate基于128 位唯值产生算法生成16 进制数值(编码后以长度32 串表示)作为主键

  9) uuid.

  和uuid.hex 类似只是生成主键未进行编码(长度16)在某些数据库中可能出现问题(如PostgreSQL)

  10) foreign

  使用外部表字段作为主键般而言利用uuid.hex方式生成主键将提供最好性能和数据库平台适应性

  这10中生成OID标识符思路方法,increment 比较常用,把标识符生成权力交给Hibernate处理.但是当同时多个Hibernate应用操作同个数据库,甚至同张表时候.就推荐使用identity 依赖底层数据库实现,但是数据库必须支持自动增长,当然针对区别数据库选择区别思路方法.如果你不能确定你使用数据库具体支持什么情况下.可以选择用native 让Hibernate来帮选择identity,sequence,或hilo.

  另外由于常用数据库如Oracle、DB2、SQLServer、MySql 等都提供了易用主键生成机制(Auto-Increase 字段或者Sequence)我们可以在数据库提供主键生成机制上采用generator-=native主键生成方式

  不过值得注意些数据库提供主键生成机制在效率上未必最佳大量并发insert数据时可能会引起表的间互锁数据库提供主键生成机制往往是通过在个内部表中保存当前主键状态(如对于自增型主键而言此内部表中就维护着当前最大值和递增量)的后每次插入数据会读取这个最大值然后加上递增量作为新记录主键的后再把这个新最大值更新回内部表中这样次Insert操作可能导致数据库内部多次表读写操作同时伴随还有数据加锁解锁操作这对性能产生了较大影响因此对于并发Insert要求较高系统推荐采用uuid.hex 作为主键生成机制

Tags: 

延伸阅读

最新评论

发表评论