关于 Hibernate 实体持久化部分的源码分析
暂时阅读了 Hibernate 的 Session 的 save(),update(),flush(),觉得大概了解了 Hibernate 的实体持久化,在此记录一下;
介绍下几个关键的地方,
1,Hibernate 的持久化操作的实际执行者都是 Listener 对象,调用 onXXX() 方法进行实际的数据库操作;
2,actionQueue 存储着 action,action 就是等待着执行的数据库操作;
3,PersistentContext 用于存储持久化对象,fush() 就会使里面的部分对象(符合要求的对象)的状态同步到数据库(具体的操作下面会提到);
save() 的过程:
会把实体放进 PersistentContext,生成用于插入数据的 SQL 语句,actionQueue 会调用 addInsertAction()方法,其实就是执行插入,并没有真的往里面加入 action;
update() 的过程:
就是把实体放进去 PersistentContext,当然,其类型是特别的(MANAGED 或 READ_ONLY,不为 Status.GONE 和 Status.LOADING),能在 flush() 的时候把状态同步到数据库;
flush() 的过程:
找出 PersitentContext 里的符合条件的实体,生成对应的 updateAction,把 updateAction 放进 ActionQueue 里去,也就是把 action 添加到 executableList 中,然后生成用于update 的语句,放进 batchStatements 里(其实,ActionQueue 的 executeActions 的操作就是执行 batchStatements 里的 SQL 语句,或者直接执行 executeBatch() 方法),然后调用 actionQueue 的 executeActions() 方法,即再执行 batchStatements 里的全部 SQL,或者直接执行生成的 update 语句(不放进 batchStatement 里),总的来说都是执行全部 update 语句;
由上可知,其实 flush() 就是执行实体更新,实体更新也只能通过 flush() 执行,用 flush() 进行批量插入以提高效率是不可能的,这也是李刚的轻量级 Java EE 的一个大的错误之处(第四版的 P473~474);
我体会不到 flush 有什么好处,底层就是一次过把全部在内存里的 PreparedStatement 对象 全部调用 executeUpdate() / executeBatch(),连与 DB 通讯的时间都没有节省到,加大了学习成本,增加了使用陷阱(flush() 的行为 与 flushMode 直接相关);
上述有误,flush 有好处,flush 可以实现 executeBatch,提高性能(批量更新,update 同一个表的数据,sql 必须一样),executeBatch 即节省了通讯时间;
浙公网安备 33010602011771号