使用hibernate在5秒内插入11万条数据,你觉得可能吗?

本文介绍了一种通过直接使用SQL语句实现数据从一个表到另一个结构不同表的快速迁移方法,对比使用Hibernate逐条处理数据的方式,这种方法仅需5秒即可完成11万条数据的迁移,极大地提高了效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求是这样的,需要查询某几个表的数据,然后插入到另外一个表。

一看到需求,很多人都会用hibernate去把这些数据都查询出来,然后放到list中,

然后再用for循环之类的进行遍历,一条一条的取出数据对对象进行赋值,然后在调用dao层的save 方法进行保存对象。

hibernate保存一条数据是在35毫秒左右,咱们来计算下时间:

35*110000=3850000 毫秒

3850000/1000=3850秒

3850/60=64.1666666分钟,

如果咱们使用hibernate的话,那么要执行一个多小时,这根本就无法体现出效率了,而且这么大的数据,服务器的压力也不小。

好啦,上面说了这么多,咱们来看看实际的操作。

测试的数据库是MSSQL,MYSQL速度也是差不多的


我建立了一个表,表里有115546条数据。11万


然后我又建了了一个表,两个表结构完全不同。


我这里是直接使用sql语句进行数据插入,看代码:

insert into test(name) select s.address from Student s

使用了insert into select 语句,其实也就是相当于复制而已。

这时候,咱们就可以用hibernate来创建查询,执行改条sql语句了

这样的效率非常的高,我插入11万条数据,只用了5秒钟。而上面的方法却用时超过1个小时。

截图:




<think>嗯,用户想要用Hibernate框架插入数据并且避免重复。首先,我需要考虑Hibernate的批量插入机制。记得Hibernate的Session可能会缓存大量对象导致内存问题,所以需要设置合适的批处理大小,比如hibernate.jdbc.batch_size属性。这样可以通过批量操作减少数据库往返次数,提高效率[^1]。 然后,避免重复数据的问题。用户可能希望根据某些唯一性约束来确保数据不重复。比如在数据库层面设置唯一索引,或者在插入前先查询是否存在重复记录。不过,先查询再插入的话,如果数据量很大可能会影响性能。这时候可以用数据库的唯一约束,结合Hibernate的异常处理机制,捕捉ConstraintViolationException,然后进行相应的处理,比如跳过重复记录或者更新现有数据。 另外,使用Hibernate的merge()方法可能会有帮助,因为它会检查数据库中是否存在相同的记录,如果存在就更新,不存在就插入。不过这个方法在批量处理时可能效率不高,因为每次都要检查数据库。 还有,事务的管理也很重要。应该在一个事务中执行所有的插入操作,这样一旦发生错误可以回滚,保证数据的一致性。同时,合理管理Session的刷新和清除,避免内存溢出。比如,每插入一定数量的实体后,调用session.flush()和session.clear()来清理一级缓存。 用户提到的唯一性可能涉及多个字段的组合,这时候在实体类上使用@UniqueConstraint注解来定义联合唯一约束是个好办法。例如,在@Table注解中添加uniqueConstraints属性,指定哪些字段组合需要唯一。这样数据库会自动检查,避免重复。 另外,还可以考虑使用Hibernate的@NaturalId注解来标记自然主键,这些字段组合作为唯一标识。这样在插入时,Hibernate会自动检查这些自然ID是否存在,避免重复。 不过,处理大量数据插入时,可能需要考虑使用StatelessSession,因为它不缓存对象,减少内存消耗。但StatelessSession不会触发事件监听器和拦截器,需要权衡使用。 还有,如果重复数据的情况较多,可以预先将待插入数据根据唯一键分组,去除重复项,再进行批量插入。这可以通过Java代码在内存中处理,比如使用Set集合来去重,或者使用数据库的临时表进行去重处理。 最后,性能优化方面,除了设置批处理大小,还可以关闭二级缓存和查询缓存,减少日志输出,以提高插入速度。同时,合理配置连接池参数,确保数据库连接资源充足。 总结一下,实现步骤可能是:配置Hibernate批处理参数,定义唯一约束,使用merge()方法或查询避免重复,管理事务和Session,处理异常,并进行性能优化。</think>### 使用Hibernate批量插入数据并避免重复的实现方法 #### 1. **配置Hibernate批量插入优化** Hibernate默认逐插入数据,需通过以下配置启用批量操作: ```xml <!-- hibernate.cfg.xml --> <property name="hibernate.jdbc.batch_size">50</property> <!-- 每批插入50 --> <property name="hibernate.order_inserts">true</property> <!-- 优化插入顺序 --> <property name="hibernate.order_updates">true</property> ``` 此配置通过减少与数据库的交互次数提升性能[^1]。 --- #### 2. **定义唯一性约束** 在数据库表或实体类中明确唯一性规则: ```java @Entity @Table( name = "my_entity", uniqueConstraints = @UniqueConstraint( columnNames = {"field1", "field2"} // 联合唯一约束 ) ) public class MyEntity { // 字段定义 } ``` 数据库会自动拒绝违反唯一性约束的插入操作。 --- #### 3. **使用`MERGE`操作避免重复** 通过`merge()`方法实现“存在则更新,不存在则插入”: ```java Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); for (MyEntity entity : entities) { session.merge(entity); // 自动检查唯一性 if (i % 50 == 0) { // 按批处理大小刷新 session.flush(); session.clear(); } } tx.commit(); session.close(); ``` --- #### 4. **预查询去重(适用低重复率场景)** ```java List<MyEntity> newEntities = entities.stream() .filter(e -> session.createQuery("FROM MyEntity WHERE field1=:f1 AND field2=:f2") .setParameter("f1", e.getField1()) .setParameter("f2", e.getField2()) .list().isEmpty() ).collect(Collectors.toList()); // 然后批量插入newEntities ``` --- #### 5. **异常处理** 捕获唯一性约束异常并记录: ```java try { // 批量插入代码 } catch (PersistenceException e) { if (e.getCause() instanceof ConstraintViolationException) { logger.warn("重复数据: {}", e.getMessage()); } } ``` --- #### 6. **性能优化建议** - 使用`StatelessSession`处理超大数据量(无一级缓存) - 关闭二级缓存:`hibernate.cache.use_second_level_cache=false` - 设置连接池参数(如HikariCP) --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值