Skip to content

Commit 6029b47

Browse files
committed
Users can specify different datasources for the jdbc-item reader and or jdbc-item writer
Users can specify a unique data source for the JdbcCursorItemReader and or writer instead of using the default datasource. If a jdbc-item-reader or jdbc-item-writer data source is not specified the default will be used by the reader or writer. Updated docs Updated readme docs
1 parent 0e56642 commit 6029b47

File tree

8 files changed

+343
-25
lines changed

8 files changed

+343
-25
lines changed

docs/src/main/asciidoc/batch-starter.adoc

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,39 @@ can also use the following properties to configure a `JdbcCursorItemReader`:
287287
| SQL query from which to read.
288288
|===
289289

290+
You can also specify JDBC DataSource specifically for the reader by using the following properties:
291+
.`JdbcCursorItemReader` Properties
292+
|===
293+
| Property | Type | Default Value | Description
294+
295+
| `spring.batch.job.jdbccursoritemreader.datasource.enable`
296+
| `boolean`
297+
| `false`
298+
| Determines whether `JdbcCursorItemReader` `DataSource` should be enabled.
299+
300+
| `jdbccursoritemreader.datasource.url`
301+
| `String`
302+
| `null`
303+
| JDBC URL of the database.
304+
305+
| `jdbccursoritemreader.datasource.username`
306+
| `String`
307+
| `null`
308+
| Login username of the database.
309+
310+
| `jdbccursoritemreader.datasource.password`
311+
| `String`
312+
| `null`
313+
| Login password of the database.
314+
315+
| `jdbccursoritemreader.datasource.driver-class-name`
316+
| `String`
317+
| `null`
318+
| Fully qualified name of the JDBC driver.
319+
|===
320+
321+
NOTE: The default `DataSource` will be used by the `JDBCCursorItemReader` if the `jdbccursoritemreader_datasource` is not specified.
322+
290323
See the https://docs.spring.io/spring-batch/docs/4.3.x/api/org/springframework/batch/item/database/JdbcCursorItemReader.html[`JdbcCursorItemReader` documentation].
291324

292325
[[kafkaItemReader]]
@@ -505,6 +538,39 @@ configuration options by setting the following properties:
505538
| Whether to verify that every insert results in the update of at least one record.
506539
|===
507540

541+
You can also specify JDBC DataSource specifically for the writer by using the following properties:
542+
.`JdbcBatchItemWriter` Properties
543+
|===
544+
| Property | Type | Default Value | Description
545+
546+
| `spring.batch.job.jdbcbatchitemwriter.datasource.enable`
547+
| `boolean`
548+
| `false`
549+
| Determines whether `JdbcCursorItemReader` `DataSource` should be enabled.
550+
551+
| `jdbcbatchitemwriter.datasource.url`
552+
| `String`
553+
| `null`
554+
| JDBC URL of the database.
555+
556+
| `jdbcbatchitemwriter.datasource.username`
557+
| `String`
558+
| `null`
559+
| Login username of the database.
560+
561+
| `jdbcbatchitemwriter.datasource.password`
562+
| `String`
563+
| `null`
564+
| Login password of the database.
565+
566+
| `jdbcbatchitemreader.datasource.driver-class-name`
567+
| `String`
568+
| `null`
569+
| Fully qualified name of the JDBC driver.
570+
|===
571+
572+
NOTE: The default `DataSource` will be used by the `JdbcBatchItemWriter` if the `jdbcbatchitemwriter_datasource` is not specified.
573+
508574
See the https://docs.spring.io/spring-batch/docs/4.3.x/api/org/springframework/batch/item/database/JdbcBatchItemWriter.html[`JdbcBatchItemWriter` documentation].
509575

510576
[[kafkaitemwriter]]

spring-cloud-starter-single-step-batch-job/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
</properties>
1818

