You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于已有Product ArrayList实现Spring Batch结合JPA/Hibernate批量保存

Spring Batch 处理内存中ArrayList并通过JPA批量保存

核心思路

跳过文件读取环节,直接用Spring Batch提供的ListItemReader读取内存中的ArrayList<Product>,配合JpaItemWriter完成批量持久化,中间可按需添加自定义处理器做数据校验/转换。

依赖准备

确保项目依赖包含Spring Batch和Spring Data JPA(以Maven为例):

<dependencies>
    <!-- Spring Batch 核心依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-batch</artifactId>
    </dependency>
    <!-- Spring Data JPA -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <!-- 数据库驱动,根据实际使用的数据库替换 -->
    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
        <scope>runtime</scope>
    </dependency>
</dependencies>

1. Product实体类示例

假设你已有如下实体类(适配JPA规范):

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.Data;

@Entity
@Data
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private Double price;
    // 其他业务字段及getter/setter(Lombok @Data可自动生成)
}

2. 配置自定义ItemReader

用Spring Batch内置的ListItemReader直接读取内存列表,无需自定义Reader实现:

import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.support.ListItemReader;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.List;

@Configuration
public class BatchConfig {

    // 替换为你实际的Product集合,可从业务层注入或动态获取
    private List<Product> getExistingProductList() {
        List<Product> products = new ArrayList<>();
        products.add(new Product(null, "无线耳机", 399.0));
        products.add(new Product(null, "智能手表", 1299.0));
        return products;
    }

    @Bean
    public ItemReader<Product> productItemReader() {
        return new ListItemReader<>(getExistingProductList());
    }
}

如果集合是动态生成的(比如从接口或数据库查询),可通过StepExecutionListener在步骤启动时加载数据,避免硬编码。

3. 可选:自定义数据处理器

如需对数据做校验、转换,实现ItemProcessor:

import org.springframework.batch.item.ItemProcessor;

public class ProductItemProcessor implements ItemProcessor<Product, Product> {
    @Override
    public Product process(Product product) throws Exception {
        // 示例:校正非法价格
        if (product.getPrice() < 0) {
            product.setPrice(0.0);
        }
        // 可添加补全默认值、格式转换等逻辑
        return product;
    }
}

在配置类中注册处理器Bean:

@Bean
public ItemProcessor<Product, Product> productItemProcessor() {
    return new ProductItemProcessor();
}

4. 配置JpaItemWriter实现批量保存

使用Spring Batch提供的JpaItemWriter,直接对接JPA完成批量持久化:

import org.springframework.batch.item.database.JpaItemWriter;
import jakarta.persistence.EntityManagerFactory;
import org.springframework.context.annotation.Bean;

@Bean
public JpaItemWriter<Product> productJpaItemWriter(EntityManagerFactory entityManagerFactory) {
    JpaItemWriter<Product> writer = new JpaItemWriter<>();
    writer.setEntityManagerFactory(entityManagerFactory);
    return writer;
}

5. 组装Job和Step

将Reader、Processor(可选)、Writer组合成Step,再构建Job:

import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.job.builder.JobBuilder;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.transaction.PlatformTransactionManager;

@EnableBatchProcessing
@Configuration
public class BatchConfig {
    // 上述Reader、Processor、Writer Bean...

    @Bean
    public Step productBatchStep(JobRepository jobRepository,
                                PlatformTransactionManager transactionManager,
                                ItemReader<Product> productItemReader,
                                ItemProcessor<Product, Product> productItemProcessor,
                                JpaItemWriter<Product> productJpaItemWriter) {
        return new StepBuilder("productBatchStep", jobRepository)
                .<Product, Product>chunk(100) // 每100条提交一次事务,根据数据库性能调整
                .reader(productItemReader)
                .processor(productItemProcessor) // 无需处理器可删除此行
                .writer(productJpaItemWriter)
                .transactionManager(transactionManager)
                .build();
    }

    @Bean
    public Job productBatchJob(JobRepository jobRepository, Step productBatchStep) {
        return new JobBuilder("productBatchJob", jobRepository)
                .start(productBatchStep)
                .build();
    }
}

6. 启动Batch Job

通过CommandLineRunner在项目启动时自动执行,或通过Controller/定时任务触发:

import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class BatchJobStarter implements CommandLineRunner {

    private final JobLauncher jobLauncher;
    private final Job productBatchJob;

    public BatchJobStarter(JobLauncher jobLauncher, Job productBatchJob) {
        this.jobLauncher = jobLauncher;
        this.productBatchJob = productBatchJob;
    }

    @Override
    public void run(String... args) throws Exception {
        JobParameters jobParameters = new JobParametersBuilder()
                .addLong("executeTime", System.currentTimeMillis()) // 确保每次Job参数唯一,避免重复执行
                .toJobParameters();
        jobLauncher.run(productBatchJob, jobParameters);
    }
}

关键优化配置

在application.properties中添加Hibernate批量操作配置,提升插入性能:

# Hibernate批量插入配置
spring.jpa.properties.hibernate.jdbc.batch_size=100
spring.jpa.properties.hibernate.order_inserts=true
spring.jpa.properties.hibernate.order_updates=true

内容的提问来源于stack exchange,提问作者Vishvajeet w

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 18:15:11