spring data jpa开启批量插入、批量更新

原文链接:https://www.cnblogs.com/blog5277/p/10661096.html

原文作者:博客园--曲高终和寡

*******************如果你看到这一行,说明爬虫在本人还没有发布完成的时候就抓走了我的文章,导致内容不完整,请去上述的原文链接查看原文****************

最近准备上spring全家桶写一下个人项目,该学的都学学,其中ORM框架,最早我用的是jdbcTemplate,后来用了Mybatis,唯独没有用过JPA(Hibernate)系的,过去觉得Hibernate太重量级了,后来随着springboot和spring data jpa出来之后,让我觉得好像还不错,再加上谷歌趋势。。。

只有中日韩在大规模用Mybatis(我严重怀疑是中国的外包),所以就很奇怪,虽然说中国的IT技术在慢慢抬头了,但是这社会IT发展的主导目前看来还是美国、欧洲,这里JPA、Hibernate是绝对的主流,那么我觉得学习并以JPA为主开发是我接下来个人项目的选择。

那么经过几天简单的摸索,发现JPA可以说是非常的好用,尤其DDD设计思想简直完美符合现在springboot、微服务的设计理念(仅代表个人看法)。

不过呢,在使用过程中就会遇到一个问题,我之前写的爬虫插入效率非常低,一方面是因为我服务器上Mysql表现的极差,详情请看:

[评测]低配环境下,PostgresQL和Mysql读写性能简单对比(欢迎大家提出Mysql优化意见)

另外一方面,JPA的批量插入源码:

这saveAll明明就是循环调用save方法了啊,我们写个简单的测试插入数据方法试一下:

我们打开了Hibernate显示sql日志,看一下输出结果:

看日志,JPA是先把所有的数据全查出来了,如果数据库有就更新,没有就新增。我们再看一下阿里的监控,如果没有配可以按照这个文章里面的方法配

springboot2.0配置连接池(hikari、druid)

我插了5条数据,结果执行了10次sql,这特么。。。我不太能理解,可能是我太菜了?我跑脚本至少了成千上万条数据往库里插,这种写法得给我辣鸡数据库写死。

并且这样效率也太低了吧,查询不会用in?insert不会拼sql?并且很多场景我自己能控制是插入还是新增,我根本不需要你给我校验一次,我只想安安静静的插数据,那么有没有办法呢?有的。

在配置文件里加入:

spring.jpa.properties.hibernate.jdbc.batch_size=
spring.jpa.properties.hibernate.jdbc.batch_versioned_data=true
spring.jpa.properties.hibernate.order_inserts=true
spring.jpa.properties.hibernate.order_updates =true

这个batch size建议设置成你数据库每秒最大写入数/2 ,没有理由只是我自己感觉这样好一点。。。

自己在repository里面定义两个接口 batchSave,batchUpdate并实现:

@Override
@Transactional
public <S extends T> Iterable<S> batchSave(Iterable<S> var1) {
Iterator<S> iterator = var1.iterator();
int index = 0;
while (iterator.hasNext()){
em.persist(iterator.next());
index++;
if (index % BATCH_SIZE == 0){
em.flush();
em.clear();
}
}
if (index % BATCH_SIZE != 0){
em.flush();
em.clear();
}
return var1;
}
@Override
public <S extends T> Iterable<S> batchUpdate(Iterable<S> var1) {
Iterator<S> iterator = var1.iterator();
int index = 0;
while (iterator.hasNext()){
em.merge(iterator.next());
index++;
if (index % BATCH_SIZE == 0){
em.flush();
em.clear();
}
}
if (index % BATCH_SIZE != 0){
em.flush();
em.clear();
}
return var1;
}

然后对批量插入的入口稍作改动,改成刚刚自己实现的调用batchSave的方法

我们运行一下看看结果:

这次500条用了778毫秒,跟之前5条712相差不多,但是我们大家看到了,控制台打印了500条插入语句。。。这个导致我一度以为批量插入失败了,按理说看时间是成功了呀,所以后来配置了阿里的监控一看:

放心了,是Hibernate自己日志打印有问题,所以后来我给Hibernate日志打印关掉了,专心用阿里的druid

