1
\$\begingroup\$

I am newbie to Spring Framework. I am trying to move table data from one vendor database to another vendor database using Spring Boot + Spring Batch. I am looking for feedback if this correct approach to solve my particular problem. As part of data transfer process, I have created 3 tables like below

Tables

  • project_preprocess
  • project_main
  • project_backup

Then, I created a Spring Batch job that performs below steps -

  1. Delete data in project_preprocess table
  2. Copy data into project_preprocess table from source database
  3. Take backup of project_main in project_backup
  4. Delete data from project_main
  5. Copy data from project_preprocess into project_main

My code that attempts to accomplish above task is below. Please let me know if this is Spring-way to implement.

@Configuration
@EnableBatchProcessing
public class BatchConfiguration2 {

    @Autowired
    public JobBuilderFactory jobBuilderFactory;

    @Autowired
    public StepBuilderFactory stepBuilderFactory;

    @Autowired 
    public DataSourceConfigs dataSource;

    @Bean
    public PlatformTransactionManager transactionManager() {
        return new ResourcelessTransactionManager();
    }

    @Bean
    public JobExplorer jobExplorer() throws Exception {
        MapJobExplorerFactoryBean jobExplorerFactory = new MapJobExplorerFactoryBean(mapJobRepositoryFactoryBean());
        jobExplorerFactory.afterPropertiesSet();
        return jobExplorerFactory.getObject();
    }

    @Bean
    public MapJobRepositoryFactoryBean mapJobRepositoryFactoryBean() {
        MapJobRepositoryFactoryBean mapJobRepositoryFactoryBean = new MapJobRepositoryFactoryBean();
        mapJobRepositoryFactoryBean.setTransactionManager(transactionManager());
        return mapJobRepositoryFactoryBean;
    }

    @Bean
    public JobRepository jobRepository() throws Exception {
        return mapJobRepositoryFactoryBean().getObject();
    }

    @Bean
    public JobLauncher jobLauncher() throws Exception {
        SimpleJobLauncher simpleJobLauncher = new SimpleJobLauncher();
        simpleJobLauncher.setJobRepository(jobRepository());
        return simpleJobLauncher;
    }



    public ItemReader<Project> reader(DataSource datasource) {
        JdbcCursorItemReader<Project> reader = new JdbcCursorItemReader<Project>();
        reader.setDataSource(datasource);
        reader.setName("project-reader");
        reader.setSql("SELECT id, name, description, creationDate, createdBy FROM dbo.project");
        reader.setRowMapper(new BeanPropertyRowMapper<>(Project.class));
        reader.setFetchSize(100);
        return reader;      
    }

    @Bean
    public ProjectItemProcessor processor() {
        return new ProjectItemProcessor();
    }


    public ItemWriter<Project> jdbcWriter(DataSource ds, ItemPreparedStatementSetter<Project> setter) {



        JdbcBatchItemWriter<Project> writer = new JdbcBatchItemWriter<>();
        writer.setDataSource(ds);           
        writer.setSql("INSERT INTO dbo.project_preprocess(id, name, description, creation_date, created_by, data_source_id) VALUES(?,?,?,?,?,?);");
        writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>());
        writer.setItemPreparedStatementSetter(setter);

        return writer;

    }

    @Bean
    public ItemPreparedStatementSetter<Project> setter() {
        return (item, ps) -> {
            ps.setInt(1, item.getId());
            ps.setString(2, item.getName());
            ps.setString(3, item.getDescription());
            ps.setString(4, item.getCreationDate());
            ps.setString(5, item.getCreatedBy());
            ps.setInt(6, 1);
        };
    }


    @Bean
    public Job importProjectTableJob(JobCompletionNotificationListener listener) {
        return jobBuilderFactory.get("importFortifyProjectTable")
                .incrementer(new RunIdIncrementer())
                .listener(listener)
                .start(databaseOpsTasklet("DELETE FROM dbo.project_preprocess"))
                .next(loadIntoProcessingTable())
                .next(databaseOpsTasklet("INSERT INTO dbo.project_backup SELECT * FROM dbo.project_main"))
                .next(databaseOpsTasklet("DELETE FROM dbo.project_main"))
                .next(databaseOpsTasklet("INSERT INTO dbo.project_main SELECT * FROM dbo.project_preprocess"))                
                .build();
    }

    public Step databaseOpsTasklet(String sql){
        return stepBuilderFactory.get("loadIntoProcessingTable")
                .tasklet(tasklet(sql))
                .build();       
    }


    public Tasklet tasklet(String sql) {
        return new TableOpsTasklet(sql, dataSource.getPrimaryDataSource());
    }

    @Bean
    public Step loadIntoProcessingTable() {
        return stepBuilderFactory.get("loadIntoProcessingTable")
                .<Project, Project> chunk(100)
                .reader(reader(dataSource.getSourceDataSource()))
                .processor(processor())
                .writer(jdbcWriter(dataSource.getPrimaryDataSource(), setter()))
                .build();
    }

    /*
    @Bean
    public JobRunScheduler scheduler() {
        JobRunScheduler scheduler = new JobRunScheduler();
        return scheduler;
    }
   */
    // end::jobstep[]
}

TableOpsTasklet.java

public class TableOpsTasklet implements Tasklet {


    private DataSource dataSource;

    private String sql;

    public TableOpsTasklet (String sql, DataSource dataSource) {
        this.sql = sql;
        this.dataSource = dataSource;
    }

    @Override
    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
        System.out.println("Executing database operations");
         new JdbcTemplate(dataSource)
                .execute(sql);
         return RepeatStatus.FINISHED;
    }

}

Project.java

public class Project {

    private int id;
    private String name;
    private String description;
    private String creationDate;
    private String createdBy;

    public Project() {  

    }

    public Project(int id, String name, String description, String creationDate, String createdBy){
        this.id = id;
        this.name = name;
        this.description = description;
        this.creationDate = creationDate;
        this.createdBy = createdBy;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getCreationDate() {
        return creationDate;
    }

    public void setCreationDate(String creationDate) {
        this.creationDate = creationDate;
    }

    public String getCreatedBy() {
        return createdBy;
    }

    public void setCreatedBy(String createdBy) {
        this.createdBy = createdBy;
    }

    @Override
    public String toString() {
        return "Project [id=" + id + ", name=" + name + ", description=" + description + ", creationDate="
                + creationDate + ", createdBy=" + createdBy + "]";
    }


}

Application.java

@SpringBootApplication
public class Application {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class, args);
    }
}
\$\endgroup\$

migrated from stackoverflow.com Dec 28 '17 at 7:52

This question came from our site for professional and enthusiast programmers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.