spring batch demo 註解版
阿新 • • 發佈:2019-01-15
pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ncsi</groupId>
<artifactId >Demo1_SpringBatch</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Demo1_SpringBatch</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding >
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency >
<!-- <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8</version>
<scope>test</scope>
</dependency> -->
<!-- Apache DBCP-->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<!-- Mysql Dependency -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.25</version>
</dependency>
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-core</artifactId>
<version>3.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<!-- <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.0.9.RELEASE</version>
</dependency> -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
<!-- <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.3.11.RELEASE</version>
</dependency> -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
<!-- <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.11.RELEASE</version>
<scope>test</scope>
</dependency> -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.0.5.RELEASE</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
UserEntity:
package com.Entity;
import java.util.Date;
public class UserEntity {
private String recordType;
private String name;
private Date birthday;
private Integer children;
private int lineNumber;//檔案每行的行數 如果是錯誤記錄,就可以把錯誤資訊準確的放到某一行
public UserEntity(){
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public Integer getChildren() {
return children;
}
public void setChildren(Integer children) {
this.children = children;
}
public int getLineNumber() {
return lineNumber;
}
public void setLineNumber(int lineNumber) {
this.lineNumber = lineNumber;
}
public String getRecordType() {
return recordType;
}
public void setRecordType(String recordType) {
this.recordType = recordType;
}
public UserEntity(String name, Date birthday, Integer children, int lineNumber) {
super();
this.name = name;
this.birthday = birthday;
this.children = children;
this.lineNumber = lineNumber;
}
@Override
public String toString() {
return "UserEntity [name=" + name + ", birthday=" + birthday
+ ", children=" + children + ", lineNumber=" + lineNumber + "]";
}
}
CsvJoblistener:
package com.listener;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobExecutionListener;
import org.springframework.stereotype.Component;
@Component
public class csvJobListener implements JobExecutionListener {
public csvJobListener(){
System.out.println("listener !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
}
@Override
public void beforeJob(JobExecution jobExecution) {
// TODO Auto-generated method stub
System.out.println(" csvJobListener . beforeJob--------------------------------------");
}
@Override
public void afterJob(JobExecution jobExecution) {
// TODO Auto-generated method stub
System.out.println("csvJobListener . afterJob");
}
}
CsvSetMapper:
package com.Mapper;
import java.util.Map;
import org.springframework.batch.item.file.mapping.FieldSetMapper;
import org.springframework.batch.item.file.transform.FieldSet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindException;
import com.Entity.*;
import com.Service.CommonCSVService;
import com.Util.DateUtil;
@Component
public class CsvSetMapper implements FieldSetMapper<UserEntity>{
@Autowired(required=true)
@Qualifier("commonCSVService1")
private CommonCSVService commonCSVService1;
int lineNumber=1;
Map<String, String> csvFileNameMap;
String csvFilePathAndName;
@Override
public UserEntity mapFieldSet(FieldSet fieldSet) throws BindException {
// TODO Auto-generated method stub
UserEntity user;
try{
csvFileNameMap =commonCSVService1.getJobParams();
csvFilePathAndName =csvFileNameMap.get("csvFilePathAndName");
System.err.println(csvFilePathAndName);
//csv的結束行為9時 就不再繼續讀取了 可以用來統計檔案的總行數(我這裡不包括欄位標記行)
if(fieldSet!=null&&!fieldSet.readString(0).equals("9")){
user =new UserEntity();
user.setRecordType(fieldSet.readString(0));
user.setLineNumber(lineNumber);
user.setName(fieldSet.readString(1));
user.setBirthday(DateUtil.parseDate(fieldSet.readString(2)));
user.setChildren(fieldSet.readInt(3));
lineNumber++;
return user;
}
lineNumber=1;
}catch (Exception ex){
System.out.println("mapFieldSet :"+ex);
}
return null;
}
}
CsvItemProcessor:
package com.processor;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import com.Entity.UserEntity;
import com.Service.CommonCSVService;
import com.Util.StringUtil;
//@Component
public class CsvItemProcessor implements ItemProcessor<UserEntity, UserEntity> {
// @Autowired(required=true)
// @Qualifier("commonCSVService")
// private CommonCSVService commonCSVService;
@Override
public UserEntity process(UserEntity item) throws Exception {
// TODO Auto-generated method stub
UserEntity user;
try{
if(!StringUtil.isNotNullOrNotEmptyString(item.getName())){
return null;
}
user=new UserEntity();
user.setName(item.getName());
user.setBirthday(item.getBirthday());
user.setChildren(item.getChildren());
return user;
}catch(Exception e){
System.out.println("CsvItemProcessor :"+e);
throw e;
}
}
}
CommonCSVService:
package com.Service;
import java.util.Map;
import org.springframework.batch.core.Job;
import com.Entity.UserEntity;
public interface CommonCSVService {
Map<String, String> getJobParams();
boolean insertToDB(UserEntity item);
boolean callCSVJob(Job job,String csvFilePath,String csvFileName);
}
CommonCSVServiceImpl:
package com.Service.Impl;
import java.util.HashMap;
import java.util.Map;
import com.Entity.UserEntity;
import com.Service.CommonCSVService;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service("commonCSVService1")
public class CommonCSVServiceImpl implements CommonCSVService{
public JobParameters jobParameters;
public String csvFilePath;
public String csvFileName;
JobExecution jobExecution;
@Autowired
JobLauncher jobLauncher;
@Autowired(required = false)
private JobRepository jobRepository;
@Override
public Map<String, String> getJobParams() {
// TODO Auto-generated method stub
Map<String,String> jobParamsMap =null;
try{
jobParamsMap =new HashMap<String,String>();
jobParamsMap.put("time", jobParameters.getString("time"));
jobParamsMap.put("filePath",jobParameters.getString("filePath"));
jobParamsMap.put("csvFileName", jobParameters.getString("csvFileName"));
jobParamsMap.put("csvFilePathAndName", jobParameters.getString("csvFilePathAndName"));
}catch(Exception e){
System.out.println("CommonCSVServiceImpl.getJobParams :"+e);
}
return jobParamsMap;
}
@Override
public boolean insertToDB(UserEntity item) {
// TODO Auto-generated method stub
System.out.println(item.getName()+" !!!!!!!!!!!!!!!!!!!!!!!!!");
System.out.println("INSERT TO DB!!!!!!!!!!!!!!!!!!!!!!!!!!");
return true;
}
@Override
public boolean callCSVJob(Job job,String csvFilePath,String csvFileName) {
// TODO Auto-generated method stub
jobParameters=null;
this.csvFilePath=csvFilePath;
this.csvFileName=csvFileName;
String csvFilePathAndName=csvFilePath+csvFileName;
jobParameters = new JobParametersBuilder()
.addLong("time", System.currentTimeMillis())
.addString("filePath", csvFilePath)
.addString("csvFileName", csvFileName)
.addString("csvFilePathAndName",csvFilePathAndName)
.toJobParameters();
try {
jobExecution=jobLauncher.run(job, jobParameters);
if(jobExecution.getStatus() == BatchStatus.COMPLETED){
return true;
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
}
DateUtil
package com.Util;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateUtil {
public final static String DEFAULT_DATE_FORMAT = "dd/MM/yyyy";
public final static String _DATE = "yyyy-MM-dd";
public static Date parseDate(String dateStr){
if(dateStr.length()!=10){
return null;
}
Date date =null;
Date tranDate=null;
DateFormat df=new SimpleDateFormat(DEFAULT_DATE_FORMAT);
DateFormat tranDF = new SimpleDateFormat(_DATE);
// defaultDF.setLenient(true);
try {
date = df.parse(dateStr);
tranDate = tranDF.parse(tranDF.format(date));
} catch (Exception e) {
System.out.println("DateUtil.parseDate:"+e);
}
return tranDate;
}
}
FileUtil:
package com.Util;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class FileUtil {
public static List<String> getFilePathList(String folderpath) {
List<String> list;
File dir;
File[] files;
try {
dir = new File(folderpath);
files = dir.listFiles();
list = new ArrayList<String>();
if (files != null) {
for (int i = 0; i < files.length; i++) {
String filePathName = files[i].getPath();
if (!files[i].isDirectory()) {
list.add(filePathName);
}else {
System.out.println("this is Directory");
}
}
return list;
}
} catch (Exception e) {
System.out.println("FileUtil .getFilePathList :"+e);
}
return null;
}
public static String[] readAllFiles(String folderpath){
File file;
String[] filelist=null;
try {
file = new File(folderpath);
if (!file.isDirectory()) {
System.out.println("FileUtil .readAllFiles: 不是目錄!!");
} else if (file.isDirectory()) {
filelist= file.list();
}
} catch (Exception e) {
System.out.println("FileUtil .readAllFiles: "+e);
}
return filelist;
}
}
StringUtil:
package com.Util;
public class StringUtil {
public static boolean isNumeric(String str){
try{
for(int i=0;i<str.length();i++){
if(!Character.isDigit(str.charAt(i))){
return false;
}
}
}catch(Exception e){
System.out.println("StringUtil.isNumeric :"+e);
}
return true;
}
public static boolean isNotNullOrNotEmptyString(String str){
try{
if(str !=null &&str.length()!=0){
return true;
}
}catch(Exception e){
System.out.println("StringUtil.isNotNullOrEmptyString :"+e);
}
return false;
}
}
CsvItemWriter:
package com.writer;
import java.util.List;
import org.springframework.batch.item.ItemWriter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import com.Entity.UserEntity;
import com.Service.CommonCSVService;
@Component
public class CsvItemWriter implements ItemWriter<UserEntity> {
@Autowired(required =false)
@Qualifier("commonCSVService1")
private CommonCSVService commonCSVService1;
@Override
public void write(List<? extends UserEntity> users){
try{
for(UserEntity user :users){
if(commonCSVService1.insertToDB(user)){
System.out.println("CsvItemWriter :"+" insert successfully!");
}else{
System.out.println("CsvItemWriter :"+" insert failed !");
}
}
}catch(Exception e){
System.out.println("CsvItemWriter: "+e);
}
}
}
csvJobTest:
package com.batch;
import java.util.List;
import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.Job;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.Service.CommonCSVService;
import com.Util.FileUtil;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:config.xml")
public class csvJobTest {
private String filePath;
@Autowired(required =false)
@Qualifier("commonCSVService1")
private CommonCSVService commonCSVService1;
@Autowired
Job csvJob;
public String getFilePath(){
return filePath;
}
@Value("#{prop.usercsvFolderPath}")
public void setFilePath(String filePath){
this.filePath=filePath;
}
Map<String,String> csvFileNameMap;
@Test
public void testJob() throws Exception{
List<String> filePathList;
String[] FileList;
try{
filePathList =FileUtil.getFilePathList(filePath);
FileList=FileUtil.readAllFiles(filePath);
if(filePathList.size()>0){
for(int i=0;i<filePathList.size();i++){
if(commonCSVService1.callCSVJob(csvJob, filePath, FileList[i])){
System.out.println("csv job successfully!!!!");
}
}
}else{
System.out.println("empty folder!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
}
}catch(Exception e){
filePathList =FileUtil.getFilePathList(filePath);
}
}
}
config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:batch="http://www.springframework.org/schema/batch"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.1.7.xsd">
<import resource="classpath:database-set.xml"/>
<import resource="classpath:loadFilepath.xml"/>
<!-- For consider the using of annotations foe defining Spring Bean -->
<context:annotation-config />
<!-- For defining Spring Bean -->
<context:component-scan base-package="com" />
</beans>
database-set.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:batch="http://www.springframework.org/schema/batch"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.1.7.xsd">
<!-- Imports Other resources configuration -->
<context:property-placeholder location="classpath:database-source.properties"/>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${database.driverClass}"></property>
<property name="url" value="${database.url}"></property>
<property name="username" value="${database.username}"></property>
<property name="password" value="${database.password}"></property>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>
database-source.properties:
database.name=springbatch
database.host=localhost
database.port=3306
database.username=root
database.password=123456liu
database.driverClass=com.mysql.jdbc.Driver
database.url=jdbc:mysql://${database.host}:${database.port}/${database.name}?characterEncoding=UTF-8&characterSetResults=UTF-8
filepath.xml:
usercsvFolderPath=D:/csvJobFolder/
loadFilepath.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:batch="http://www.springframework.org/schema/batch"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.1.7.xsd">
<!-- config file path -->
<bean id="prop" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<array>
<value>classpath:filepath.properties</value>
</array>
</property>
</bean>
</beans>
result:
[INFO ] 2017-12-07 09:48:45,511 method:org.springframework.test.context.TestContextManager.retrieveTestExecutionListeners(TestContextManager.java:242)
Could not instantiate TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [javax/servlet/ServletContext]
[INFO ] 2017-12-07 09:48