spring data jpa开启批量插入、批量更新的更多相关文章

  1. 在Spring Data JPA 中使用Update Query更新实体类

    对于 Spring Data JPA 使用的时间不长,只有两年时间.但是踩过坑的却不少. 使用下列代码 @Modifying @Query("update User u set u.firs ...

  2. spring data jpa、Hibernate开启全球唯一UUID设置

    spring data jpa.Hibernate开启全球唯一UUID设置 原文链接:https://www.cnblogs.com/blog5277/p/10662079.html 原文作者:博客园 ...

  3. java批量插入或更新的问题

    在批量插入或者更新中,setXXX的时候字段类型必须一致.例如:在普通sql中 pstmt8.setBigDecimal(j ,xxx);可以写成pstmt8.setString(j,xxx.toSt ...

  4. C#使用SqlDataAdapter 实现数据的批量插入和更新

    近日由于项目要求在需要实现中型数据的批量插入和更新,晚上无聊,在网上看到看到这样的一个实现方法,特摘抄过来,以便以后可能用到参考. 一.数据的插入 DateTime begin = DateTime. ...

  5. mybatis 注解的方式批量插入,更新数据

    一,当向数据表中插入一条数据时,一般先检查该数据是否已经存在,如果存在更新,不存在则新增  使用关键字  ON DUPLICATE KEY UPDATE zk_device_id为主键 model  ...

  6. 关于Spring Data JPA更新部分字段的问题

    1.问题背景 个人比较喜欢Spring data JPA,这次的问题是在实体类中使用List类型作为字段,JPA也提供了操作的方法,即使用@ElementCollection注解,网上对于JPA的知识 ...

  7. mybatis中批量插入以及更新

    1:批量插入 批量插入就是在预编译的时候,将代码进行拼接,然后在数据库执行 <insert id="batchInsert" parameterType="java ...

  8. MySQL on duplicate key update 批量插入并更新已存在数据

    业务上经常存在一种现象,需要批量往表中插入多条数据,但在执行过程中,很可能因为唯一键冲突,而导致批量插入失败.因此需要事先判断哪些数据是重复的,哪些是新增的.比较常用的处理方法就是找出已存在的数据,并 ...

  9. spring data jpa使用 (转:http://www.manongjc.com/article/25284.html#four_1_7)

    Jap相关的使用 时间:2018-12-18 本文章向大家介绍Jap相关的使用,主要包括Jap相关的使用使用实例.应用技巧.基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下. ...

随机推荐

  1. 【Python】This inspection detects names that should resolve but don't. Due to dynamic dispatch and duck

    情况一:导包import时发生错误,请参考这两位 https://blog.csdn.net/zhangyu4863/article/details/80212068https://www.cnblo ...

  2. CarbonData-2:core

    package Core是carbondata的核心代码. 照例,先看Test类.CarbonPropertiesValidationTest

  3. ajax请求网络api

    不啰嗦,直接上代码: 1.在浏览器输入网址:http://api.asilu.com/weather/?callback=getname&city=深圳 你会看到如下结果:他返回的是json数 ...

  4. Mysql 聚合函数返回NULL

    [1]聚合函数返回NULL 当where条件不满足时,聚合函数sum().avg()的返回值为NULL. (1)源数据表 (2)如下SQL语句 SELECT sClass, COUNT(*) AS t ...

  5. redis-使用问题

    记录一下相关的问题,使用参考http://www.runoob.com/redis/ 1.DENIED Redis is running in protected mode 这个是启用了保护模式,这个 ...

  6. 三分钟了解Go语言的前世今生

    一. 为什么需要一个新的语言最近十年来,C/C++在计算领域没有很好得到发展,并没有新的系统编程语言出现.对开发程度和系统效率在很多情况下不能兼得.要么执行效率高,但低效的开发和编译,如C++:要么执 ...

  7. 介绍Kubernetes监控Heapster

    什么是Heapster? Heapster是容器集群监控和性能分析工具,天然的支持Kubernetes和CoreOS,Kubernetes有个出名的监控agent—cAdvisor.在每个kubern ...

  8. MySQL 压缩文件安装遇到的问题及解决方案

    第一步:从官网下载压缩文件(链接). 第二步:解压该文件,放置到想放到的位置.我的目录是在 C:\mysql\mysql-8.0.12-winx64 下. 第三步:在C:\mysql\mysql-8. ...

  9. Sql Server语句大全

    T-SQL语句大全 --跳转到SQL myDemo USE [SQL myDemo] go --声明变量id declare @id int --为变量赋值:直接赋值 --将cid为3的cname值赋 ...

  10. iOS进阶之TCP代理鉴权过程

    这段时间接触了网络代理,而自己的任务是完成TCP和UDP的网络代理,所以在这里写些自己的理解吧. 这篇文章先介绍一下TCP代理的鉴权过程(采用的是用户名和密码鉴权),下一篇文章再介绍UDP代理的鉴权过 ...