diff --git a/spring-batch-samples/README.md b/spring-batch-samples/README.md index e3d883cad4..008df335c7 100644 --- a/spring-batch-samples/README.md +++ b/spring-batch-samples/README.md @@ -101,13 +101,13 @@ remote client (such as JConsole from the JDK) which does not have Spring Batch on the classpath. See the Spring Core Reference Guide for more details on how to customise the JMX configuration. -### Jdbc Cursor and Batch Update sample +### Jdbc Readers and Batch Update sample The purpose of this sample is to show to usage of the -`JdbcCursorItemReader` and the `JdbcBatchItemWriter` to make +`JdbcCursorItemReader`/`JdbcPagingItemReader` and the `JdbcBatchItemWriter` to make efficient updates to a database table. -[Jdbc Cursor and Batch Update sample](./src/main/java/org/springframework/batch/sample/jdbc/README.md) +[Jdbc Readers and Batch Update sample](./src/main/java/org/springframework/batch/sample/jdbc/README.md) ### Amqp Job Sample diff --git a/spring-batch-samples/src/main/java/org/springframework/batch/sample/jdbc/JdbcCursorReaderBatchWriterSampleJob.java b/spring-batch-samples/src/main/java/org/springframework/batch/sample/jdbc/JdbcReaderBatchWriterSampleJob.java similarity index 81% rename from spring-batch-samples/src/main/java/org/springframework/batch/sample/jdbc/JdbcCursorReaderBatchWriterSampleJob.java rename to spring-batch-samples/src/main/java/org/springframework/batch/sample/jdbc/JdbcReaderBatchWriterSampleJob.java index 65e4bf4b9a..be2a53d7e1 100644 --- a/spring-batch-samples/src/main/java/org/springframework/batch/sample/jdbc/JdbcCursorReaderBatchWriterSampleJob.java +++ b/spring-batch-samples/src/main/java/org/springframework/batch/sample/jdbc/JdbcReaderBatchWriterSampleJob.java @@ -22,14 +22,12 @@ import org.springframework.batch.core.job.builder.JobBuilder; import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.core.step.builder.StepBuilder; +import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider; import org.springframework.batch.item.database.JdbcBatchItemWriter; -import org.springframework.batch.item.database.JdbcCursorItemReader; import org.springframework.batch.item.database.builder.JdbcBatchItemWriterBuilder; -import org.springframework.batch.item.database.builder.JdbcCursorItemReaderBuilder; import org.springframework.batch.sample.domain.trade.CustomerCredit; import org.springframework.batch.sample.domain.trade.internal.CustomerCreditIncreaseProcessor; -import org.springframework.batch.sample.domain.trade.internal.CustomerCreditRowMapper; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; @@ -41,17 +39,7 @@ */ @Configuration @EnableBatchProcessing -public class JdbcCursorReaderBatchWriterSampleJob { - - @Bean - public JdbcCursorItemReader itemReader() { - String sql = "select ID, NAME, CREDIT from CUSTOMER"; - return new JdbcCursorItemReaderBuilder().name("customerReader") - .dataSource(dataSource()) - .sql(sql) - .rowMapper(new CustomerCreditRowMapper()) - .build(); - } +public class JdbcReaderBatchWriterSampleJob { @Bean public JdbcBatchItemWriter itemWriter() { @@ -64,12 +52,13 @@ public JdbcBatchItemWriter itemWriter() { } @Bean - public Job job(JobRepository jobRepository, JdbcTransactionManager transactionManager) { + public Job job(JobRepository jobRepository, JdbcTransactionManager transactionManager, + ItemReader itemReader, JdbcBatchItemWriter itemWriter) { return new JobBuilder("ioSampleJob", jobRepository) .start(new StepBuilder("step1", jobRepository).chunk(2, transactionManager) - .reader(itemReader()) + .reader(itemReader) .processor(new CustomerCreditIncreaseProcessor()) - .writer(itemWriter()) + .writer(itemWriter) .build()) .build(); } diff --git a/spring-batch-samples/src/main/java/org/springframework/batch/sample/jdbc/README.md b/spring-batch-samples/src/main/java/org/springframework/batch/sample/jdbc/README.md index 4bede67bff..9bcb91591c 100644 --- a/spring-batch-samples/src/main/java/org/springframework/batch/sample/jdbc/README.md +++ b/spring-batch-samples/src/main/java/org/springframework/batch/sample/jdbc/README.md @@ -1,9 +1,9 @@ -### Jdbc Cursor and Batch Update sample +### Jdbc Readers and Batch Update sample ## About The purpose of this sample is to show to usage of the -`JdbcCursorItemReader` and the `JdbcBatchItemWriter` to make +`JdbcCursorItemReader`/`JdbcPagingItemReader` and the `JdbcBatchItemWriter` to make efficient updates to a database table. The `JdbcBatchItemWriter` accepts a special form of @@ -18,13 +18,23 @@ which is used to configure the query for the writer. ## Run the sample -You can run the sample from the command line as following: +You can run the cursor reader sample from the command line as following: ``` $>cd spring-batch-samples # Launch the sample using the XML configuration -$>../mvnw -Dtest=JdbcCursorFunctionalTests#testLaunchJobWithXmlConfiguration test +$>../mvnw -Dtest=JdbcCursorFunctionalTests#testLaunchJobWithXmlConfig test # Launch the sample using the Java configuration -$>../mvnw -Dtest=JdbcCursorFunctionalTests#testLaunchJobWithJavaConfiguration test +$>../mvnw -Dtest=JdbcCursorFunctionalTests#testLaunchJobWithJavaConfig test +``` + +You can run the paging reader sample from the command line as following: + +``` +$>cd spring-batch-samples +# Launch the sample using the XML configuration +$>../mvnw -Dtest=JdbcPagingFunctionalTests#testLaunchJobWithXmlConfig test +# Launch the sample using the Java configuration +$>../mvnw -Dtest=JdbcPagingFunctionalTests#testLaunchJobWithJavaConfig test ``` diff --git a/spring-batch-samples/src/main/java/org/springframework/batch/sample/jdbc/cursor/JdbcCursorReaderBatchWriterSampleJob.java b/spring-batch-samples/src/main/java/org/springframework/batch/sample/jdbc/cursor/JdbcCursorReaderBatchWriterSampleJob.java new file mode 100644 index 0000000000..7b1cca6512 --- /dev/null +++ b/spring-batch-samples/src/main/java/org/springframework/batch/sample/jdbc/cursor/JdbcCursorReaderBatchWriterSampleJob.java @@ -0,0 +1,44 @@ +/* + * Copyright 2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.batch.sample.jdbc.cursor; + +import javax.sql.DataSource; + +import org.springframework.batch.item.database.JdbcCursorItemReader; +import org.springframework.batch.item.database.builder.JdbcCursorItemReaderBuilder; +import org.springframework.batch.sample.domain.trade.CustomerCredit; +import org.springframework.batch.sample.domain.trade.internal.CustomerCreditRowMapper; +import org.springframework.batch.sample.jdbc.JdbcReaderBatchWriterSampleJob; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @author Mahmoud Ben Hassine + */ +@Configuration +public class JdbcCursorReaderBatchWriterSampleJob extends JdbcReaderBatchWriterSampleJob { + + @Bean + public JdbcCursorItemReader itemReader(DataSource dataSource) { + String sql = "select ID, NAME, CREDIT from CUSTOMER"; + return new JdbcCursorItemReaderBuilder().name("customerReader") + .dataSource(dataSource) + .sql(sql) + .rowMapper(new CustomerCreditRowMapper()) + .build(); + } + +} diff --git a/spring-batch-samples/src/main/java/org/springframework/batch/sample/jdbc/paging/JdbcPagingReaderBatchWriterSampleJob.java b/spring-batch-samples/src/main/java/org/springframework/batch/sample/jdbc/paging/JdbcPagingReaderBatchWriterSampleJob.java new file mode 100644 index 0000000000..4ecd24c855 --- /dev/null +++ b/spring-batch-samples/src/main/java/org/springframework/batch/sample/jdbc/paging/JdbcPagingReaderBatchWriterSampleJob.java @@ -0,0 +1,61 @@ +/* + * Copyright 2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.batch.sample.jdbc.paging; + +import java.util.HashMap; +import java.util.Map; + +import javax.sql.DataSource; + +import org.springframework.batch.core.configuration.annotation.StepScope; +import org.springframework.batch.item.database.JdbcPagingItemReader; +import org.springframework.batch.item.database.Order; +import org.springframework.batch.item.database.builder.JdbcPagingItemReaderBuilder; +import org.springframework.batch.sample.domain.trade.CustomerCredit; +import org.springframework.batch.sample.domain.trade.internal.CustomerCreditRowMapper; +import org.springframework.batch.sample.jdbc.JdbcReaderBatchWriterSampleJob; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @author Mahmoud Ben Hassine + */ +@Configuration +public class JdbcPagingReaderBatchWriterSampleJob extends JdbcReaderBatchWriterSampleJob { + + @Bean + @StepScope + public JdbcPagingItemReader itemReader(DataSource dataSource, + @Value("#{jobParameters['credit']}") Double credit) { + Map parameterValues = new HashMap<>(); + parameterValues.put("statusCode", "PE"); + parameterValues.put("credit", credit); + parameterValues.put("type", "COLLECTION"); + + return new JdbcPagingItemReaderBuilder().name("customerReader") + .dataSource(dataSource) + .selectClause("select NAME, ID, CREDIT") + .fromClause("FROM CUSTOMER") + .whereClause("WHERE CREDIT > :credit") + .sortKeys(Map.of("ID", Order.ASCENDING)) + .rowMapper(new CustomerCreditRowMapper()) + .pageSize(2) + .parameterValues(parameterValues) + .build(); + } + +} diff --git a/spring-batch-samples/src/main/resources/jobs/iosample/jdbcPaging.xml b/spring-batch-samples/src/main/resources/org/springframework/batch/sample/jdbc/job/jdbcPaging.xml similarity index 73% rename from spring-batch-samples/src/main/resources/jobs/iosample/jdbcPaging.xml rename to spring-batch-samples/src/main/resources/org/springframework/batch/sample/jdbc/job/jdbcPaging.xml index 1720b24129..66b24b386e 100644 --- a/spring-batch-samples/src/main/resources/jobs/iosample/jdbcPaging.xml +++ b/spring-batch-samples/src/main/resources/org/springframework/batch/sample/jdbc/job/jdbcPaging.xml @@ -1,44 +1,58 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spring-batch-samples/src/test/java/org/springframework/batch/sample/iosample/JdbcPagingFunctionalTests.java b/spring-batch-samples/src/test/java/org/springframework/batch/sample/iosample/JdbcPagingFunctionalTests.java deleted file mode 100644 index a6b85ea1e7..0000000000 --- a/spring-batch-samples/src/test/java/org/springframework/batch/sample/iosample/JdbcPagingFunctionalTests.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2006-2022 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.batch.sample.iosample; - -import org.springframework.batch.core.JobParameters; -import org.springframework.batch.core.StepExecution; -import org.springframework.batch.core.scope.context.StepSynchronizationManager; -import org.springframework.batch.item.ItemReader; -import org.springframework.batch.sample.domain.trade.CustomerCredit; -import org.springframework.batch.test.MetaDataInstanceFactory; -import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; - -/** - * @author Dan Garrette - * @author Dave Syer - * @since 2.0 - */ -@SpringJUnitConfig(locations = "/jobs/iosample/jdbcPaging.xml") -class JdbcPagingFunctionalTests extends AbstractIoSampleTests { - - @Override - protected void pointReaderToOutput(ItemReader reader) { - JobParameters jobParameters = super.getUniqueJobParametersBuilder().addDouble("credit", 0.).toJobParameters(); - StepExecution stepExecution = MetaDataInstanceFactory.createStepExecution(jobParameters); - StepSynchronizationManager.close(); - StepSynchronizationManager.register(stepExecution); - } - - @Override - protected JobParameters getUniqueJobParameters() { - return super.getUniqueJobParametersBuilder().addDouble("credit", 10000.).toJobParameters(); - } - -} diff --git a/spring-batch-samples/src/test/java/org/springframework/batch/sample/jdbc/JdbcCursorFunctionalTests.java b/spring-batch-samples/src/test/java/org/springframework/batch/sample/jdbc/JdbcCursorFunctionalTests.java index a8f94033ee..927c432918 100644 --- a/spring-batch-samples/src/test/java/org/springframework/batch/sample/jdbc/JdbcCursorFunctionalTests.java +++ b/spring-batch-samples/src/test/java/org/springframework/batch/sample/jdbc/JdbcCursorFunctionalTests.java @@ -23,6 +23,7 @@ import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobParameters; import org.springframework.batch.core.launch.JobLauncher; +import org.springframework.batch.sample.jdbc.cursor.JdbcCursorReaderBatchWriterSampleJob; import org.springframework.batch.test.JobLauncherTestUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; diff --git a/spring-batch-samples/src/test/java/org/springframework/batch/sample/jdbc/JdbcPagingFunctionalTests.java b/spring-batch-samples/src/test/java/org/springframework/batch/sample/jdbc/JdbcPagingFunctionalTests.java new file mode 100644 index 0000000000..1344797977 --- /dev/null +++ b/spring-batch-samples/src/test/java/org/springframework/batch/sample/jdbc/JdbcPagingFunctionalTests.java @@ -0,0 +1,78 @@ +/* + * Copyright 2006-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.batch.sample.jdbc; + +import org.junit.jupiter.api.Test; + +import org.springframework.batch.core.BatchStatus; +import org.springframework.batch.core.Job; +import org.springframework.batch.core.JobExecution; +import org.springframework.batch.core.JobParameters; +import org.springframework.batch.core.JobParametersBuilder; +import org.springframework.batch.core.launch.JobLauncher; +import org.springframework.batch.sample.jdbc.paging.JdbcPagingReaderBatchWriterSampleJob; +import org.springframework.batch.test.JobLauncherTestUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * @author Dan Garrette + * @author Dave Syer + * @author Mahmoud Ben Hassine + * @since 2.0 + */ +@SpringJUnitConfig(locations = { "/simple-job-launcher-context.xml", "/job-runner-context.xml", + "/org/springframework/batch/sample/jdbc/job/jdbcPaging.xml" }) +class JdbcPagingFunctionalTests { + + @Autowired + private JobLauncherTestUtils jobLauncherTestUtils; + + @Test + void testLaunchJobWithXmlConfig() throws Exception { + // given + JobParameters jobParameters = jobLauncherTestUtils.getUniqueJobParametersBuilder() + .addDouble("credit", 0.) + .toJobParameters(); + + // when + JobExecution jobExecution = this.jobLauncherTestUtils.launchJob(jobParameters); + + // then + assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus()); + } + + @Test + public void testLaunchJobWithJavaConfig() throws Exception { + // given + ApplicationContext context = new AnnotationConfigApplicationContext(JdbcPagingReaderBatchWriterSampleJob.class); + JobLauncher jobLauncher = context.getBean(JobLauncher.class); + Job job = context.getBean(Job.class); + + // when + JobParameters jobParameters = new JobParametersBuilder().addDouble("credit", 0.).toJobParameters(); + JobExecution jobExecution = jobLauncher.run(job, jobParameters); + + // then + assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus()); + } + +} diff --git a/spring-batch-samples/src/test/java/org/springframework/batch/sample/iosample/TwoJobInstancesPagingFunctionalTests.java b/spring-batch-samples/src/test/java/org/springframework/batch/sample/jdbc/TwoJobInstancesPagingFunctionalTests.java similarity index 92% rename from spring-batch-samples/src/test/java/org/springframework/batch/sample/iosample/TwoJobInstancesPagingFunctionalTests.java rename to spring-batch-samples/src/test/java/org/springframework/batch/sample/jdbc/TwoJobInstancesPagingFunctionalTests.java index 46b65a08e9..f19a61e621 100644 --- a/spring-batch-samples/src/test/java/org/springframework/batch/sample/iosample/TwoJobInstancesPagingFunctionalTests.java +++ b/spring-batch-samples/src/test/java/org/springframework/batch/sample/jdbc/TwoJobInstancesPagingFunctionalTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2022 the original author or authors. + * Copyright 2006-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.batch.sample.iosample; +package org.springframework.batch.sample.jdbc; import java.util.Date; @@ -43,7 +43,7 @@ * @since 2.0 */ @SpringJUnitConfig( - locations = { "/simple-job-launcher-context.xml", "/jobs/ioSampleJob.xml", "/jobs/iosample/jdbcPaging.xml" }) + locations = { "/simple-job-launcher-context.xml", "/org/springframework/batch/sample/jdbc/job/jdbcPaging.xml" }) class TwoJobInstancesPagingFunctionalTests { @Autowired