如何使用弹簧批处理多条线?

时间:2014-03-12 18:30:29

标签: java spring spring-batch

我的数据是这样的 用户ID,的UserData

1,data11

1,data12

2,data21

3,data31

问题是如何让弹簧批量项读取器读取多行并映射到像

这样的对象
Map < userid, List < userdata > >

感谢。

1 个答案:

答案 0 :(得分:2)

要遵循的步骤:

  • 通过实现ItemWriter创建自定义Item Writer类,我们在User中实现了一个逻辑来存储Map<String,List<String>>对象,因为单个用户可以拥有多个关联数据

    package com.spring.batch.domain;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import org.springframework.batch.item.ItemWriter;
    
    public class UserItemWriter implements ItemWriter<User> {
    
        private static Map<String, List<String>> userMap = new HashMap<String, List<String>>();
    
        public void write(List<? extends User> users) throws Exception {
    
            for (User user : users) {
                List<String> list = userMap.get(user.getUserId());
                if (list == null) {
                    list = new ArrayList<String>();
                }
                list.add(user.getUserData());
                userMap.put(user.getUserId(), list);
            }
        }
    
        public static Map<String, List<String>> getUserMap() {
            return userMap;
        }
    
    }
    
  • 普通User POJO课程有两个字段userIduserData

    package com.spring.batch.domain;
    
    public class User {
        private String userId;
        private String userData;
    
        public String getUserId() {
            return userId;
        }
    
        public void setUserId(String userId) {
            this.userId = userId;
        }
    
        public String getUserData() {
            return userData;
        }
    
        public void setUserData(String userData) {
            this.userData = userData;
        }
    
    }
    
  • 运行作业的主要类

    package com.spring.batch.main;
    
    import java.util.List;
    import java.util.Map;
    
    import org.springframework.batch.core.Job;
    import org.springframework.batch.core.JobParametersBuilder;
    import org.springframework.batch.core.JobParametersInvalidException;
    import org.springframework.batch.core.launch.JobLauncher;
    import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
    import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
    import org.springframework.batch.core.repository.JobRestartException;
    import org.springframework.beans.BeansException;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.spring.batch.domain.UserItemWriter;
    
    public class Main {
        public static void main(String[] args) throws BeansException,
                JobExecutionAlreadyRunningException, JobRestartException,
                JobInstanceAlreadyCompleteException, JobParametersInvalidException {
            ApplicationContext appContext = new ClassPathXmlApplicationContext(
                    "config/application-context.xml");
            JobLauncher jobLauncher = (JobLauncher) appContext.getBean("jobLauncher");
            jobLauncher.run(
                    (Job) appContext.getBean("job"),
                    new JobParametersBuilder().addString("input.file.name",
                            "file:src/main/resources/data/input.csv").toJobParameters());
    
            Map<String,List<String>> userMap=UserItemWriter.getUserMap();
            for (String userId : userMap.keySet()) {
                System.out.println(userId + ":" + userMap.get(userId));
            }
        }
    }
    
  • 应用context.xml中:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans ...>
    
        <import resource="jobs.xml" />
    
        <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">
            <property name="transactionManager" ref="transactionManager" />
        </bean>
    
        <bean id="transactionManager"
            class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />
    
    </beans>
    
  • jobs.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans ...>
    
        <job id="job" restartable="false"
            xmlns="http://www.springframework.org/schema/batch">
            <step id="step1">
                <tasklet>
                    <chunk reader="csvItemReader" writer="userItemWriter"
                        commit-interval="2">
                    </chunk>
                </tasklet>
            </step>
        </job>
    
        <bean id="userItemWriter" class="com.spring.batch.domain.UserItemWriter"
            scope="step" />
    
        <bean id="csvItemReader" class="org.springframework.batch.item.file.FlatFileItemReader"
            scope="step">
            <property name="lineMapper">
                <bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
                    <property name="lineTokenizer">
                        <bean
                            class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
                            <property name="names" value="userId,userData" />
                        </bean>
                    </property>
                    <property name="fieldSetMapper">
                        <bean
                            class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
                            <property name="prototypeBeanName" value="user" />
                        </bean>
                    </property>
                </bean>
            </property>
            <property name="linesToSkip" value="1" />
            <property name="resource" value="#{jobParameters['input.file.name']}" />
        </bean>
    
        <bean id="user" class="com.spring.batch.domain.User" scope="prototype" />
    
    </beans>
    
  • input.csv

    UserId,UserData
    1,data11
    1,data12
    2,data21
    3,data31
    
  • 项目结构截图(Maven) enter image description here