Spring 批处理:在实体中设置实体

Spring Batch: Set entity within an entity

我有一个实体 用户,它有另一个实体作为部门。

@Entity
@Getter
@Setter
public class User {
    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private Integer id;
    private String name;
    private Integer salary;

    @ManyToOne
    private Department department;
}

还有一个实体部门

@Entity
@Getter
@Setter
public class Department {

    public Department(String departmentName){
        this.name = departmentName;
    }

    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private Integer id;

    private String name;
}

处理器 class

@Component
public class Processor implements ItemProcessor<User, User> {

    @Override
    public User process(User item) throws Exception {
        return item;
    }
}

作家class

@Component
@Slf4j
public class DBWriter implements ItemWriter<User> {
    private final UserRepository userRepository;

    @Autowired
    public DBWriter(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Override
    public void write(List<? extends User> users) throws Exception {
        log.info("Inserting value of user with data size: {}", users.size());
        userRepository.saveAll(users);
    }
}

还有我的SpringBatchConfigclass

@Configuration
@EnableBatchProcessing
public class SpringBatchConfig {


    private final DepartmentRepository departmentRepository;

    public SpringBatchConfig(DepartmentRepository departmentRepository) {
        this.departmentRepository = departmentRepository;
    }

    @Bean
    public Job job(JobBuilderFactory jobBuilderFactory,
                   StepBuilderFactory stepBuilderFactory,
                   ItemReader<User> reader,
                   ItemProcessor<User, User> process,
                   ItemWriter<User> writer
    ) {
        Step step = stepBuilderFactory.get("user-insertion")
                .<User, User>chunk(100000)
                .reader(reader)
                .processor(process)
                .writer(writer)
                .build();

        return jobBuilderFactory.get("user-insertion")
                .incrementer(new RunIdIncrementer())
                .start(step)
                .build();
    }

    @Bean
    public FlatFileItemReader<User> itemReader() {
        FlatFileItemReader<User> flatFileItemReader = new FlatFileItemReader<>();
        flatFileItemReader.setResource(new FileSystemResource("src/main/resources/users.csv"));
        flatFileItemReader.setName("CSV-Reader");
        flatFileItemReader.setLinesToSkip(1);
        flatFileItemReader.setLineMapper(getLineMapper());
        Department department = departmentRepository.save(new Department("Development"));
        return flatFileItemReader;
    }

    @Bean
    public LineMapper<User> getLineMapper() {
        DefaultLineMapper<User> defaultLineMapper = new DefaultLineMapper<>();

        DelimitedLineTokenizer lineTokenizer = new DelimitedLineTokenizer();
        lineTokenizer.setDelimiter(",");
        lineTokenizer.setStrict(false);
        lineTokenizer.setNames("name", "department", "salary");

        BeanWrapperFieldSetMapper<User> fieldSetMapper = new BeanWrapperFieldSetMapper<>();
        fieldSetMapper.setTargetType(User.class);

        defaultLineMapper.setLineTokenizer(lineTokenizer);
        defaultLineMapper.setFieldSetMapper(fieldSetMapper);

        return defaultLineMapper;
    }
}

我无法在批量插入时将部门分配给用户。假设可以将单个部门分配给当前的用户列表。

如何在用户中插入部门?

您正在 reader 的 bean 定义方法中执行写入操作:

Department department = departmentRepository.save(new Department("Development"));

这是不正确的。不希望在 Spring bean 定义方法中编写这样的代码。

您需要做的是让您的 reader 读取 User 个实例并在每个实例上设置部门。然后你的作者会保存用户和它的部门。如果您的 JPA 映射正确,UserRepository 应该已经这样做了。