View Javadoc
1   /*
2    * Copyright 2010-2025 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  package org.mybatis.spring.sample.config;
17  
18  import java.time.LocalDateTime;
19  import java.util.HashMap;
20  import java.util.Map;
21  
22  import javax.sql.DataSource;
23  
24  import org.apache.ibatis.session.ExecutorType;
25  import org.apache.ibatis.session.SqlSessionFactory;
26  import org.mybatis.spring.SqlSessionFactoryBean;
27  import org.mybatis.spring.batch.MyBatisBatchItemWriter;
28  import org.mybatis.spring.batch.MyBatisCursorItemReader;
29  import org.mybatis.spring.batch.builder.MyBatisBatchItemWriterBuilder;
30  import org.mybatis.spring.batch.builder.MyBatisCursorItemReaderBuilder;
31  import org.mybatis.spring.sample.batch.UserToPersonItemProcessor;
32  import org.mybatis.spring.sample.domain.Person;
33  import org.mybatis.spring.sample.domain.User;
34  import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
35  import org.springframework.batch.core.job.Job;
36  import org.springframework.batch.core.job.builder.JobBuilder;
37  import org.springframework.batch.core.repository.JobRepository;
38  import org.springframework.batch.core.step.Step;
39  import org.springframework.batch.core.step.builder.StepBuilder;
40  import org.springframework.batch.infrastructure.item.ItemProcessor;
41  import org.springframework.batch.infrastructure.item.ItemReader;
42  import org.springframework.batch.infrastructure.item.ItemWriter;
43  import org.springframework.context.annotation.Bean;
44  import org.springframework.context.annotation.Configuration;
45  import org.springframework.core.convert.converter.Converter;
46  import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
47  import org.springframework.jdbc.datasource.DataSourceTransactionManager;
48  import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
49  import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
50  import org.springframework.transaction.PlatformTransactionManager;
51  
52  @Configuration
53  @EnableBatchProcessing
54  public class SampleJobConfig {
55  
56    @Bean
57    public DataSource dataSource() {
58      return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.HSQL)
59          .addScript("org/mybatis/spring/sample/db/database-schema.sql")
60          .addScript("org/springframework/batch/core/schema-drop-hsqldb.sql")
61          .addScript("org/springframework/batch/core/schema-hsqldb.sql")
62          .addScript("org/mybatis/spring/sample/db/database-test-data.sql").build();
63    }
64  
65    @Bean
66    public PlatformTransactionManager transactionManager(DataSource dataSource) {
67      return new DataSourceTransactionManager(dataSource);
68    }
69  
70    @Bean
71    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
72      var resourcePatternResolver = new PathMatchingResourcePatternResolver();
73      var ss = new SqlSessionFactoryBean();
74      ss.setDataSource(dataSource);
75      ss.setMapperLocations(resourcePatternResolver.getResources("org/mybatis/spring/sample/mapper/*.xml"));
76      var configuration = new org.apache.ibatis.session.Configuration();
77      configuration.setDefaultExecutorType(ExecutorType.BATCH);
78      ss.setConfiguration(configuration);
79      return ss.getObject();
80    }
81  
82    @Bean
83    public MyBatisCursorItemReader<User> reader(SqlSessionFactory sqlSessionFactory) {
84      // @formatter:off
85          return new MyBatisCursorItemReaderBuilder<User>()
86                  .sqlSessionFactory(sqlSessionFactory)
87                  .queryId("org.mybatis.spring.sample.mapper.UserMapper.getUsers")
88                  .build();
89          // @formatter:on
90    }
91  
92    @Bean
93    public UserToPersonItemProcessor processor() {
94      return new UserToPersonItemProcessor();
95    }
96  
97    @Bean
98    public MyBatisBatchItemWriter<Person> writer(SqlSessionFactory sqlSessionFactory) {
99      // @formatter:off
100         return new MyBatisBatchItemWriterBuilder<Person>()
101                 .sqlSessionFactory(sqlSessionFactory)
102                 .statementId("org.mybatis.spring.sample.mapper.PersonMapper.createPerson")
103                 .itemToParameterConverter(createItemToParameterMapConverter("batch_java_config_user", LocalDateTime.now()))
104                 .build();
105         // @formatter:on
106   }
107 
108   public static <T> Converter<T, Map<String, Object>> createItemToParameterMapConverter(String operationBy,
109       LocalDateTime operationAt) {
110     return item -> {
111       Map<String, Object> parameter = new HashMap<>();
112       parameter.put("item", item);
113       parameter.put("operationBy", operationBy);
114       parameter.put("operationAt", operationAt);
115       return parameter;
116     };
117   }
118 
119   @Bean
120   public Job importUserJob(JobRepository jobRepository, Step step1) {
121     // @formatter:off
122         return new JobBuilder("importUserJob", jobRepository)
123                 .flow(step1)
124                 .end()
125                 .build();
126         // @formatter:on
127   }
128 
129   @Bean
130   public Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManager, ItemReader<User> reader,
131       ItemProcessor<User, Person> processor, ItemWriter<Person> writer) {
132     // @formatter:off
133         return new StepBuilder("step1", jobRepository)
134                 .<User, Person>chunk(10, transactionManager)
135                 .reader(reader)
136                 .processor(processor)
137                 .writer(writer)
138                 .build();
139         // @formatter:on
140   }
141 
142 }