首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Java进行批量插入的最佳方法是什么?

问使用Java进行批量插入的最佳方法是什么?
EN

Stack Overflow用户
提问于 2013-07-21 14:02:51
回答 1查看 1.1K关注 0票数 1

我正在尝试开发一个应用程序,它可以在数据库中保存很多结构化对象。现在,我正在使用Spring (使用hibernate + MySQL (MyIsam表+外键))编写代码,使用Spring数据存储库为数据服务编写代码很容易,但性能太慢。

例如,我试图在一个表中插入100条记录,耗时8,5秒。

我尝试在MySQL cmd中直接执行相同的插入操作(在一个过程中使用硬编码的“插入字符串”),它显示了时间- 0,85秒。即使这样的结果对我来说也太慢了,但这是MySQL的问题。

阅读论坛,我发现了帖子,它说Spring不能正确地执行批量插入。

我如何使我的应用程序更快?我希望使用大小类似于1000或1000以上的批量插入操作。

情况很复杂,因为我不能将对象存储到一个大容量中(尽管批量的大小)。

为了使它更清楚:

objectGame包含objectRound列表,objectGame也包含objectGamePlayer列表,objectRound包含objectRoundCard列表,objectGamePlayer包含objectPlayerCard列表,objectGamePlayer也包含objectPlayerBet列表

当然,要插入一个objectGame,它需要执行几个步骤:插入大量的objectGame并获取它们具有对象游戏Ids的Ids,插入大部分objectRound并获取它们的Ids .诸若此类

哪条路更适合我?

使用Spring,jdbc,hibernate,myBatis?或者另一种方式?

EN

回答 1

Stack Overflow用户

发布于 2021-06-03 13:11:52

您是对的,Spring默认情况下不会以一种高效的方式进行批量插入。当我们想要将25000多个对象批量写入一个表时,我们就遇到了这个问题,我们需要编写8个这样的表。我们是怎么做到的。

默认情况下,Spring会将对象提取到EntityManager的缓存中,然后比较并决定是调用persist还是merge。我绕过了这个逻辑,因为我根据版本知道我是想坚持还是合并。诀窍是基于if (entity.getVersion() == 0) {来确定

代码语言:javascript
复制
public List<T> update(Collection<T> entities) {
        List<T> ret =  new ArrayList<>();
        EntityManager em = getEntityManager();
        for (T entity : entities) {
            if (entity.getVersion() == 0) {
                em.persist(entity);
                ret.add(entity);
            } else {
                ret.add(em.merge(entity));
            }
        }
        return ret;
    }

您需要EntityManager的句柄,您可以通过创建自己的SimpleJpaRepository实现来获得它,只需扩展SimpleJpaRepository类即可。

代码语言:javascript
复制
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.support.JpaEntityInformation;

public class MyJpaRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements JpaRepository<T, ID>, JpaSpecificationExecutor<T> {

    private EntityManager entityManager;

    public MyJpaRepositoryImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {
        super(entityInformation, entityManager);
        
        // Keep the EntityManager around to used from the newly introduced methods.
        this.entityManager = entityManager;
    }

    public EntityManager getEntityManager() {
        return entityManager;
    }
}

在应用程序的SpringConfig上添加下面的烦恼来实例化回购实现,而不是使用@EnableJpaRepositories(basePackages = "..." , repositoryBaseClass = MyJpaRepositoryImpl.class)来实例化默认的SimpleJpaRepository

代码语言:javascript
复制
@Configuration
@EnableJpaRepositories(basePackages = "au.com.xyz.infrastructure.repositories" , repositoryBaseClass = MyJpaRepositoryImpl.class)
@ComponentScan(basePackages = {"au.com.xyz.infrastructure.repositories.plugin", "au.com.xyz.infrastructure.repositories.external", ...})

public class InfrastructureSpringConfig {
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17773144

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档