当前位置: 首页 > 知识库问答 >
问题:

使用批处理作业的FlatFileItemReader和FlatFileItemWriter

危砚
2023-03-14

我想从文本文件中读取、解析和写入数据。我实现了这一点,但我有一个关于标识符声明的问题。我在下面展示了我的类。

客户数据apper.java

public class CustomerDataMapper implements FieldSetMapper<Customer> {
     private static Log log = LogFactory.getLog(CustomerDataMapper.class);

     @Override
     public RawData mapFieldSet(FieldSet fieldSet) throws BindException {
          Customer customer = new Customer();

          try {
              customer.setCustNum(fieldSet.readInt("id"));
              customer.setNameSurname(fieldSet.readString("name"));
          }catch (Exception e){
              log.error("Mapping error, " + e);
          }
          return customer;
     }
}

顾客JAVA

@Component
@Scope("prototype")
public class Customer implements Serializable{
    private Integer custNum;
    private String nameSurname;

    public String getCustNum) {
        return custNum;
    }

    public void setCustNum(String custNum) {
        this.custNum = custNum;
    }

    public String getNameSurname() {
        return nameSurname;
    }

    public void setNameSurname(String nameSurname) {
        this.nameSurname = nameSurname;
    }
}

文件管理器。xml

<bean id="customerFileItemReader" class="org.springframework.batch.item.file.FlatFileItemReader" scope="step">
    <property name= "encoding" value ="Cp1254"/>                           
    <property name="resource" value="#{jobParameters['processPath']}"/>
    <property name="lineMapper">
    <bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
        <property name="lineTokenizer">
            <bean class="org.springframework.batch.item.file.transform.FixedLengthTokenizer">
                <property name="names" value="id, name"/>
                <property name="columns" ref="1-9, 10-30"/>
            </bean>
        </property>
        <property name="fieldSetMapper">
            <bean class="mapper.CustomerDataMapper ">
                <property name="fileName" value="#{jobParameters['fileNameAndTime']}"/>
            </bean>
        </property>
    </bean>
</property>
<bean id="customerFileItemWriter" class="org.springframework.batch.item.database.JdbcBatchItemWriter">
    <property name="dataSource" ref="dataSource"/>
    <property name="sql">
        <value>
            <![CDATA[
                insert into CUSTOMER(CUST_NUM, NAME_SURNAME)
                values (:custNum, :nameSurname)
            ]]>
        </value>
    </property>
    <property name="itemSqlParameterSourceProvider">
    <bean class="org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider"/>
</property>
 <bean id = "customerSkipListener" class="listener.CustomerSkipListener"/>

<batch:job id="customerImportJob">
    <batch:step id="smsPasswordDataImportStep">
        <batch:tasklet>
            <batch:chunk reader="customerFileItemReader" writer="customerFileItemWriter" commit-interval="1" skip-limit="1000">
            <batch:skippable-exception-classes>
                <batch:include class="java.lang.Exception"/>
                <batch:exclude class="java.io.FileNotFoundException"/>
            </batch:skippable-exception-classes> <batch:listeners>
            <batch:listener ref="customerSkipListener" />
        </batch:listeners>
        </batch:chunk>
    </batch:tasklet>

</batch:step>

我想问这个问题,我可以在FieldSetMapper中使用下面的类吗?如果我在定义标识符时不使用Camelcase符号,那么写入数据库就不起作用了。有什么方法或方法吗?非常感谢。

顾客JAVA

@Component
@Scope("prototype")
public class Customer implements Serializable{

private Integer Cust_Num;
private String Name_Surname;

public String getCust_Num() {
    return Cust_Num;
}

public void setCust_Num(String Cust_Num) {
    this.Cust_Num = Cust_Num;
}

public String getName_Surname() {
    return Name_Surname;
}

public void setName_Surname(String Name_Surname) {
    this.Name_Surname = Name_Surname;
}
}

共有1个答案

危宜
2023-03-14

我想问这个问题,可以用这个类来做FieldSetMapper吗

是的,你可以使用这个类。由于您编写了自定义的FieldSetMapper,因此您可以控制映射逻辑。你的地图绘制程序应该是这样的:

public class CustomerDataMapper implements FieldSetMapper<Customer> {
   private static Log log = LogFactory.getLog(CustomerDataMapper.class);

   @Override
   public RawData mapFieldSet(FieldSet fieldSet) throws BindException {
      Customer customer = new Customer();

      try {
          customer.setCust_Num(fieldSet.readInt("id"));
          customer.setName_Surname(fieldSet.readString("name"));
      }catch (Exception e){
          log.error("Mapping error, " + e);
      }
      return customer;
   }
}

但你的问题不在阅读端(以及字段设置映射器),而是在编写端。JdbcBatchItemWriter使用ItemSqlParameterSourceProviderCustomer对象中提取数据,并在sql查询中进行设置。默认情况下,将使用BeanPropertyItemSqlParameterSourceProvider,此实现基于JavaBeans命名约定提取数据。但是,您可以提供一个自定义实现,在您的情况下,它类似于:

class CustomerItemSqlParameterSourceProvider implements ItemSqlParameterSourceProvider<Customer> {

    @Override
    public SqlParameterSource createSqlParameterSource(Customer customer) {
        Map<String, Object> params = new HashMap<>();
        params.put("custNum", customer.getCust_Num());
        params.put("nameSurname", customer.getName_Surname());
        return new MapSqlParameterSource(params);
    }
}

然后在编写器上设置这个CustomerItemSqlParameterSourceProvider

希望这有帮助。

 类似资料:
  • 我有以下工作要处理在一定的时间间隔或特别的基础上。 作业中的步骤如下: 我也想要用户界面,在那里我可以触发一个特别的基础上的工作,而且我应该能够提供参数从用户界面。 我想用Spring batch来完成这个任务,但它更多的是用于读->处理->写之类的工作。这里,在第一步中,我正在生成由第二步读取的数据。我不确定我是否还可以使用Spring batch来实现这个,或者有更好的方法来实现这个。

  • 我试图验证输入文件是否为空或有数据。我正在使用Spring批处理通过XML bean配置,我的实际配置如下: 在我的课堂上,我有这样的东西: 但它从未进入“else”声明,它只是结束了这个过程。 有人知道是否有其他方法来验证文件是否为空吗?

  • 我已经使用开始我的作业,当我尝试使用另一个请求停止作业时,然后获取exeption: JobExecutionNotrunningException:JobExecution必须正在运行,才能停止 当打印作业状态总是获取但批处理作业正在运行时 它的web应用程序,首先上传一些CSV文件,并使用spring batch启动一些操作,在执行过程中,如果用户需要停止,则从另一个控制器方法来停止请求,并试

  • 如果我的平面文件中有不正确数量的令牌,我会遇到以下异常。 如果我抓住了错误的标记异常我想打印自定义错误日志与文件名,行号和行引起异常。 帮助我。 非常感谢。