使用RepositoryItemReader nativeQuery使用Spring Boot进行Spring批处理

时间:2018-08-13 22:21:42

标签: spring spring-boot spring-data-jpa

目前我正在使用Spring Boot + Spring Batch + Spring data jpa。

我正在使用RepositoryItemReader。正常

    Page<QuoteOfferFulfillment> findByStatus(String status,
                    Pageable pageable);

其工作正常且按预期工作。但是当我使用本机查询时,我没有收到任何错误,但结果总是为0。我尝试了两种方式:

    1. 

    @Query(value = "SELECT * FROM QUOTE_OFFER_FULFILLMENT QOF WHERE QOF.STATUS= (:status) OR QOF.STATUS=(:status1) AND QOF.RETRY_COUNT < 3 \n#pageable\n", countQuery = "SELECT count(*) FROM QUOTE_OFFER_FULFILLMENT QOF WHERE QOF.STATUS=(:status) OR QOF.STATUS=(:status1) AND QOF.RETRY_COUNT < 3 \n#pageable\n", nativeQuery = true)
        Page<QuoteOfferFulfillment> findByStatusAndRetryCount(
                @Param("status") String status,
                @Param("status1") String status1, Pageable pageable);

and second way

    2. Page<QuoteOfferFulfillment> findByStatusAndRetryCount(
                @Param("status") QuoteOfferFulfillmentStatus status,
                @Param("status1") QuoteOfferFulfillmentStatus status1, Pageable pageable);

