1. 程式人生 > >spring batch demo 註解版

spring batch demo 註解版

專案結構

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&amp;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