2016-08-04 66 views
0

如下面的代碼在step1中看到我正在閱讀users.xml和寫入數據庫現在在step2我正在讀取userdetails.xml並寫入數據庫,但我需要step1自動生成密鑰步驟2的tbl_user。我怎樣才能做到這一點?從xml文件中讀取Spring批處理並寫入數據庫。需要step1自動生成密鑰爲step2

的xmlns:的xsi = 「http://www.w3.org/2001/XMLSchema-instance」 的xsi:的schemaLocation =「http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.2.xsdhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd「>

<import resource="../config/context.xml" /> 
<import resource="../config/database.xml" />    


<bean id="xmlItemReader1" class="org.springframework.batch.item.xml.StaxEventItemReader"> 
    <property name="resource" value="file:xml/outputs/users.xml" /> 
    <property name="fragmentRootElementName" value="user" /> 
    <property name="unmarshaller" ref="userUnmarshaller"/>      
</bean> 

<bean id="xmlItemReader2" class="org.springframework.batch.item.xml.StaxEventItemReader"> 
    <property name="resource" value="file:xml/outputs/userdetails.xml" /> 
    <property name="fragmentRootElementName" value="userdetail" /> 
    <property name="unmarshaller" ref="userUnmarshaller"/>      
</bean> 

<bean id="itemProcessor1" class="com.qmetry.recovery.mapper.UserItemProcessor" /> 

<bean id="itemProcessor2" class="com.qmetry.recovery.mapper.UserDetailItemProcessor" /> 

<job id="testJob2" xmlns="http://www.springframework.org/schema/batch"> 
     <step id="step2_1"> 
      <tasklet transaction-manager="transactionManager"> 
       <chunk reader="xmlItemReader1" writer="databaseItemWriter1" processor="itemProcessor1" 
         commit-interval="100" /> 
      </tasklet>     
     <listeners>     
      <listener ref="testListener" /> 
     </listeners>    
     </step> 
     <step id="step2_2"> 
      <tasklet transaction-manager="transactionManager"> 
       <chunk reader="xmlItemReader2" writer="databaseItemWriter2" processor="itemProcessor1" 
         commit-interval="100" /> 
      </tasklet>     
     </step>    
</job> 
<bean id="testListener" class="com.qmetry.recovery.mapper.TestListener" scope="step" /> 

<bean id="databaseItemWriter1" class="org.springframework.batch.item.database.JdbcBatchItemWriter"> 
    <property name="dataSource" ref="dataSource" /> 
    <property name="sql"> 
     <value> 
      <![CDATA[   
       insert into TBL_USER(USERNAME,EMAILID) 
       values (?, ?)       
      ]]> 
     </value> 
    </property> 

    <!--We need a custom setter to handle the conversion between Jodatime LocalDate and MySQL DATE BeanPropertyItemSqlParameterSourceProvider--> 
    <property name="itemPreparedStatementSetter"> 
     <bean class="com.qmetry.recovery.mapper.UserItemPreparedStatementSetter"/> 
    </property> 
</bean> 
<bean id="databaseItemWriter2" class="org.springframework.batch.item.database.JdbcBatchItemWriter"> 
    <property name="dataSource" ref="dataSource" /> 
    <property name="sql"> 
     <value> 
      <![CDATA[   
       insert into TBL_USERDETAIL(USERID,CONTACT) 
       values (?, ?) 
      ]]> 
     </value> 
    </property> 

    <!--We need a custom setter to handle the conversion between Jodatime LocalDate and MySQL DATE BeanPropertyItemSqlParameterSourceProvider--> 
    <property name="itemPreparedStatementSetter"> 
     <bean class="com.qmetry.recovery.mapper.UserDetailItemPreparedStatementSetter"/> 
    </property> 
</bean>  

users.xml中

<?xml version="1.0" encoding="UTF-8"?><users> 
    <user> 
     <userId>1</userId> 
     <userName>Taher</userName> 
     <emailId>[email protected]</emailId> 
    </user> 
</users> 

userdetails.xml

<?xml version="1.0" encoding="UTF-8"?><userdetails> 
    <userdetail> 
     <userDetailId>1</userDetailId> 
     <userId__TblUser>1</userId__TblUser> 
     <contact>1111111111</contact> 
    </userdetail> 
    <userdetail> 
     <userDetailId>2</userDetailId> 
     <userId__TblUser>1</userId__TblUser> 
     <contact>2222222222</contact> 
    </userdetail> 
    <userdetail> 
     <userDetailId>4</userDetailId> 
     <userId__TblUser>1</userId__TblUser> 
     <contact>4444444444</contact> 
    </userdetail> 
</userdetails> 
+1

userdetails.xml中必須有與用戶相關的其他內容。你如何確定它屬於一個用戶從一個XML文件到另一個? –

+0

我使用的XML是使用spring批量從db表中讀取並寫入xml的XML。現在我必須實現它反之亦然,即從該XML讀取並寫入數據庫。 – TaherT

+0

