JPA中以HibernatePersistence为provider的批量插入问题
为什么要批量插入
要插入10000条数据,如果不批量插入的话,那么我们执行的sql语句将是10000条insert
insert into member (group_id, user_id, role, extend) values (101, 100, 3, NULL)
insert into member (group_id, user_id, role, extend) values (101, 101, 3, NULL)
insert into member (group_id, user_id, role, extend) values (101, 102, 3, NULL)
insert into member (group_id, user_id, role, extend) values (101, 103, 3, NULL)
......
如果是批量插入,一批次插入50条,那么10000条数据将生成200条insert语句
insert into member (group_id, user_id, role, extend) VALUES (101, 100, 3, NULL), (101, 101, 3, NULL), ..., (101, 149, 3, NULL)
insert into member (group_id, user_id, role, extend) VALUES (101, 100, 3, NULL), (101, 101, 3, NULL), ..., (101, 149, 3, NULL)
好了,以上是jdbc级别的批量插入,换言之,我们需要JPA提供批量插入功能
JPA批量插入
搜索了Stackoverflow,似乎JPA本身并没有对批量插入的支持
http://stackoverflow.com/questions/7440397/how-to-do-the-batch-insert-in-jpa
Hibernate批量插入
因为使用Hibernate作为JPA的provider实现,因此我们可以使用Hibernate提供的批量插入功能
查阅hibernate文档
http://docs.jboss.org/hibernate/core/3.3/reference/en/html/batch.html
(1) 首先要在hibernate配置文件中配置属性
<property name="hibernate.jdbc.batch_size" value="20" /> <!-- value文档建议在10-50间 -->
(2) 批量插入代码示例
for ( int i=0; i<100000; i++ ) {
Customer customer = new Customer(.....);
session.save(customer);
if ( i % 20 == 0 ) { //20, same as the JDBC batch size
//flush a batch of inserts and release memory:
session.flush();
session.clear();
}
}
注意
如果批量插入的实体主键为@GeneratedValue(strategy=IDENTITY)类型,则hibernate会透明关闭在jdbc级别的批量插入;因为实际上,每次插入该实体的一个实例,hibernate都需要搜索该实例的主键;想想在代码中,我们persist实例之后,就能够通过get方法获取实例的主键;
实验结果也说明了这点
实体定义
@Entity
@Table (name="member")
public class GroupUser {
@Id
@GeneratedValue(strategy=IDENTITY)
@Column(name="id", nullable=true, unique=true)
private Integer id; ...... }
实验代码
Session session = (Session)em.getDelegate();
session.setFlushMode(FlushMode.MANUAL); for (int i = 0; i < userIds.size(); ++i) {
session.save(new GroupUser(groupId, userIds.get(i), role));
if (i % 20 == 0) {
session.flush();
session.clear();
}
}
日志输出
Hibernate: insert into member (group_id, user_id, role, extend) values (?, ?, ?, ?)
Hibernate: insert into member (group_id, user_id, role, extend) values (?, ?, ?, ?)
Hibernate: insert into member (group_id, user_id, role, extend) values (?, ?, ?, ?)
Hibernate: insert into member (group_id, user_id, role, extend) values (?, ?, ?, ?)
......
JPA中以HibernatePersistence为provider的批量插入问题的更多相关文章
- sql 中的Bulk和C# 中的SqlBulkCopy批量插入数据 ( 回顾 and 粗谈 )
通常,我们会对于一个文本文件数据导入到数据库中,不多说,上代码. 首先,表结构如下. 其次,在我当前D盘中有个文本文件名为2.txt的文件. 在数据库中,可以这样通过一句代码插入. Bulk in ...
- 多线程查询数据,将结果存入到redis中,最后批量从redis中取数据批量插入数据库中【我】
多线程查询数据,将结果存入到redis中,最后批量从redis中取数据批量插入数据库中 package com.xxx.xx.reve.service; import java.util.ArrayL ...
- C#中的SqlBulkCopy批量插入数据
在C#中,我们可以使用sqlBulkCopy去批量插入数据,其他批量插入方法不在讨论. 1 /// <summary> 2 /// SqlBulkCopy批量插入数据 3 /// < ...
- 使用事务操作SQLite数据批量插入,提高数据批量写入速度,源码讲解
SQLite数据库作为一般单机版软件的数据库,是非常优秀的,我目前单机版的软件产品线基本上全部替换Access作为优选的数据库了,在开发过程中,有时候需要批量写入数据的情况,发现传统的插入数据模式非常 ...
- 【sqlserver】批量插入10万数据
DECLARE @LN VARCHAR(300),@MN VARCHAR(200),@FN VARCHAR(200)DECLARE @LN_N INT,@MN_N INT,@FN_N INTSET @ ...
- 寻找 IBatisNet 批量插入(批量复制) 的心路历程
1.IBatisNet本身就是一个比较早的ORM框架,再加上是从java iBatis移值过来的,其流行程度不是特别高资料也不是很多(一年前),不过最近好像搜索比较多了一些(可能是训练的结果吧) 2. ...
- asp.net Ibatis.net 批量插入数据ORACLE
在开发中我们有时会遇到需要批量插入数据,最普通的就是每次 插入一条.但是当数据量大道一定的地步会很影响性能.下面例子示范了ibatis.net批量插入 ibatis.net 的XML文件里面使用ite ...
- Mybatis批量插入,是否能够返回id列表
第1次代码 void batchAdd(List<Photo> list); <insert id="batchAdd" parameterType=" ...
- mybatis的插入与批量插入的返回ID的原理
目录 背景 底层调用方法 单个对象插入 列表批量插入 完成 背景 最近正在整理之前基于mybatis的半ORM框架.原本的框架底层类ORM操作是通过StringBuilder的append拼接的,这次 ...
随机推荐
- strcpy完整版 与 strcpy为什么有返回值
一个标准的strcpy函数: 原本以为自己对strcpy还算比较了解,结果面试时还是悲剧了. 下面给出网上strcpy的得分版本: 2分 void strcpy( char *strDest, cha ...
- PCanywhere/teamviewer/RDP/ultraVNC/tigerVNC/realVNC/Xmanager
PCanywhere/teamviewer/RDP/ultraVNC/tigerVNC/realVNC/Xmanager 1, 通常应用场景一般CentOS/RHEL等linux系统不配置安装Desk ...
- maven 命令小记
mvn help:system mvn clean compile mvn clean test 测试 mvn clean package ...
- h5新特性
!DOCTYPE html><html> <head> <meta charset="utf-8"> <title></ ...
- HybridApp开发准备工作——WebView
如大家所见,手机真是越来越离不开我们的日常生活了,像我,现在出门必带的是手机.移动电源.公交卡:钱包什么的再也没出过门.两年前,我还在Android的应用开发中当了一次过客.嗯,当时JAVA学得太糟糕 ...
- java关键字-transient
java语言的关键字,变量修饰符,如果用transient声明一个实例变量,当对象存储时,它的值不需要维持. Java的serialization提供了一种持久化对象实例的机制.当持久化对象时,可能有 ...
- js中setTimeout/setInterval定时器用法示例
js中setTimeout(定时执行一次)和setInterval(间隔循环执行)用法介绍. setTimeout:在指定的毫秒数后调用指定的代码段或函数:setTimeout示例代码 functio ...
- jquery源码阅读笔记一
1. jquery无new的构造函数. 无new的构造函数是怎么实现的.比如我们一般这么用jQuery. $(".test").text(); 但是我们一般是这么写的. var t ...
- Android中的创建型模式总结
共5种,单例模式.工厂方法模式.抽象工厂模式.建造者模式.原型模式 单例模式 定义:确保某一个类的实例只有一个,而且向其他类提供这个实例. 单例模式的使用场景:某个类的创建需要消耗大量资源,new一个 ...
- AIX-df命令
df 命令显示文件系统的总空间和可用空间信息.FileSystem 参数指定文件系统驻留的设备的名称,文件系统的安装目录或文件系统的相对路径名.File 参数指定非安装点的文件或目录.如果指定 Fil ...