首页 > 解决方案 > 如何使用spring批处理从表中获取ID字段

问题描述

我正在尝试使用弹簧批处理从表中获取所有字段。

我得到了所有字段,除了 ID 字段(主键和外键)

下面是我的读者:

@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);
    
    }
}

其他字段是成功的,但是像 transactionId 和 deposit 这样的 ID 字段为空。

我认为有某种保护不允许这些字段显示其值。

有人可以帮助我吗?

标签: javaspring-batch

解决方案


表中的列名是ID_TRANSACTION,但您似乎使用 lombok 生成的 getter/setter 将是getTransactionId/ setTransactionId,与列名不匹配。根据 javadoc BeanPropertyRowMapper,如果列名与字段名不匹配,则可以使用别名。以下是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找不到名为getPerson_Id/的 getter/setter setPerson_Id


推荐阅读