最近在学习Spring batch相关的内容,网上也有不少Spring Batch相关的知识,不过大多都是使用xml进行配置的。这里是我用注解的方式进行相关的学习心得。
首先我们来看如何将一个文本文件中的内容导入到数据库中。
我们先来看一下我们所需要的环境。我们这里使用的是STS(Spring Tool Suite)当然也可以使用Eclipse(需要有maven插件)或者Myeclipse。我们使用的数据库是MySQl,当然也可以使用其他的数据库,根据自己的需要。
现在开始我们的文件到数据库的学习。
第一步,我们需要创建一个maven的project。然后在我们的项目下会有三个包,这里我们只需要其中的两个,就是main下的两个(java和resources包)。
第二步,我们来配置一下我们的pom文件。
一、org.springframework.boot
1、spring-boot-starter-batch
2、spring-boot-starter-jdbc
3、spring-boot-starter-jetty
二、mysql的jdbc驱动包
配置完这些,我们的软件就会自动下载这些包以及相关的依赖包,这需要一点时间。
第三步,我们需要来配置我们的数据库连接的相关信息。
我们需要在resources包下新建一个properties文件,如下。
1 spring.datasource.driverClassName=com.mysql.jdbc.Driver 2 spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test 3 spring.datasource.username=root 4 spring.datasource.password=
第四步:由于几天我们学习的是将文件内容读到数据库中,所以,接下来我们需要准备一个文件,这个文件需要时flat类型的,例如txt或者csv等。
1 zhangsan,anhui,1991/02/15,M 2 lisi,shanghai,1992/01/09,F 3 wangwu,wuhan,1990/01/22,M 4 zhaoliu,tianjin,1991/11/11,F 5 zhangkun,huashan,1989/09/20,M
第五步,我们需要创建一个entity对象类,如下:
1 public class User { 2 private String userId; 3 private String userName; 4 private String address; 5 private Date birth; 6 private String gender; 7 8 public String getUserId() { 9 return userId; 10 } 11 12 public void setUserId(String userId) { 13 this.userId = userId; 14 } 15 16 public Date getBirth() { 17 return birth; 18 } 19 20 public void setBirth(Date birth) { 21 this.birth = birth; 22 } 23 24 public String getGender() { 25 return gender; 26 } 27 28 public void setGender(String gender) { 29 this.gender = gender; 30 } 31 32 public String getUserName() { 33 return userName; 34 } 35 36 public void setUserName(String userName) { 37 this.userName = userName; 38 } 39 40 public String getAddress() { 41 return address; 42 } 43 44 public void setAddress(String address) { 45 this.address = address; 46 } 47 48 public User() { 49 50 } 51 52 public User(String userId, String userName, String address ,String gender, Date birth) { 53 this.userId = userId; 54 this.userName = userName; 55 this.address = address; 56 this.gender = gender; 57 this.birth = birth; 58 } 59 60 @Override 61 public String toString() { 62 return "userId"+ userId +", userName: " + userName + ", address: " + address + ",gender: " + gender + ", birthDay: "+birth; 63 } 64 65 }
第六步,batch是一个用来执行job的框架。所以我们需要来创建一个job,在job里需要配置我们的step,每一个step的完成需要有三个动作,读文件,处理信息,写数据库。代码如下:
1 @Configuration 2 @EnableBatchProcessing 3 public class Configuration { 4 @Bean 5 public ItemReader<User> reader() { 6 FlatFileItemReader<User> reader = new FlatFileItemReader<User>(); 7 reader.setResource(new ClassPathResource("test.csv")); 8 reader.setLineMapper(new DefaultLineMapper<User>() {{ 9 setLineTokenizer(new DelimitedLineTokenizer() {{ 10 setNames(new String[] { "userName", "address", "birth", "gender" }); 11 }}); 12 setFieldSetMapper(new BeanWrapperFieldSetMapper<User>() {{ 13 setTargetType(User.class); 14 }}); 15 }}); 16 return reader; 17 } 18 19 @Bean 20 public ItemProcessor<User, User> processor() { 21 return new UserItemProcessor(); 22 } 23 24 @Bean 25 public ItemWriter<User> writer(DataSource dataSource) { 26 JdbcBatchItemWriter<User> writer = new JdbcBatchItemWriter<User>(); 27 writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<User>()); 28 writer.setSql("INSERT INTO User (user_name, address,birth,gender) VALUES (:userName, :address, :birth,:gender)"); 29 writer.setDataSource(dataSource); 30 return writer; 31 } 32 33 @Bean 34 public Job CSV2DBJob(JobBuilderFactory jobs, Step s1) { 35 return jobs.get("CSV2DBJob") 36 .incrementer(new RunIdIncrementer()) 37 .flow(s1) 38 .end() 39 .build(); 40 } 41 42 @Bean 43 public Step step1(StepBuilderFactory stepBuilderFactory, ItemReader<User> reader, 44 ItemWriter<User> writer, ItemProcessor<User, User> processor) { 45 return stepBuilderFactory.get("step1") 46 .<User, User> chunk(10) 47 .reader(reader) 48 .processor(processor) 49 .writer(writer) 50 .build(); 51 } 52 53 @Bean 54 public JdbcTemplate jdbcTemplate(DataSource dataSource) { 55 return new JdbcTemplate(dataSource); 56 } 57 58 }
step中的process需要我们自己来根据自己的实际进行相关的处理,如下
1 public class UserItemProcessor implements ItemProcessor<User, User> { 2 3 @Override 4 public User process(final User user) throws Exception { 5 final String userId = "2014010"+ user.getUserId(); 6 final String gender = user.getGender().equals("M")?"male":"female"; 7 final Date birth = user.getBirth(); 8 final String userName = user.getUserName().substring(0,1).toUpperCase()+user.getUserName().substring(1).toLowerCase(); 9 final String address = user.getAddress().substring(0,1).toUpperCase()+user.getAddress().substring(1).toLowerCase(); 10 11 final User transformedUser = new User(userId,userName, address,gender,birth); 12 13 14 return transformedUser; 15 }
一切都好了,我们还需要写一个application类来启动我们的job,具体如下:
1 @ComponentScan 2 @EnableAutoConfiguration 3 public class Application { 4 5 public static void main(String[] args) { 6 ApplicationContext ctx = SpringApplication.run(Application.class, args); 7 } 8 9 }
最后,还需要提醒的是,由于我们的batch中的entity没有配置自动建表,所以我们需要自己提前在数据库中创建一个User表或者在我们的resources包下面建一个schema-all.sql文件,在这里写入我们的建表语句就可以了,schema-all是可以直接被Spring batch框架识别的。
1 DROP TABLE IF EXISTS user; 2 3 CREATE TABLE user ( 4 user_id BIGINT AUTO_INCREMENT NOT NULL PRIMARY KEY, 5 user_name VARCHAR(20), 6 address VARCHAR(20), 7 birth Date, 8 gender varchar(1) 9 );
好了一切到此就结束了,现在启动我们的工程就可以将我们的文件内容导入到我们的数据库中了。