如何使用 spring 批处理从 table 获取 ID 字段
How to get ID fields from table using spring batch
我正在尝试使用 spring 批处理从 table 中获取所有字段。
我得到了所有字段,除了 ID 字段(主键 e 外键)
下面是我的reader:
@Configuration
public class ReaderConfig {
@Bean
public JdbcCursorItemReader<Entity> Reader(
@Qualifier("datasource") DataSource dataSource) {
return new JdbcCursorItemReaderBuilder<Entity>()
.name("Reader")
.dataSource(dataSource)
.sql("select * from table")
.rowMapper(new BeanPropertyRowMapper<Entity>(Entity.class))
.build();
}
}
下面是我的作者:
@Configuration
public class WriterConfig {
@Bean
public ItemWriter<Entity> Writer() {
return entities-> entities.forEach(System.out::println);
}
}
其他字段成功,但ID字段如transactionId和deposit为空。
我认为有某种保护措施不允许这些字段显示其值。
有人可以帮助我吗?
您的 table 中的列名称是 ID_TRANSACTION
,但是您似乎使用 lombok 生成的 getter/setter 是 getTransactionId
/setTransactionId
,与列名不匹配。根据BeanPropertyRowMapper
的javadoc,如果列名与字段名不匹配,可以使用别名。这是 javadoc:
的摘录
To facilitate mapping between columns and fields that don't have matching names,
try using column aliases in the SQL statement like
"select fname as first_name from customer".
在您的情况下,您需要将查询更新为:
select ID_TRANSACTION as transactionId, ID_DEPOSIT as depositId, /* other fields */ from rm_transaction
这是一个简单的例子:
import javax.sql.DataSource;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.database.JdbcCursorItemReader;
import org.springframework.batch.item.database.builder.JdbcCursorItemReaderBuilder;
import org.springframework.batch.item.file.FlatFileItemWriter;
import org.springframework.batch.item.file.builder.FlatFileItemWriterBuilder;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.FileSystemResource;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
@Configuration
@EnableBatchProcessing
public class MyJobConfig {
@Bean
public JdbcCursorItemReader<Person> itemReader() {
String sql = "select person_id as id, name from person";
return new JdbcCursorItemReaderBuilder<Person>()
.name("personItemReader")
.dataSource(dataSource())
.sql(sql)
.beanRowMapper(Person.class) // equivalent to .rowMapper(new BeanPropertyRowMapper<>(Person.class))
.build();
}
@Bean
public ItemWriter<Person> itemWriter() {
return items -> items.forEach(System.out::println);
}
@Bean
public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) {
return jobs.get("job")
.start(steps.get("step")
.<Person, Person>chunk(5)
.reader(itemReader())
.writer(itemWriter())
.build())
.build();
}
public static void main(String[] args) throws Exception {
ApplicationContext context = new AnnotationConfigApplicationContext(MyJobConfig.class);
JobLauncher jobLauncher = context.getBean(JobLauncher.class);
Job job = context.getBean(Job.class);
jobLauncher.run(job, new JobParameters());
}
@Bean
public DataSource dataSource() {
EmbeddedDatabase embeddedDatabase = new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.HSQL)
.addScript("/org/springframework/batch/core/schema-hsqldb.sql")
.build();
JdbcTemplate jdbcTemplate = new JdbcTemplate(embeddedDatabase);
jdbcTemplate.execute("create table person (person_id int primary key, name varchar(20));");
for (int i = 1; i <= 10; i++) {
jdbcTemplate.execute(String.format("insert into person values (%s, 'foo%s');", i, i));
}
return embeddedDatabase;
}
static class Person {
private int id;
private String name;
public Person() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
return "Person{id=" + id + ", name='" + name + '\'' + '}';
}
}
}
这会打印:
Person{id=1, name='foo1'}
Person{id=2, name='foo2'}
Person{id=3, name='foo3'}
Person{id=4, name='foo4'}
Person{id=5, name='foo5'}
Person{id=6, name='foo6'}
Person{id=7, name='foo7'}
Person{id=8, name='foo8'}
Person{id=9, name='foo9'}
Person{id=10, name='foo10'}
如果您将 sql 查询更改为 select * from person
,您将看到 id 字段无法正确映射,因为 BeanPropertyRowMapper
找不到 getter/setter 名为 getPerson_Id
/setPerson_Id
.
@Bean
public JpaPagingItemReader<Transaction> remuneradorReader() {
JpaPagingItemReader<Transaction> databaseReader = new JpaPagingItemReader<>();
databaseReader.setEntityManagerFactory(entityManagerFactory);
databaseReader.setQueryString("select o from table o");
databaseReader.setPageSize(1000);
return databaseReader;
}
我正在尝试使用 spring 批处理从 table 中获取所有字段。
我得到了所有字段,除了 ID 字段(主键 e 外键)
下面是我的reader:
@Configuration
public class ReaderConfig {
@Bean
public JdbcCursorItemReader<Entity> Reader(
@Qualifier("datasource") DataSource dataSource) {
return new JdbcCursorItemReaderBuilder<Entity>()
.name("Reader")
.dataSource(dataSource)
.sql("select * from table")
.rowMapper(new BeanPropertyRowMapper<Entity>(Entity.class))
.build();
}
}
下面是我的作者:
@Configuration
public class WriterConfig {
@Bean
public ItemWriter<Entity> Writer() {
return entities-> entities.forEach(System.out::println);
}
}
其他字段成功,但ID字段如transactionId和deposit为空。
我认为有某种保护措施不允许这些字段显示其值。
有人可以帮助我吗?
您的 table 中的列名称是 ID_TRANSACTION
,但是您似乎使用 lombok 生成的 getter/setter 是 getTransactionId
/setTransactionId
,与列名不匹配。根据BeanPropertyRowMapper
的javadoc,如果列名与字段名不匹配,可以使用别名。这是 javadoc:
To facilitate mapping between columns and fields that don't have matching names,
try using column aliases in the SQL statement like
"select fname as first_name from customer".
在您的情况下,您需要将查询更新为:
select ID_TRANSACTION as transactionId, ID_DEPOSIT as depositId, /* other fields */ from rm_transaction
这是一个简单的例子:
import javax.sql.DataSource;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.database.JdbcCursorItemReader;
import org.springframework.batch.item.database.builder.JdbcCursorItemReaderBuilder;
import org.springframework.batch.item.file.FlatFileItemWriter;
import org.springframework.batch.item.file.builder.FlatFileItemWriterBuilder;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.FileSystemResource;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
@Configuration
@EnableBatchProcessing
public class MyJobConfig {
@Bean
public JdbcCursorItemReader<Person> itemReader() {
String sql = "select person_id as id, name from person";
return new JdbcCursorItemReaderBuilder<Person>()
.name("personItemReader")
.dataSource(dataSource())
.sql(sql)
.beanRowMapper(Person.class) // equivalent to .rowMapper(new BeanPropertyRowMapper<>(Person.class))
.build();
}
@Bean
public ItemWriter<Person> itemWriter() {
return items -> items.forEach(System.out::println);
}
@Bean
public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) {
return jobs.get("job")
.start(steps.get("step")
.<Person, Person>chunk(5)
.reader(itemReader())
.writer(itemWriter())
.build())
.build();
}
public static void main(String[] args) throws Exception {
ApplicationContext context = new AnnotationConfigApplicationContext(MyJobConfig.class);
JobLauncher jobLauncher = context.getBean(JobLauncher.class);
Job job = context.getBean(Job.class);
jobLauncher.run(job, new JobParameters());
}
@Bean
public DataSource dataSource() {
EmbeddedDatabase embeddedDatabase = new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.HSQL)
.addScript("/org/springframework/batch/core/schema-hsqldb.sql")
.build();
JdbcTemplate jdbcTemplate = new JdbcTemplate(embeddedDatabase);
jdbcTemplate.execute("create table person (person_id int primary key, name varchar(20));");
for (int i = 1; i <= 10; i++) {
jdbcTemplate.execute(String.format("insert into person values (%s, 'foo%s');", i, i));
}
return embeddedDatabase;
}
static class Person {
private int id;
private String name;
public Person() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
return "Person{id=" + id + ", name='" + name + '\'' + '}';
}
}
}
这会打印:
Person{id=1, name='foo1'}
Person{id=2, name='foo2'}
Person{id=3, name='foo3'}
Person{id=4, name='foo4'}
Person{id=5, name='foo5'}
Person{id=6, name='foo6'}
Person{id=7, name='foo7'}
Person{id=8, name='foo8'}
Person{id=9, name='foo9'}
Person{id=10, name='foo10'}
如果您将 sql 查询更改为 select * from person
,您将看到 id 字段无法正确映射,因为 BeanPropertyRowMapper
找不到 getter/setter 名为 getPerson_Id
/setPerson_Id
.
@Bean
public JpaPagingItemReader<Transaction> remuneradorReader() {
JpaPagingItemReader<Transaction> databaseReader = new JpaPagingItemReader<>();
databaseReader.setEntityManagerFactory(entityManagerFactory);
databaseReader.setQueryString("select o from table o");
databaseReader.setPageSize(1000);
return databaseReader;
}