1919
<dependencies>
20+
<dependency>
21+
<groupId>org.springframework.cloud</groupId>
22+
<artifactId>spring-cloud-task-core</artifactId>
23+
</dependency>
2024
<dependency>
2125
<groupId>org.springframework.boot</groupId>
2226
<artifactId>spring-boot-starter-batch</artifactId>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright 2022-2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.cloud.task.batch.autoconfigure.jdbc;
18+
19+
import javax.sql.DataSource;
20+
21+
import org.springframework.beans.factory.annotation.Qualifier;
22+
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
23+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
24+
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
25+
import org.springframework.boot.context.properties.ConfigurationProperties;
26+
import org.springframework.cloud.task.configuration.DefaultTaskConfigurer;
27+
import org.springframework.cloud.task.configuration.TaskConfigurer;
28+
import org.springframework.context.annotation.Bean;
29+
import org.springframework.context.annotation.Primary;
30+
31+
/**
32+
* Establishes the default {@link DataSource} for the Task when creating a {@link DataSource}
33+
* for {@link org.springframework.batch.item.database.JdbcCursorItemReader}
34+
* or {@link org.springframework.batch.item.database.JdbcBatchItemWriter}.
35+
*
36+
* @author Glenn Renfro
37+
* @since 3.0
38+
*/
39+
class JDBCSingleStepDataSourceAutoConfiguration {
40+
41+
@ConditionalOnMissingBean
42+
@Bean
43+
public TaskConfigurer myTaskConfigurer(DataSource dataSource) {
44+
return new DefaultTaskConfigurer(dataSource);
45+
}
46+
47+
@ConditionalOnProperty(prefix = "spring.batch.job.jdbcsinglestep.datasource", name = "enable", havingValue = "true", matchIfMissing = true)
48+
@ConditionalOnMissingBean(name = "springDataSourceProperties")
49+
@Bean(name = "springDataSourceProperties")
50+
@ConfigurationProperties("spring.datasource")
51+
@Primary
52+
public DataSourceProperties springDataSourceProperties() {
53+
return new DataSourceProperties();
54+
}
55+
56+
@ConditionalOnProperty(prefix = "spring.batch.job.jdbcsinglestep.datasource", name = "enable", havingValue = "true", matchIfMissing = true)
57+
@Bean(name = "springDataSource")
58+
@Primary
59+
public DataSource dataSource(@Qualifier("springDataSourceProperties")DataSourceProperties springDataSourceProperties) {
60+
DataSource dataSource = springDataSourceProperties.initializeDataSourceBuilder().build();
61+
return dataSource;
62+
}
63+
}

spring-cloud-starter-single-step-batch-job/src/main/java/org/springframework/cloud/task/batch/autoconfigure/jdbc/JdbcBatchItemWriterAutoConfiguration.java

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2020 the original author or authors.
2+
* Copyright 2020-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,18 +20,26 @@
2020

2121
import javax.sql.DataSource;
2222

23+
import org.apache.commons.logging.Log;
24+
import org.apache.commons.logging.LogFactory;
25+
2326
import org.springframework.batch.item.database.ItemPreparedStatementSetter;
2427
import org.springframework.batch.item.database.ItemSqlParameterSourceProvider;
2528
import org.springframework.batch.item.database.JdbcBatchItemWriter;
2629
import org.springframework.batch.item.database.builder.JdbcBatchItemWriterBuilder;
2730
import org.springframework.beans.factory.annotation.Autowired;
31+
import org.springframework.beans.factory.annotation.Qualifier;
2832
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
2933
import org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration;
3034
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
3135
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
36+
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
37+
import org.springframework.boot.context.properties.ConfigurationProperties;
3238
import org.springframework.boot.context.properties.EnableConfigurationProperties;
39+
import org.springframework.context.ApplicationContext;
3340
import org.springframework.context.annotation.Bean;
3441
import org.springframework.context.annotation.Configuration;
42+
import org.springframework.context.annotation.Import;
3543

