基本上每个系统都有一个导入功能,大量的数据填写进入 excel 模板中,然后使用导入功能导入的数据库中,这样可以大大的提高工作效率。那么导入就涉及到了批量保存数据库的问题了。 那么通常情况下,在一个 Session 对象的缓存中数量有限的持久化对象,等到Session 对象处理事务完毕,还要关闭 Session 对象,从而及时释放 session 的缓存占用的内存。在批量保存 1 万条数据,如果一次性把需要保存的 1 万条数据加载到内存职工,当执行事务提交的时候,就会清理缓存, hibernate 执行 1 万条更新语句。这样更新的方式有两个缺点: ( 1 ) 占用大量内存,必须把 1 万条加载到内存中,然后一一更新它们。 ( 2 )执行的 update 数目过多,每个 update 语句只能更新一条数据,必须通过 1万条 update 语句才能更新 1 万条数据,频繁地访问数据库,会大大降低应用的性能。 对于以上的情况,咱们可以通过 Session 来进行批量操作, Session 的 sava 方法都会把处理对象的存放在自己的缓存职工,如果通过一个 Session 对象来处理大量持久化对象,应该及时从缓存中清空已经处理完毕并且不会在访问的对象。具体的做法就是处理完一个对象或者小批量对象后,立刻调用 Flush ()方法清理缓存,然后再调用Clear ()方法清空缓存。 如果通过 Session 来进行批量操作,会受到以下的约束: 1. 需要在 hibernate 的配置文件中设置 JDBC 单次批量处理的数目,合理的取值通常为 10 ~50 ,例如 hibernate.jdbc.batch_size= 3 0; 这样设置的,就需要保证每次像数据库发送的批量 SQL 语句数目与这个 batch_size 属性一致。 2. 如果操作对象采用 "identity" 标识符生成器,则 Hibernate 无法在 JDBC 层进行批量插入操作。 3. 进行批量操作时,建议关闭 hibernate 的第二级缓存, Session 的缓存为hibernate 的第一级缓存,通常它是事务范围内的缓存,每个事务都有单独的第一级缓存。 SessionFactory 的外置缓存为 Hibernate 的第二级荤菜,它是应用范围内的缓存,所有的事务都共享同一个第二级缓存。在任何情况下, hibernate 的第一级缓存总是可用的,在默认情况下, hibernate 的第二级缓存是关闭的,但是也可以在 hibernate的配置文件中手动关闭二级缓存: Hibernate.cache.use_second_level_cache=false; 在 itoo 中批量保存的代码如下: - * 批量保存
- *
- * @param list
- * list类型
- * @return 返回boolean值
- */
- public <T> boolean saveEntitys(List<T> list) {
- boolean flag = false;
- int batchSize = 30;
- int i = 0;
- getDataBaseName(list.get(0));
- try {
- for (Object entity : list) {
- getEntityManager().persist(entity);
- i++;
- if (i % batchSize == 0) {
- getEntityManager().flush();
- getEntityManager().clear();
- }
- }
- flag = true;
- } catch (Exception e) {
-
- }
- return flag;
- }
复制代码
在以上的程序中,每次执行 session.flush() 方法,就会向数据库职工批量插入 30 条记录。接下来 session.clear() 方法把 20 个刚保存的 对象从缓存中清空。 只要是设计有批量导入的情况,都会涉及到批量保存的内容,这篇博客就是让你的批量保存达到最优效果。
|