Search code examples
javaspring-batchjdbctemplate

Custom Item Reader that uses JdbcPagingItemReader?


I am able to read from my db when this code snippet is in my batchConfig

 @Bean
public ItemReader<? extends Orders> reader() {

    JdbcPagingItemReader<Orders> reader = new JdbcPagingItemReader<Orders>();
    final SqlPagingQueryProviderFactoryBean sqlPagingQueryProviderFactoryBean = new SqlPagingQueryProviderFactoryBean();
    sqlPagingQueryProviderFactoryBean.setDataSource(dataSource);
    sqlPagingQueryProviderFactoryBean.setSelectClause("select *");
    sqlPagingQueryProviderFactoryBean.setFromClause("from orders");
    sqlPagingQueryProviderFactoryBean.setWhereClause(
        "where order_status=var1 and date < var2");
    sqlPagingQueryProviderFactoryBean.setSortKey("date");

    try {
        reader.setQueryProvider(sqlPagingQueryProviderFactoryBean.getObject());
    } catch (Exception e) {
        e.printStackTrace();
    }

    reader.setDataSource(dataSource);
    reader.setPageSize(3);
    reader.setRowMapper(new BeanPropertyRowMapper<Orders>(Orders.class));
    return reader;
}

However, I am not able to pass variables to this ItemReader dynamically from my Restful API. From what I read, I should create a custom item reader however I am not sure how to create that leveraging JdbcPagingItemReader.

Would any of you help me on this one? Thanks!

public void orderProcess(String var1) {
        taskExecutor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    JobParameters jobParameters = new JobParametersBuilder()
                        .addString("var1", var1)
                        .addString("var", "sampleValue1")
                        .addString("time",
                            new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S")
                                .format(Calendar.getInstance().getTime()))
                        .addDate("date", new Date()).toJobParameters();
                    jobLauncher.run(job, jobParameters);
                } catch (Exception e) {
                    LogUtil.logError(LOGGER, "ERROR IN STARTING JOB", e);
                }
            }
        });
    }

Solution

  • Hi @MahmoudBenHassine, i want to pass it using job parameters, i added in the question

    In that case, you should make your item reader step-scoped in order to inject job parameters in its configuration dynamically. Here is an example:

     @Bean
    public ItemReader<? extends Orders> reader(
                        @Value("#{jobParameters['var1']}") String var1,
                        @Value("#{jobParameters['var2']}") String var2) {
    
        JdbcPagingItemReader<Orders> reader = new JdbcPagingItemReader<Orders>();
        final SqlPagingQueryProviderFactoryBean sqlPagingQueryProviderFactoryBean = new SqlPagingQueryProviderFactoryBean();
        sqlPagingQueryProviderFactoryBean.setDataSource(dataSource);
        sqlPagingQueryProviderFactoryBean.setSelectClause("select *");
        sqlPagingQueryProviderFactoryBean.setFromClause("from orders");
        sqlPagingQueryProviderFactoryBean.setWhereClause(
            "where order_status=" + var1 + " and date < " + var2);
        sqlPagingQueryProviderFactoryBean.setSortKey("date");
    
        try {
            reader.setQueryProvider(sqlPagingQueryProviderFactoryBean.getObject());
        } catch (Exception e) {
            e.printStackTrace();
        }
    
        reader.setDataSource(dataSource);
        reader.setPageSize(3);
        reader.setRowMapper(new BeanPropertyRowMapper<Orders>(Orders.class));
        return reader;
    }
    

    You can find more details in the reference documentation here: Late Binding of Job and Step Attributes