2016-08-04 70 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

相关问题