hibernate 批量插入数据
如题,有两种方法
1)使用FLUSH
2)使用JDBC
分别来解释:
1)hibernate在进行数据库操作的时候,都要有事务支持的。可能你曾遇到过,没有加事务,程序会报错的情况。
而事务每次提交的时候,都会和数据库交互,即让数据库执行SQL语句。
在说到hibernate中的save() 或者saveOrUpdate()方法,其实,它们都是利用hibernate的一级缓存,在事务没有提交的时候,所有对象,并没有写入数据库。而是保存在内存中。在事务提交的时候,hibernate会把这些对象持久化到数据库中。另一方面,hibernate提供了一个显式的API来强制写数据库。就是FLUSH。当程序执行session.flush(),就会持久化数据,而不必等到事务提交时才执行。
本人写了一个DEMO,一个线程产生USER,一个保存USER。
生产者代码如下:
package com.baidu.test;import java.util.ArrayList; import java.util.Collections; import java.util.List;import com.baidu.model.User;public class test extends Thread {public static int count = 0;public static List<User> userlist = Collections.synchronizedList(new ArrayList()); public User user;public static void main(String[] args) {new test().start();new HandleThread().start();}public static int usercount=0;@Overridepublic void run() {while (true) {try {Thread.sleep(2000);} catch (InterruptedException e) {// TODO Auto-generated catch block e.printStackTrace();}User t = new User();t.setId(usercount);t.setUsername("name_" + usercount);userlist.add(t);System.out.println("生产出一个user_"+usercount);usercount++;}}}
消费者代码如下:
package com.baidu.test;import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration;import com.baidu.model.User;public class HandleThread extends Thread {@Overridepublic void run() {boolean flag=false;Configuration config = new Configuration();config.configure();SessionFactory factory = config.buildSessionFactory();Session session = factory.openSession();while (true) {if (test.userlist.size() > 0) {for (int i = 0; i < test.userlist.size(); i++) {System.out.println("处理了"+ test.userlist.get(i).getId());insert(test.userlist.get(i),session);}test.userlist.clear();}try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}if(flag)break;}session.close();}public void insert(User user,Session session) {Transaction tran = session.beginTransaction();session.save(user);if (test.count++ % 10 == 0) {System.out.println(test.count);session.flush();session.clear();}tran.commit();}}
if (test.count++ % 10 == 0) {System.out.println(test.count);session.flush();session.clear();}这段代码就是执行批量操作的核心。当然这个需要在hibernate配置文件中配置下 <property name="hibernate.jdbc.batch_size">10</property>这个值,从网上得到的说法是一次推送SQL语句的条数。暂且相信了,后续我将验证(通过抓包)。 至此,第一种批量处理已经完成。 2) to be continue... Hibernate批量处理其实从性能上考虑,它是很不可取的,浪费了很大的内存。从它的机制上讲,Hibernate它是先把符合条件的数据查出来,放到内存当中,然后再进行操作。实际使用下来性能非常不理想,在笔者的实际 使用中采用下面的第三种优化方案的数据是:100000条数据插入数据库,主流台式机的配置,需要约30分钟,呵呵,晕倒. 总结下来有三种来处理以解决性能问题: 1:绕过Hibernate API ,直接通过 JDBC API 来做,这个方法性能上是比较好的。也是最快的. 2:运用存储过程。 3:还是用Hibernate API 来进行常规的批量处理,可以也有变,变就变在,我们可以在查找出一定的量的时候,及时的将这些数据做完操作就 删掉,session.flush();session.evict(XX对象集); 这样也可以挽救一点性能损失。这个“一定的量”要就要根据实际情况做定量参考了。一般为30-60左右,但效果仍然不理想. 1:绕过Hibernate API ,直接通过 JDBC API 来做,这个方法性能上是比较好的,也是最快的。(实例为 更新操作) Transaction tx=session.beginTransaction(); //注意用的是hibernate事务处理边界 Connection conn=session.connection(); PreparedStatement stmt=conn.preparedStatement("update CUSTOMER as C set C.sarlary=c.sarlary+1 where c.sarlary>1000"); stmt.excuteUpdate(); tx.commit(); //注意用的是hibernate事务处理边界 这小程序中,采用的是直接调用JDBC 的API 来访问数据库,效率很高。避免了Hibernate 先查询出来加载到内存,再进行操作引发的性能问题 。 2:运用存储过程。但这种方式考虑到易植和程序部署的方便性,不建议使用.(实例为 更新操作) 如果底层数据库(如Oracle)支持存储过程,也可以通过存储过程来执行批量更新。存储过程直接在数据库中运行,速度更加快。在Oracle数 据库中可以定义一个名为batchUpdateCustomer()的存储过程,代码如下: 代码内容 create or replace procedure batchUpdateCustomer(p_age in number) as begin update CUSTOMERS set AGE=AGE+1 where AGE>p_age; end; 以上存储过程有一个参数p_age,代表客户的年龄,应用程序可按照以下方式调用存储过程: 代码内容 tx = session.beginTransaction(); Connection con=session.connection(); String procedure = "{call batchUpdateCustomer(?) }"; CallableStatement cstmt = con.prepareCall(procedure); cstmt.setInt(1,0); //把年龄参数设为0 cstmt.executeUpdate(); tx.commit(); 从上面程序看出,应用程序也必须绕过Hibernate API,直接通过JDBC API来调用存储过程。 3:还是用Hibernate API 来进行常规的批量处理,可以也有变,变就变在,我们可以在查找出一定的量的时候,及时的将这些数据做完操作就 删掉,session.flush();session.evict(XX对象集); 这样也可以挽救一点性能损失。这个“一定的量”要就要根据实际情况做定量参考了。。 (实例为 保存操作) 业务逻辑为:我们要想数据库插入10 0000 条数据 tx=session.beginTransaction(); for(int i=0;i<100000;i++) { Customer custom=new Customer(); custom.setName("user"+i); session.save(custom); if(i%50==0) // 以每50个数据作为一个处理单元,也就是我上面说的“一定的量”,这个量是要酌情考虑的 { session.flush(); session.clear(); } } 这样可以把系统维持在一个稳定的范围....
转载于:https://www.cnblogs.com/shenghaishiweini/p/3865901.html
hibernate 批量插入数据相关推荐
- python加数据库_用python批量插入数据到数据库中
既然使用python操作数据库必不可少的得使用pymysql模块 可使用两种方式进行下载安装: 1.使用pip方式下载安装 pip install pymysql 2.IDE方式 安装完成后就可以正常 ...
- 批量插入数据库语句java_java相关:MyBatis批量插入数据到Oracle数据库中的两种方式(实例代码)...
java相关:MyBatis批量插入数据到Oracle数据库中的两种方式(实例代码) 发布于 2020-7-22| 复制链接 本文通过实例代码给大家分享了MyBatis批量插入数据到Oracle数据库 ...
- oracle insert汉字出错,Oracle数据库之Oracle批量插入数据SQL语句太长出错:无效的主机/绑定变量名...
本文主要向大家介绍了Oracle数据库之Oracle批量插入数据SQL语句太长出错:无效的主机/绑定变量名,通过具体的内容向大家展现,希望对大家学习Oracle数据库有所帮助. Oracle数据库,用 ...
- linux批量es数据,Elasticsearch批量插入数据
Elasticsearch批量插入数据 使用bulk批量操作数据库 1. 创建批量操作文件 格式: {"index":{"_index":"home& ...
- android SQLite 批量插入数据慢的解决方案 (针对于不同的android api 版本)
android SQLite 批量插入数据慢的解决方案 (针对于不同的android api 版本) 参考文章: (1)android SQLite 批量插入数据慢的解决方案 (针对于不同的andro ...
- php addall,ThinkPHP3.2框架使用addAll()批量插入数据的方法
这篇文章主要介绍了ThinkPHP3.2框架使用addAll()批量插入数据的方法,结合实例形式分析了thinkPHP针对单条数据插入及批量数据插入操作的相关实现技巧,需要的朋友可以参考下 本文实例讲 ...
- .NET Excel 2003 批量插入数据很慢的解决办法
.Net利用Office组件的操作Excel批量插入数据据的时候,会非常慢. 我也曾经想利用其它组件来实现这个功能,但是效果不是很理想.后来经过查阅资料,发现Excel.Range的Value属性是O ...
- bulk_create 批量插入数据
def booklist(request):# 动态插入100条数据for i in range(100):models.Book2.objects.create(name='第%s本书'%i)#批量 ...
- shell批量插入数据
用shell脚本批量插入数据,很简单.直接看代码: #! /bin/bashhost="xxx" port="xxx" userName="xxx&q ...
- MySQL批量插入数据的几种方法
最近公司要求测试数据库的性能,就上网查了一些批量插入数据的代码,发现有好几种不同的用法,插入同样数据的耗时也有区别 别的先不说,先上一段代码与君共享 方法一: package com.bigdata; ...
最新文章
- 关于USART接收中断的BUG和注意事项
- Linux 7 cmake:curses library not found
- mybatis select count(*) 一直返回0 mysql_Mybatis教程1:MyBatis快速入门
- 【渝粤题库】陕西师范大学100101美学概论作业(高起本)
- 人工智能常用 API
- 阿里云助力1药网开辟疫情防控“第二战场”
- 1000行MySQL学习笔记,收藏版!
- java设计app_一个APP的诞生——从零开始设计你的手机应用
- 太仓爱尚你婚庆--太仓浪漫婚庆第一品牌
- kafka的push与poll
- SPSS调节效应检验(图文+数据集)【SPSS 045期】
- libvlc.java_java – LibVlc android无法加载库
- 港大HKU邮箱(connect.hku.hk)添加至iphone 自带邮箱方法
- Trading Convexity for Scalability
- 计算机没网络怎么更新网卡驱动,电脑网卡驱动更新 怎么更新网卡驱动(图文)...
- 前端例程20210731:圆形表盘时钟布局实现
- 三种数据库的 SQL 注入详解
- angular2+ 常用链接
- CentOS6 64bit系统一键快速安装VNC桌面实现Linux桌面
- 3000亿紫光集团破产重整,原因是啥?
热门文章
- Equal-size partition problem
- 图论 有向无环图 拓扑排序 是什么
- kubernetes PVC介绍
- python if 比较小数浮点数
- 计网实验1--配置路由
- python使用密钥加密的表述_Python生成rsa密钥对操作示例
- java单链表上的选择排序_《Java数据结构和算法》简单排序选择排序
- 基于springboot+vue的学生选课系统(前后端分离)
- Unity3D(二)游戏对象及组件
- 凌阳单片机c语言延时函数,凌阳单片机C语言(网站整理).doc