在实体类中

    @SqlResultSetMappings({
            @SqlResultSetMapping(name = "SqlResultSetMapping.count", columns = @ColumnResult(name = "cnt")) })
    @NamedNativeQueries({
            @NamedNativeQuery(name = "QuoteOfferFulfillment.findByStatusAndRetryCount", resultClass = QuoteOfferFulfillment.class, query = "SELECT * FROM QUOTE_OFFER_FULFILLMENT WHERE STATUS= (:status) OR STATUS=(:status1) AND RETRY_COUNT < 3"),
            @NamedNativeQuery(name = "QuoteOfferFulfillment.findByStatusAndRetryCount.count", resultSetMapping = "SqlResultSetMapping.count", query = "SELECT count(*) as cnt FROM QUOTE_OFFER_FULFILLMENT WHERE STATUS= (:status) OR STATUS=(:status1) AND RETRY_COUNT < 3") })
    @Entity

    public class QuoteOfferFulfillment implements Serializable {

其他批次配置

    @Configuration
    public class BatchScheduler {

        @Bean
        public ResourcelessTransactionManager resourcelessTransactionManager() {
            return new ResourcelessTransactionManager();
        }

        @Bean
        public JobRepository jobRepository() throws Exception {
            return new MapJobRepositoryFactoryBean(resourcelessTransactionManager()).getObject();
        }

        @Bean
        public ThreadPoolTaskExecutor taskExecutor() {
            ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
            taskExecutor.setCorePoolSize(15);
            taskExecutor.setMaxPoolSize(20);
            taskExecutor.setQueueCapacity(30);
            return taskExecutor;
        }

        @Bean
        public SimpleJobLauncher jobLauncher(ThreadPoolTaskExecutor taskExecutor,
                JobRepository jobRepository) {
            SimpleJobLauncher launcher = new SimpleJobLauncher();
            launcher.setTaskExecutor(taskExecutor);
            launcher.setJobRepository(jobRepository);
            return launcher;
        }

    }

    @Configuration
    @EnableBatchProcessing
    @Import(BatchScheduler.class)
    public class BatchConfiguration {

    @Autowired
        public StepBuilderFactory stepBuilderFactory;

        @Autowired
        public JobBuilderFactory jobBuilderFactory;

        @Autowired
        public QuoteOfferFulfillmentRepository fulfillmentRepository;

        @Autowired
        private SimpleJobLauncher jobLauncher;

    @Scheduled(cron = "*/5 * * * * *")
        public void perform() throws Exception {

            System.out.println("Job Started at :" + new Date());

            JobParameters param = new JobParametersBuilder()
                    .addString("JobID", String.valueOf(System.currentTimeMillis())).toJobParameters();

            JobExecution execution = jobLauncher.run(job(), param);

            System.out.println("Job finished with status :" + execution.getStatus());
        }

     @Bean
        public RepositoryMetadata repositoryMetadata() {
            return new DefaultRepositoryMetadata(QuoteOfferFulfillmentRepository.class);
        }

        @Bean
        public RepositoryItemReader<QuoteOfferFulfillment> reader() {
            RepositoryItemReader<QuoteOfferFulfillment> fullfillment = new RepositoryItemReader<QuoteOfferFulfillment>();
            fullfillment.setRepository(fulfillmentRepository);
            fullfillment.setMethodName("findByStatusAndRetryCount");
            List<QuoteOfferFulfillmentStatus> list = new ArrayList<QuoteOfferFulfillmentStatus>();
            list.add("FULFILLMENT_READY");
            list.add("FAILED");
            fullfillment.setArguments(list);
            fullfillment.setPageSize(40);
            HashMap<String, Direction> sorts = new HashMap<>();
            sorts.put("id", Direction.DESC);
            fullfillment.setSort(sorts);
            return fullfillment;
        }

        @Bean
        public RepositoryItemWriter<QuoteOfferFulfillment> writer() {
            System.out.println("BatchConfiguration.writer()");
            RepositoryItemWriter<QuoteOfferFulfillment> itemWriter = new RepositoryItemWriter<QuoteOfferFulfillment>();
            itemWriter.setRepository(fulfillmentRepository);
            itemWriter.setMethodName("save");
            return itemWriter;
        }

        @Bean
        public Step step1() throws Exception {
            return this.stepBuilderFactory.get("step1")
                    .<QuoteOfferFulfillment, QuoteOfferFulfillment> chunk(1).reader(reader())
                    .processor(new SubmitionProcessor()).writer(writer()).build();
        }

        @Bean
        public Job job() throws Exception {
            System.out.println("BatchConfiguration2.job() =+> ");
            return this.jobBuilderFactory.get("job").incrementer(new RunIdIncrementer()).start(step1())
                    .listener(new JobCompletionListener()).build();

        }

    }

我做错了哪里。请让我知道您的建议。

1 个答案:

答案 0 :(得分:0)

但是我已经以其他方式解决了

@Bean
    public ItemReader<QuoteOfferFulfillment> reader() {
        JpaPagingItemReader<QuoteOfferFulfillment> fullfillment = new JpaPagingItemReader<>();
        try {
            String sqlQuery = "SELECT * FROM FULFILLMENT QOF WHERE QOF.STATUS='"
                    + FULFILLMENT_READY + "'" + " OR QOF.STATUS='"
                    + FAILED + "'" + " AND QOF.RETRY_COUNT < 3";
            JpaNativeQueryProvider<QuoteOfferFulfillment> queryProvider = new JpaNativeQueryProvider<QuoteOfferFulfillment>();
            queryProvider.setSqlQuery(sqlQuery);
            queryProvider.setEntityClass(QuoteOfferFulfillment.class);
            queryProvider.afterPropertiesSet();
            fullfillment.setEntityManagerFactory(entityManagerFactory);
            fullfillment.setPageSize(3);
            fullfillment.setQueryProvider(queryProvider);
            fullfillment.afterPropertiesSet();
            fullfillment.setSaveState(true);
        }
        catch (Exception e) {
            System.out.println("BatchConfiguration.reader() ==> error " + e.getMessage());
        }
        return fullfillment;
    }

使用RepositoryItemReader还有其他方法吗?原因是使用RepositoryItemReader,我们可以使用Repository接口本身遵循标准的本地查询(@Query)。