3644
/**
3745
* Autconfiguration for a {@code JdbcBatchItemWriter}.
@@ -43,14 +51,21 @@
4351
@Configuration(proxyBeanMethods = false)
4452
@EnableConfigurationProperties(JdbcBatchItemWriterProperties.class)
4553
@AutoConfigureAfter(BatchAutoConfiguration.class)
54+
@Import(JDBCSingleStepDataSourceAutoConfiguration.class)
4655
public class JdbcBatchItemWriterAutoConfiguration {
4756

57+
private static final Log logger = LogFactory
58+
.getLog(JdbcBatchItemWriterAutoConfiguration.class);
59+
4860
@Autowired(required = false)
4961
private ItemPreparedStatementSetter itemPreparedStatementSetter;
5062

5163
@Autowired(required = false)
5264
private ItemSqlParameterSourceProvider itemSqlParameterSourceProvider;
5365

66+
@Autowired
67+
ApplicationContext applicationContext;
68+
5469
private JdbcBatchItemWriterProperties properties;
5570

5671
private DataSource dataSource;
@@ -65,9 +80,16 @@ public JdbcBatchItemWriterAutoConfiguration(DataSource dataSource,
6580
@ConditionalOnMissingBean
6681
@ConditionalOnProperty(prefix = "spring.batch.job.jdbcbatchitemwriter", name = "name")
6782
public JdbcBatchItemWriter<Map<String, Object>> itemWriter() {
83+
DataSource writerDataSource = this.dataSource;
84+
try {
85+
writerDataSource = this.applicationContext.getBean("jdbcBatchItemWriterSpringDataSource", DataSource.class);
86+
}
87+
catch (Exception ex) {
88+
logger.info("Using Default Data Source for the JdbcBatchItemWriter");
89+
}
6890

6991
JdbcBatchItemWriterBuilder<Map<String, Object>> jdbcBatchItemWriterBuilder = new JdbcBatchItemWriterBuilder<Map<String, Object>>()
70-
.dataSource(this.dataSource).sql(this.properties.getSql());
92+
.dataSource(writerDataSource).sql(this.properties.getSql());
7193
if (this.itemPreparedStatementSetter != null) {
7294
jdbcBatchItemWriterBuilder
7395
.itemPreparedStatementSetter(this.itemPreparedStatementSetter);
@@ -83,4 +105,17 @@ else if (this.itemSqlParameterSourceProvider != null) {
83105
return jdbcBatchItemWriterBuilder.build();
84106
}
85107

108+
@ConditionalOnProperty(prefix = "spring.batch.job.jdbcbatchitemwriter.datasource", name = "enable", havingValue = "true")
109+
@Bean(name = "jdbcBatchItemWriterDataSourceProperties")
110+
@ConfigurationProperties("jdbcbatchitemwriter.datasource")
111+
public DataSourceProperties jdbcBatchItemWriterDataSourceProperties() {
112+
return new DataSourceProperties();
113+
}
114+
115+
@ConditionalOnProperty(prefix = "spring.batch.job.jdbcbatchitemwriter.datasource", name = "enable", havingValue = "true")
116+
@Bean(name = "jdbcBatchItemWriterSpringDataSource")
117+
public DataSource writerDataSource(@Qualifier("jdbcBatchItemWriterDataSourceProperties") DataSourceProperties writerDataSourceProperties) {
118+
DataSource result = writerDataSourceProperties.initializeDataSourceBuilder().build();
119+
return result;
120+
}
86121
}

spring-cloud-starter-single-step-batch-job/src/main/java/org/springframework/cloud/task/batch/autoconfigure/jdbc/JdbcCursorItemReaderAutoConfiguration.java

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2021 the original author or authors.
2+
* Copyright 2020-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -23,16 +23,24 @@
2323

2424
import javax.sql.DataSource;
2525

26+
import org.apache.commons.logging.Log;
27+
import org.apache.commons.logging.LogFactory;
28+
2629
import org.springframework.batch.item.database.JdbcCursorItemReader;
2730
import org.springframework.batch.item.database.builder.JdbcCursorItemReaderBuilder;
2831
import org.springframework.beans.factory.annotation.Autowired;
32+
import org.springframework.beans.factory.annotation.Qualifier;
2933
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
3034
import org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration;
3135
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
3236
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
37+
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
38+
import org.springframework.boot.context.properties.ConfigurationProperties;
3339
import org.springframework.boot.context.properties.EnableConfigurationProperties;
40+
import org.springframework.context.ApplicationContext;
3441
import org.springframework.context.annotation.Bean;
3542
import org.springframework.context.annotation.Configuration;
43+
import org.springframework.context.annotation.Import;
3644
import org.springframework.jdbc.core.PreparedStatementSetter;
3745
import org.springframework.jdbc.core.RowMapper;
3846

@@ -45,8 +53,15 @@
4553
@EnableConfigurationProperties(JdbcCursorItemReaderProperties.class)
4654
@AutoConfigureAfter(BatchAutoConfiguration.class)
4755
@ConditionalOnProperty(prefix = "spring.batch.job.jdbccursoritemreader", name = "name")
56+
@Import(JDBCSingleStepDataSourceAutoConfiguration.class)
4857
public class JdbcCursorItemReaderAutoConfiguration {
4958

59+
private static final Log logger = LogFactory
60+
.getLog(JdbcCursorItemReaderAutoConfiguration.class);
61+
62+
@Autowired
63+
ApplicationContext applicationContext;
64+
5065
private final JdbcCursorItemReaderProperties properties;
5166

5267
private final DataSource dataSource;
@@ -61,10 +76,18 @@ public JdbcCursorItemReaderAutoConfiguration(
6176
@ConditionalOnMissingBean
6277
public JdbcCursorItemReader<Map<String, Object>> itemReader(@Autowired(required = false) RowMapper<Map<String, Object>> rowMapper,
6378
@Autowired(required = false) PreparedStatementSetter preparedStatementSetter) {
79+
DataSource readerDataSource = this.dataSource;
80+
try {
81+
readerDataSource = this.applicationContext.getBean("jdbcCursorItemReaderSpringDataSource", DataSource.class);
82+
}
83+
catch (Exception e) {
84+
logger.info("Using Default Data Source for the JdbcCursorItemReader");
85+
86+
}
6487
return new JdbcCursorItemReaderBuilder<Map<String, Object>>()
6588
.name(this.properties.getName())
6689
.currentItemCount(this.properties.getCurrentItemCount())
67-
.dataSource(this.dataSource)
90+
.dataSource(readerDataSource)
6891
.driverSupportsAbsolute(this.properties.isDriverSupportsAbsolute())
6992
.fetchSize(this.properties.getFetchSize())
7093
.ignoreWarnings(this.properties.isIgnoreWarnings())
@@ -86,6 +109,20 @@ public RowMapper<Map<String, Object>> rowMapper() {
86109
return new MapRowMapper();
87110
}
88111

112+
@ConditionalOnProperty(prefix = "spring.batch.job.jdbccursoritemreader.datasource", name = "enable", havingValue = "true")
113+
@Bean(name = "jdbcCursorItemReaderDataSourceProperties")
114+
@ConfigurationProperties("jdbccursoritemreader.datasource")
115+
public DataSourceProperties jdbcCursorItemReaderDataSourceProperties() {
116+
return new DataSourceProperties();
117+
}
118+
119+
@ConditionalOnProperty(prefix = "spring.batch.job.jdbccursoritemreader.datasource", name = "enable", havingValue = "true")
120+
@Bean(name = "jdbcCursorItemReaderSpringDataSource")
121+
public DataSource readerDataSource(@Qualifier("jdbcCursorItemReaderDataSourceProperties")DataSourceProperties readerDataSourceProperties) {
122+
DataSource result = readerDataSourceProperties.initializeDataSourceBuilder().build();
123+
return result;
124+
}
125+
89126
public static class MapRowMapper implements RowMapper<Map<String, Object>> {
90127

91128
@Override

0 commit comments

Comments
 (0)