• springbatch操作CSV文件


    一、需求分析

    使用Spring Batch对CSV文件进行读写操作: 读取一个含有四个字段的CSV文件(id, name, age, score), 

    对文件做简单的处理, 然后输出到还有一个csv文件里.


    二、代码实现

    1. 代码结构图:


    JobLaunch: 启动Job

    CsvItemProcessor: 对Reader数据进行处理

    Student: 实体对象

    input.csv: 数据读取文件

    output.csv: 数据输出文件


    2. applicationContext.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"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans  
    	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
    	http://www.springframework.org/schema/context  
    	http://www.springframework.org/schema/context/spring-context-2.5.xsd"
    	default-autowire="byName">
    	
    	<context:annotation-config />
    	<context:component-scan base-package="com.zdp.springbatch" />
    
    	<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
    		<property name="jobRepository" ref="jobRepository" />
    	</bean>
    
    	<bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean" />
    
    	<bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />
    </beans>

    3. springBatch.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <bean:beans xmlns="http://www.springframework.org/schema/batch"
    	xmlns:bean="http://www.springframework.org/schema/beans" 
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:context="http://www.springframework.org/schema/context"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans 
    	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
    	http://www.springframework.org/schema/context 
    	http://www.springframework.org/schema/context/spring-context-2.5.xsd
    	http://www.springframework.org/schema/batch 
    	http://www.springframework.org/schema/batch/spring-batch-2.1.xsd">
    
    	<!-- 装载spring核心配置文件 -->
    	<bean:import resource="applicationContext.xml" />
    
        <bean:bean id="student" class="com.zdp.springbatch.Student"></bean:bean>
        
    	<job id="csvJob">
            <step id="csvStep">
                <tasklet transaction-manager="transactionManager">
                    <chunk reader="csvItemReader" writer="csvItemWriter" processor="csvItemProcessor" commit-interval="1" />
                </tasklet>
            </step>
        </job>
        
        <!-- 读csv文件 -->
        <bean:bean id="csvItemReader" class="org.springframework.batch.item.file.FlatFileItemReader" scope="step">
            <bean:property name="resource" value="classpath:input.csv"/>
            <bean:property name="lineMapper">
                <bean:bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
                    <bean:property name="lineTokenizer" ref="lineTokenizer"/>
                    <bean:property name="fieldSetMapper">
                        <bean:bean class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
                            <bean:property name="prototypeBeanName" value="student"></bean:property>
                        </bean:bean>
                    </bean:property>
                </bean:bean>
            </bean:property>
        </bean:bean>
    
    
        <!-- lineTokenizer -->
        <bean:bean id="lineTokenizer" class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
            <bean:property name="delimiter" value=","/>
            <bean:property name="names">
                <bean:list>
                    <bean:value>id</bean:value>
                    <bean:value>name</bean:value>
                    <bean:value>age</bean:value>
                    <bean:value>score</bean:value>
                </bean:list>
            </bean:property>
        </bean:bean>
        
        <!-- 写CSV文件 -->
        <bean:bean id="csvItemWriter" class="org.springframework.batch.item.file.FlatFileItemWriter" scope="step">
            <bean:property name="resource" value="file:src/output.csv"/>
            <bean:property name="lineAggregator">
                <bean:bean class="org.springframework.batch.item.file.transform.DelimitedLineAggregator">
                    <bean:property name="delimiter" value=","></bean:property>
                    <bean:property name="fieldExtractor">
                        <bean:bean class="org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor">
                            <bean:property name="names" value="name,age,score"></bean:property>
                        </bean:bean>
                    </bean:property>
                </bean:bean>
            </bean:property>
        </bean:bean>
    </bean:beans>

    这个文件中配置了这次执行的JOB:csvJob。本Job包括一个Step。完毕一个完整的CSV文件读写功能。

    分别由 csvItemReader完毕CSV文件的读操作,由 csvItemProcessor完毕对取得数据的处理,由 csvItemWriter完毕对CSV文件的写操作

    csvItemReader实现的是Spring Batch提供的FlatFileItemReader类。此类主要用于Flat文件的读操作。它包括两个必要的属性 resource和 lineMapper。前者指定要读取的文件的位置,后者是将文件的每一行映射成一个POJO对象。当中 lineMapper也有两个重要属性 lineTokenizer和 fieldSetMapper, lineTokenizer将文件的一行分解成一个 FieldSet,然后由 fieldSetMapper映射成POJO对象。这样的方式与DB的读操作很类似。lineMapper类似于ResultSet,文件里的一行类似于Table中的一条记录,被封装成的FieldSet,类似于RowMapper。

    至于怎么将一条记录封装,这个工作由lineTokenizer的继承类DelimitedLineTokenizer完毕。DelimitedLineTokenizer的delimiter属性决定文件的一行数据依照什么分解,默认的是“。”。 names属性标示分解的每一个字段的名字。传给fieldSetMapper(本实例用的是BeanWrapperFieldSetMapper)的时候。就能够依照这个名字取得相应的值。fieldSetMapper的属性prototypeBeanName,是映射POJO类的名字。设置了此属性后,框架就会将lineTokenizer分解成的一个FieldSet映射成Pojo对象,映射是依照名字来完毕的(lineTokenizer分解时标注的名字与Pojo对象中字段的名字相应)。

    总之,FlatFileItemReader读取一条记录由下面四步完毕:1,从resource指定的文件里读取一条记录;2。lineTokenizer将这条记录依照delimiter分解成Fileset,每一个字段的名字由names属性取得;3,将分解成的Fileset传递给fieldSetMapper,由其依照名字映射成POJO对象。4,终于由FlatFileItemReader将映射成的Pojo对象返回,框架将返回的对象传递给Processor。

    csvItemWriter实现的是FlatFileItemWriter类。此类与FlatFileItemReader类相似,也有两个重要的属性:resource和lineAggregator。

    前者是要输出的文件的路径,后者和lineTokenizer类似。lineAggregator(本实例用DelimitedLineAggregator类)也有两个重要的属性:delimiter和fieldExtractor。

    Delimiter标示输出的字段以什么切割,后者将Pojo对象组装成由Pojo对象的字段组成的一个字符串。

    相同FlatFileItemWriter写一条记录也有下面四步完毕:1,Processor传递过来一个对象给lineAggregator;2。lineAggregator将其这个对象转化成一个数组;3,再由lineAggregator的属性fieldExtractor将数组转化成依照delimiter切割一个字符串。4,将这个字符串输出。


    4. CsvItemProcessor

    /**
     * ItemProcessor类。
     */
    @Component("csvItemProcessor")
    public class CsvItemProcessor implements ItemProcessor<Student, Student> {
    
        /**
         * 对取到的数据进行简单的处理。

    * * @param student 处理前的数据。 * @return 处理后的数据。 * @exception Exception 处理是发生的不论什么异常。

    */ @Override public Student process(Student student) throws Exception { // 合并id和name student.setName(student.getId() + "--" + student.getName()); // age加2 student.setAge(student.getAge() + 2); // score加10 student.setScore(student.getScore() + 10); // 将处理后的结果传递给writer return student; }

    csvItemProcessor实现的是ItemProcessor类。此类接受Reader映射成的Pojo对象。能够对此对象做对应的业务逻辑处理,然后返回,框架就会将返回的结果传递给Writer进行写操作

    5. Student

    /**
     * Pojo类_Student
     */
    public class Student {
    	private String id;
    	private String name;
    	private int age;
    	private float score;
    
    	public String getId() {
    		return id;
    	}
    
    	public void setId(String id) {
    		this.id = id;
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public int getAge() {
    		return age;
    	}
    
    	public void setAge(int age) {
    		this.age = age;
    	}
    
    	public float getScore() {
    		return score;
    	}
    
    	public void setScore(float score) {
    		this.score = score;
    	}
    }
    6. JobLaunch

    /**
     * Test client
     */
    public class JobLaunch {
    
    	public static void main(String[] args) {
    		try {
    			ApplicationContext context = new ClassPathXmlApplicationContext("springBatch.xml");
    
    			JobLauncher jobLauncher = (JobLauncher) context.getBean("jobLauncher");
    			Job job = (Job) context.getBean("csvJob"); 
    
    			// JobLauncher能够用来启动Job
    			JobExecution result = jobLauncher.run(job, new JobParameters());
    			
    			// 处理结束,控制台打印处理结果 
    			System.out.println(result.toString());
    		} catch (Exception e) {
    			throw new RuntimeException("error happens...", e);
    		}
    	}
    }

    7. input and output

    input.csv:

     

    output.csv:


    转自:http://www.cnblogs.com/gulvzhe


    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    如何使用xshell在阿里云服务器上安装tomcat
    如何使用Xshell连接阿里云服务器
    jQuery封装ajax的使用方法
    ES6新增语法
    数组坍塌原理
    JavaScript冒泡排序、选择排序、数组去重
    JS循环嵌套的执行原理
    分栏布局
    如何实现两列固定与一列自适应
    CSS过渡、动画及变形的基本属性与运用
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4729523.html
Copyright © 2020-2023  润新知