《深入浅出Hibernate》----夏昕
****第一章的连接池值得看
****Transaction.commit方法中随即调用session.flush方法,flush方法中,会完成两个任务:
<1>flushEverything();刷新所以数据(设计脏数据的判定)。
<2>execute();执行数据库完成SQL持久化(涉及翻译成相应的SQL语句交由数据库执行)。
****在sessionFactory.openSession中,Hibernate会初始化数据库连接,与次同时,将AutoCommint设为false,如下
session=sessionFactory.openSession();
session.save(user);
session.close();
并不起作用,因为缺少commite();
****基于JTA的事务管理提供了跨越session的事务管理的能力
****session.get与session.load的区别:
<1>若未能发现符合条件的记录,get方法返回null,而load方法会抛出一个ObjectNotFoundException。
<2>load方法可以返回实体的代理类实例(用于延迟加载等),而get方法直接返回实体类。
<3>load方法可以充分利用一集缓存session和二级缓存sessionFactory,而get仅能利用一级缓存。
****Hibernate3中,原hibernat2的find()与iterate()方法由Query。list()与Quesy。iteerate()代替。
****find()不能利用缓存,iterate()可以利用缓存但在没有缓存的查询语句中,实际用到的sql查询语句为
N+1的形式,即先选出id,再由id进行select。
****find()的实现中用是get(),而iterate()用的是load()。(不确定)
****优化:
制定合理的缓存策略;
采用合理的session管理机制(如TreadLocal);
尽量采用延迟加载;
设定合理的批处理参数(batch_size);
如果可以,选用UUID作为主键生成器;
如果可以,选用基于version的乐观锁代替悲观锁;
打开Hibernate的SQL日志输出(hibernate。show_sql);
数据库的优化;
一对多关联中应在“一”端使用“inverse=true”
****调试:
<1>hibernate.cfg.xml中设show_sql为true
<2>把log4j配置文件中的JDBC的参数绑定打开(log4j.properties中log4j.net.sf.hibernate.type=debug)
****session/transaction不应由业务逻辑或DAO来管理应由容器管理,如Spring容器管理。
****记录数据库操作的日志可以用hibernat中的intercepter来实现P310
****注意测试用例的使用P371
《hibernat quickly》
***DAO两种基本的使用方式:
每个应用一个DAO:一个中央DAO负责创建,更新,查询和删除所有的实体对象。
每个类一个DAO:每个实体类都有自己的DAO,它只负责创建,查询,更新和删除该对象的实例。
推荐使用第二种,符合开闭原则(open-closed),对扩展开发,对修改关闭。
***解决各个DAO的重复代码:
A。层超类型模式:每个DAO中的同样代码集中放到AbstractDAO中,其他具体DAO扩展它。
B。Spring的template-callback模式:即用HibernateTemplate类来代替session,
与HbirenateTemplate交互有两种方法:a。辅助方法(与session中方法同名)b。回调方法
C。用Spring的HibernateDAOSupport类更加方便。
***可创建用于组织DAO的Registry类:它是一个单件(singleton)由Spring支持。利用它可以实现客户端对象可在项目的任何地方获得具体DAO应用,而不需知道Spring的任何情况,从而实现隔离。
***解决只有脱管对象(detached object),即session的范围:
A。从控制器访问Session(使用初始化servlet,无关闭session)
B。servlet过滤器(由过滤器打开和关闭session)
C。从服务层组件DAO访问session(使用线程局部会话Thread Local Session)
D。使用Spring,它在后台使用了线程局部会话模式。
***几条推荐原则:
hibernate中选择短的session周期,action中无需管理session。
将hibernate查询逻辑放在DAO中而不是action中,action只协调和表示逻辑留在控制器中。
action不应该调用另一个action来实现逻辑,应将逻辑放在服务层(逻辑)或数据访问层。
***利用hibernate3的持久化事件可以实现日志记录