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
应该已经这样做了。
我有一个实体 用户,它有另一个实体作为部门。
@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
应该已经这样做了。