讓我改述評論。你如何知道用戶細節的哪一部分屬於同一用戶?另外爲什麼即使導出2個XML文件,爲什麼不是簡單的1?你想要的是,沒有在其中一個XML文件中的附加信息,是不可能的。將所有內容放在一個xml中,或者將兩個xml文件一起讀取(然後可以將用戶標識從一個文件關聯到另一個文件)。 –

回答

0

您需要將數據傳遞給未來的一步。有關解釋文檔,請參閱http://docs.spring.io/spring-batch/trunk/reference/html/patterns.html#passingDataToFutureSteps

我已經實現了文檔中的示例,並將其調整爲您的配置,並在此處提供了一些假設。

在步驟1中讀取(或寫入,取決於何時要獲取要傳遞的數據)期間,您需要將數據存儲在StepExecution中。添加到您的xmlItemReader如下:

public class YourItemReader implements ItemReader<Object> 
    private StepExecution stepExecution; 

    public void read(Object item) throws Exception { 
     // ... 

     ExecutionContext stepContext = this.stepExecution.getExecutionContext(); 
     stepContext.put("tbl_user", someObject); 
    } 

    @BeforeStep 
    public void saveStepExecution(StepExecution stepExecution) { 
     this.stepExecution = stepExecution; 
    } 

您的XML看起來就像這樣:

<step id="step2_1"> 
    <tasklet transaction-manager="transactionManager"> 
     <chunk reader="xmlItemReader1" writer="databaseItemWriter1" processor="itemProcessor1" commit-interval="100" /> 
    </tasklet>     
    <listeners>     
     <listener ref="testListener" /> 
     <listener ref="promotionListener"/> 
    </listeners> 
</step> 

添加promotionListener豆:

<beans:bean id="promotionListener" class="org.springframework.batch.core.listener.ExecutionContextPromotionListener"> 
    <beans:property name="keys" value="tbl_key"/> 
</beans:bean> 

最後,你需要檢索步驟的價值2.再次假設您在步驟2的閱讀器中需要它,您在步驟2中的閱讀器需要添加以下代碼:

public class YourItemReader2 implements ItemReader<Object> 
    private Object someObject; 

    @BeforeStep 
    public void retrieveInterstepData(StepExecution stepExecution) { 
     JobExecution jobExecution = stepExecution.getJobExecution(); 
     ExecutionContext jobContext = jobExecution.getExecutionContext(); 
     this.someObject = jobContext.get("tbl_key"); 
    } 

現在你有存取權限的步驟中讀取的值1

編輯 - 添加一些示例配置一個額外的讀步:

第1步後添加一個簡單的2步用下面的讀者從數據庫

<bean id="itemReader" class="org.springframework.batch.item.database.JdbcCursorItemReader" 
    scope="step"> 
    <property name="dataSource" ref="dataSource" />    
    <property name="sql"> 
     <value> 
      <![CDATA[ 
       YOUR SELECT STATEMENT 
      ]]> 
     </value> 
    </property> 
    <property name="rowMapper" ref="rowMapper" />  
</bean> 

和簡單的RowMapper豆獲得新的價值

<bean id="rowMapper" class="exampleRowMapper" /> 

你將不得不寫你的exampleRowMapper顯然是爲了反映你提取的數據。例如:

public class ExampleRowMapper implements ParameterizedRowMapper<String> { 

    @Override 
    public String mapRow(ResultSet rs, int rowNum) throws SQLException { 
     return String.valueOf(rs.getString(1)); 
    } 

} 

在您的dummywriter中添加stepexecution,並將您的值存儲在步驟執行上下文中。:

public class DummyItemWriter implements ItemWriter<Object> { 
    private StepExecution stepExecution; 

    @Override 
    public void write(List<? extends Object> item) throws Exception { 
     ExecutionContext stepContext = this.stepExecution.getExecutionContext(); 
     stepContext.put("someKey", someObject); 
    }  
} 

而且對於作家豆:

<bean id="savingDummyWriter" class="your.package.DummyItemWriter" /> 

,敷的工序中的讀者和作家。

<step id="step2"> 
    <tasklet>  
     <chunk reader="itemReader" writer="dummyItemWriter" commit-interval="1" />  
    </tasklet>   
    <listeners> 
     <listener ref="promotionListener"/> 
    </listeners> 
</step> 
+0

感謝您的回答。我的情況有點不同。在步驟1中,我正在讀取xml並寫入tbl_user表,現在該行在插入數據庫時​​正在生成新的主鍵我想將步驟2中的該鍵作爲foriegn鍵用於tbl_userdetail – TaherT

+0

請將該信息添加到您的問題並將問題調整爲更好反映實際問題。所以如果我在第一步之後明白了正確的話,你在你的db中創建了一行。只需在添加的中間步驟中獲取完整行,獲取所需的信息並使用promotionlistener將該信息傳遞給步驟3. –

+0

讓我在users.xml和userdetails.xml中的users.xml userId = 1中對其進行解釋但是當我再次寫入數據庫userId時,它會自動生成爲10,userId = 10現在在userdetails.xml中,因此我需要更改userId = 10而不是1.對於該itemwriter1應提供新生成的userId – TaherT

相關問題