2016-04-27 46 views
1

我是Spring批處理新手,擁有一個以.txt格式爲關鍵參數值的提要文件。我需要使用spring批處理將文件加載到Mysql數據庫中。有什麼方法可以通過鍵值消息讀取文本文件。兩行由空行分隔,分隔符爲'='。Spring批處理讀取一個key = value並將其加載到數據庫中

示例文件:

Name=Jack 
Id=ADC12345 
ClassId=7018 
Rank=-326 

Name=Gile 
Id=FED12345 
ClassId=7018 
Rank=-32 

名稱,ID,classid和排名都列值。

+0

[鏈接] http://spring.io/guides/gs/batch-processing/ [鏈接] –

+0

看看這個例子,做了相反的過程,不同之處在於你必須投資讀者和作者,如果你想讀一個文件必須有相同的格式,在你發佈,你有不同的格式的行和空格[鏈接] http://spring.io/guides/gs/batch-processing/ [鏈接] –

回答

1

這裏是一個有效的解決方案(你只需要在最後一個記錄之後的空行,否則它將不會被讀取):

1)聲明你的業務對象:

public class Student { 

    private String name; 
    private String id; 
    private Integer classId; 
    private Integer rank; 

    // Getter + Setters 

} 

2 )聲明一個自定義itemstreamreader,您將爲其委派實際的FlatFileItemReader:

public class CustomMultiLineItemReader implements ItemStreamReader<Student> { 

    private FlatFileItemReader<FieldSet> delegate; 

    @Override 
    public void open(ExecutionContext executionContext) throws ItemStreamException { 
     delegate.open(executionContext); 
    } 

    @Override 
    public void update(ExecutionContext executionContext) throws ItemStreamException { 
     delegate.update(executionContext); 
    } 

    @Override 
    public void close() throws ItemStreamException { 
     delegate.close(); 
    } 

    // Getter + Setters 
} 

3)覆蓋其讀取方法手動映射您的多記錄:

public Student read() throws Exception { 
    Student s = null; 

    for (FieldSet line = null; (line = this.delegate.read()) != null;) { 

     if (line.getFieldCount() == 0) { 
      return s; // Record must end with footer 
     } else { 

      String prefix = line.readString(0); 
      if (prefix.equals("Name")) { 
       s = new Student(); // Record must start with header 
       s.setName(line.readString(1)); 
      } 
      else if (prefix.equals("Id")) { 
       s.setId(line.readString(1)); 
      } 
      else if (prefix.equals("ClassId")) { 
       s.setClassId(line.readInt(1)); 
      } 
      else if (prefix.equals("Rank")) { 
       s.setRank(line.readInt(1)); 
      } 
     } 
    } 
    return null; 
} 

4)聲明讀者步驟並進行配置:

<bean class="xx.xx.xx.CustomMultiLineItemReader"> 
    <property name="delegate"> 
     <bean class="org.springframework.batch.item.file.FlatFileItemReader"> 
      <property name="resource" value="file:${YOUR_FILE}"></property> 
      <property name="linesToSkip" value="0"></property> 
      <property name="lineMapper"> 
       <bean class="org.springframework.batch.item.file.mapping.PatternMatchingCompositeLineMapper"> 
        <property name="tokenizers"> 
         <map> 
          <entry key="*"> 
           <bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer"> 
            <property name="delimiter" value="="></property> 
           </bean> 
          </entry>             
         </map> 
        </property> 
        <property name="fieldSetMappers"> 
         <map> 
          <entry key="*"> 
           <bean class="org.springframework.batch.item.file.mapping.PassThroughFieldSetMapper" /> 
          </entry> 
         </map> 
        </property> 
       </bean> 
      </property> 
     </bean> 
    </property> 
</bean> 

我用PatternMatchingCompositeLineMapper到行內容相關聯(: *)與相應的lineTokenizer和lineMapper(儘管在這種情況下無用)。

然後,PassThroughFieldSetMapper讓讀者進行映射,DelimitedLineTokenizer分割「=」字符上的行。

+0

謝謝Thrax ...我會研究它.. – Amuthan

+0

現在我能夠解析飼料,但面臨的問題,同時寫入我的SQL數據庫。使用class =「org.springframework.batch.item.database.JdbcBatchItemWriter」來寫入數據。沒有收到任何錯誤。 – Amuthan

+0

@Amuthan什麼問題?數據是否被插入到數據庫中?日誌說什麼? – Thrax

0

沒有與此輸入格式

  1. 開始/結束爲一個完整的項目
  2. 分割在關鍵的第2個挑戰/值對

一個解決方案是使用自定義RecordSeparatorPolicy和自定義LineMapper,如

import java.util.HashMap; 
import java.util.Map; 

import org.junit.Test; 
import org.springframework.batch.item.ExecutionContext; 
import org.springframework.batch.item.file.FlatFileItemReader; 
import org.springframework.batch.item.file.mapping.DefaultLineMapper; 
import org.springframework.batch.item.file.mapping.FieldSetMapper; 
import org.springframework.batch.item.file.separator.RecordSeparatorPolicy; 
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer; 
import org.springframework.batch.item.file.transform.FieldSet; 
import org.springframework.core.io.ClassPathResource; 
import org.springframework.validation.BindException; 

public class ReaderKeyValueTest { 
    @Test 
    public void test() throws Exception { 
     FlatFileItemReader<Map<String, String>> reader = new FlatFileItemReader<Map<String, String>>(); 
     reader.setResource(new ClassPathResource("keyvalue.txt")); 
     // custom RecordSeparatorPolicy 
     reader.setRecordSeparatorPolicy(new RecordSeparatorPolicy() { 

      @Override 
      public String preProcess(final String record) { 
       // empty line is added to the previous 'item' 
       if (record.isEmpty()) { 
        return record; 
       } else { 
        // line with content means it is part of an 'item', lets enhance it with adding a separator 
        return record + ","; 
       } 
      } 

      @Override 
      public String postProcess(final String record) { 
       return record; 
      } 

      @Override 
      public boolean isEndOfRecord(final String record) { 
       // the end of a record is marked with the last key/value pair for "Rank" 
       if (record.contains("Rank=")) { 
        return true; 
       } else { 
        return false; 
       } 
      } 
     }); 
     DefaultLineMapper<Map<String, String>> lineMapper = new DefaultLineMapper<Map<String, String>>(); 
     // the key/value pairs are separated with ',', so we can use the standard DelimitedLineTokenizer here 
     lineMapper.setLineTokenizer(new DelimitedLineTokenizer()); 
     lineMapper.setFieldSetMapper(new FieldSetMapper<Map<String, String>>() { 

      @Override 
      public Map<String, String> mapFieldSet(final FieldSet fieldSet) throws BindException { 
       Map<String, String> item = new HashMap<String, String>(); 
       // split each "Key=Value" and add to the Map 
       for (int i = 0; i < fieldSet.getValues().length; i++) { 
        String[] entry = fieldSet.getValues()[i].split("="); 
        item.put(entry[0], entry[1]); 
       } 
       return item; 
      } 
     }); 
     reader.setLineMapper(lineMapper); 
     reader.open(new ExecutionContext()); 
     Map<String, String> item; 
     while ((item = reader.read()) != null) { 
      System.out.println(item.toString()); 
     } 
     reader.read(); 
     reader.close(); 
    } 
} 

sysout產生

{ClassId=7018, Id=ADC12345, Name=Jack, Rank=-326} 
{ClassId=7018, Id=FED12345, Name=Gile, Rank=-32} 
相關問題