public
Created

a complete, 1-step Spring Batch job with supporting infrastructure (JobLauncher, JobRepository, DataSource, PlatformTransactionManager) and business logic entirely in Java. This job will read in data in a property file and then write them to the database. I used constant Strings for the bean names that way I didn't have too many magic strings floating around.

  • Download Gist
gistfile1.java
Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
// from my https://github.com/joshlong/a-walking-tour-of-all-of-springdom project
 
import org.apache.commons.logging.*;
import org.springframework.batch.core.*;
import org.springframework.batch.core.configuration.annotation.*;
import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.batch.item.*;
import org.springframework.batch.item.database.*;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.mapping.*;
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
import org.springframework.beans.factory.annotation.*;
import org.springframework.context.annotation.*;
import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.datasource.*;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler;
import org.springframework.transaction.PlatformTransactionManager;
import org.springsource.examples.sawt.services.model.Customer;
 
import javax.sql.DataSource;
import java.sql.Driver;
 
 
@Configuration
@EnableBatchProcessing(modular = true)
@ComponentScan
@PropertySource("classpath:/services.properties")
public class BatchConfiguration {
 
private Log log = LogFactory.getLog(getClass());
 
@Bean
public TaskScheduler taskScheduler() {
return new ConcurrentTaskScheduler();
}
 
@Bean
public PlatformTransactionManager transactionManager(DataSource ds) {
return new DataSourceTransactionManager(ds);
}
 
@Bean
public DataSource dataSource(Environment environment) {
String pw = environment.getProperty("dataSource.password"),
user = environment.getProperty("dataSource.user"),
url = environment.getProperty("dataSource.url");
Class<Driver> classOfDs = environment.getPropertyAsClass("dataSource.driverClass", Driver.class);
 
SimpleDriverDataSource dataSource = new SimpleDriverDataSource();
dataSource.setPassword(pw);
dataSource.setUrl(url);
dataSource.setUsername(user);
dataSource.setDriverClass(classOfDs);
return dataSource;
}
 
 
@Bean(name = readCsvFileIntoTableStepReader)
@StepScope
public FlatFileItemReader<Customer> reader(@Value("#{jobParameters['input.file']}") Resource resource) throws Exception {
 
log.debug(String.format("building FlatFileItemReader to read in the file %s", resource.getFile().getAbsolutePath()));
 
FlatFileItemReader<Customer> csvFileReader = new FlatFileItemReader<Customer>();
csvFileReader.setResource(resource);
 
DelimitedLineTokenizer delimitedLineTokenizer = new DelimitedLineTokenizer(DelimitedLineTokenizer.DELIMITER_COMMA);
delimitedLineTokenizer.setNames(new String[]{"lastName", "firstName"});
 
BeanWrapperFieldSetMapper<Customer> beanWrapperFieldSetMapper = new BeanWrapperFieldSetMapper<Customer>();
beanWrapperFieldSetMapper.setTargetType(Customer.class);
 
DefaultLineMapper<Customer> defaultLineMapper = new DefaultLineMapper<Customer>();
defaultLineMapper.setLineTokenizer(delimitedLineTokenizer);
defaultLineMapper.setFieldSetMapper(beanWrapperFieldSetMapper);
 
csvFileReader.setLineMapper(defaultLineMapper);
return csvFileReader;
}
 
@Bean(name = readCsvFileIntoTableStepProcessor)
public ItemProcessor<Customer, Customer> processor() {
return new ItemProcessor<Customer, Customer>() {
@Override
public Customer process(Customer item) throws Exception {
log.info(String.format("processing the customer %s", item.toString()));
return item;
}
};
}
 
@Bean(name = readCsvFileIntoTableStepWriter)
public JdbcBatchItemWriter<Customer> writer(DataSource dataSource) throws Exception {
JdbcBatchItemWriter<Customer> jdbcBatchItemWriter = new JdbcBatchItemWriter<Customer>();
jdbcBatchItemWriter.setAssertUpdates(true);
jdbcBatchItemWriter.setDataSource(dataSource);
jdbcBatchItemWriter.setSql(" INSERT INTO customer( first_name, last_name) VALUES ( :firstName , :lastName ) ");
jdbcBatchItemWriter.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<Customer>());
return jdbcBatchItemWriter;
}
 
@Bean
public Job customerLoaderJob(JobBuilderFactory jobs, @Qualifier(readCsvFileIntoTableStep) Step s1) {
return jobs.get(customerLoaderJob)
.flow(s1)
.end()
.build();
}
 
@Bean(name = readCsvFileIntoTableStep)
public Step readCsvFileIntoTableStep(
StepBuilderFactory stepBuilderFactory,
PlatformTransactionManager platformTransactionManager,
@Qualifier(readCsvFileIntoTableStepReader) ItemReader<Customer> ir,
@Qualifier(readCsvFileIntoTableStepProcessor) ItemProcessor<Customer, Customer> itemProcessor,
@Qualifier(readCsvFileIntoTableStepWriter) ItemWriter<Customer> iw) {
 
StepBuilder builder = stepBuilderFactory.get(readCsvFileIntoTableStep);
 
return builder.<Customer, Customer>chunk(3)
.reader(ir)
.processor(itemProcessor)
.writer(iw)
.transactionManager(platformTransactionManager)
.build();
}
 
private static final String readCsvFileIntoTableStep = "readCsvFileIntoTableStep";
private static final String readCsvFileIntoTableStepReader = readCsvFileIntoTableStep + "Reader";
private static final String readCsvFileIntoTableStepWriter = readCsvFileIntoTableStep + "Writer";
private static final String readCsvFileIntoTableStepProcessor = readCsvFileIntoTableStep + "Processor";
private static final String customerLoaderJob = "customerLoaderJob";
 
 
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.