2016-07-17 9 views
1

を使用してデータベースへの書き込み、私はXMLを読み、MySQLデータベースXMLを読み、春のバッチ

<?xml version="1.0" encoding="UTF-8"?> 
<parentNode id="001" name="p1" type="t1"> 
    <line>message1</line> 
    <line>message2</line> 
    <line>message3</line> 
    <line>message4</line> 
</parentNode> 

にそれを書きたい、私は、次のリーダー

@XmlRootElement(name = "parentNode") 
public class ParentNode { 
    private String id; 
    private String name; 
    private String type; 
    private List<String> lineNode; 

    @XmlAttribute(name = "id") 
    public String getId() { 
     return id; 
    } 

    public void setId(String id) { 
     this.id = id; 
    } 

    @XmlAttribute(name = "name") 
    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    @XmlAttribute(name = "type") 
    public String getType() { 
     return type; 
    } 

    public void setType(String type) { 
     this.type = type; 
    } 

    @XmlElement(name = "line") 
    public List<String> getLineNode() { 
     return lineNode; 
    } 

    public void setLineNode(List<String> lineNode) { 
     this.lineNode = lineNode; 
    } 
} 

を持って、私はライターを持っています

public class ParentNodeItemPreparedStatementSetter implements ItemPreparedStatementSetter<ParentNode> { 

@Override 
public void setValues(ParentNode parentNode, PreparedStatement ps) throws SQLException { 
    ps.setString(1, parentNode.getId()); 
    ps.setString(1, parentNode.getLineNode()); //HOW DO I WRITE EACH LINE INSTEAD OF ONLY THE LAST ONE 

} 

どのように3つすべてを書きますか?lineをデータベースに追加します。このコードは、<line>message4</line>message4のみをデータベースに書き込みます。 私は以下のようにParentNodeItemPreparedStatementSetterを変更することによって、私は必要なものを手に入れることができる午前:私は、データベースが

<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:batch="http://www.springframework.org/schema/batch" 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-3.0.xsd 
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"> 

    <import resource="classpath:context-datasource.xml" /> 

    <!-- JobRepository and JobLauncher are configuration/setup classes --> 
    <bean id="jobRepository" 
     class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean" /> 

    <bean id="jobLauncher" 
     class="org.springframework.batch.core.launch.support.SimpleJobLauncher"> 
     <property name="jobRepository" ref="jobRepository" /> 
    </bean> 

    <bean id="xmlItemReaderStep" class="org.springframework.batch.item.xml.StaxEventItemReader"> 
     <property name="resource" value="classpath:test.xml" /> 
     <property name="fragmentRootElementName" value="parentNode" /> 
     <property name="unmarshaller"> 
      <bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller"> 
       <property name="classesToBeBound"> 
        <list> 
         <value>com.results.model.ParentNode</value> 
        </list> 
       </property> 
      </bean> 
     </property> 
    </bean> 

    <bean id="resultsWriter" 
     class="org.springframework.batch.item.database.JdbcBatchItemWriter"> 
     <property name="dataSource" ref="dataSource" /> 
     <property name="sql"> 
      <value> 
       <![CDATA[   
        insert into playground.LINE(id, line) values (?, ?); 
       ]]> 
      </value> 
     </property> 
     <property name="ItemPreparedStatementSetter"> 
      <bean 
       class="com.results.preparedstatement.ParentNodeItemPreparedStatementSetter" /> 
     </property> 
    </bean> 

    <bean id="itemProcessor" 
     class="com.results.itemprocessors.ParentNodeItemProcessor" /> 


    <bean id="transactionManager" 
     class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" /> 


    <batch:job id="resultJob"> 
     <batch:step id="step1"> 
      <batch:tasklet transaction-manager="transactionManager"> 
       <batch:chunk reader="xmlItemReaderStep" writer="resultsWriter" 
        processor="itemProcessor" commit-interval="100" /> 
      </batch:tasklet> 
     </batch:step> 
    </batch:job> 

</beans> 

EDITは、次のように

ID | LINE 
001 | message1 
001 | message2 
001 | message3 
001 | message4 

私の設定がある持っていると思います。しかし、それは正しい方法ではないように見えます。

public class ParentNodeItemPreparedStatementSetter implements ItemPreparedStatementSetter<ParentNode> { 
@Override 
public void setValues(ParentNode parentNode, PreparedStatement ps) throws SQLException { 
    for (int i = 0; i < parentNode.getLineNode().size(); i++) { 
     ps.setString(1, parentNode.getId()); 
     ps.setString(2, parentNode.getLineNode().get(i)); 
     if (!(i == parentNode.getLineNode().size()-1)) 
      ps.addBatch(); 
    } 
} 

}

+0

すべてのspring xml confを表示できますか? – davidxxx

+0

@ davidhxxx私は完全な設定で更新しました –

答えて

1

あなたが期待している間にマッチングされていないようです:

ID | LINE 
001 | message1 
001 | message2 
001 | message3 
001 | message4 

とあなた二つの入力の構造:入力で

<?xml version="1.0" encoding="UTF-8"?> 
<parentNode id="001" name="p1" type="t1"> 
    <line>message1</line> 
    <line>message2</line> 
    <line>message3</line> 
    <line>message4</line> 
</parentNode> 


@XmlRootElement(name = "parentNode") 
public class ParentNode { 
    private String id; 
    private String name; 
    private String type; 
    private List<String> lineNode; 
    ... 

、あなたは1を持っていますあなたの読者が仕事を終えた後に、あなたのxmlの中の一行とそれゆえに一つのParentNodeインスタンスあなたのテーブルには、lineNodeリストの要素と同じ数の行がありたいので、4行になります。 対称ではありません。

実際の入力XML構造が必要な場合は、何も変更せずに、書き込み中にカスタムマッピングを実行します。

そして、いくつかの方法で、あなたはParentNodeItemPreparedStatementSetterでlineNodeリスト内の要素として多くの行として追加していることを実行します。

for (int i = 0; i < parentNode.getLineNode().size(); i++) { 
    ps.setString(1, parentNode.getId()); 
    ps.setString(2, parentNode.getLineNode().get(i)); 
    if (!(i == parentNode.getLineNode().size()-1)) 
     ps.addBatch(); 
} 

それはトリックですが、ドキュメントに従って、それは悪くないようだ。

RowMapperのの逆数として効果的に機能するSQL更新のためItemPreparedStatementSetter

便利戦略、パブリックインターフェイス。

:あなたのコメントに答える。 実際の入力XML構造が、例えば生成されたために変更できる場合は、期待通りのXML構造を設計することができます。

<?xml version="1.0" encoding="UTF-8"?> 
<parentNode id="001" name="p1" type="t1"> 
    <line parent-id="001">message1</line> 
    <line parent-id="001">message2</line> 
    <line parent-id="001">message3</line> 
    <line parent-id="001">message4</line> 
</parentNode> 

そして、あなたのリーダーconfのXMLでは、あなたはまた、あなたの構造を変更する必要があり<property name="fragmentRootElementName" value="line" />

によって

<property name="fragmentRootElementName" value="parentNode" /> 

を置き換えます:あなたは親-id値を追加する必要があります入力で xmlオブジェクト。あなたの行を変更するString型から、必要な2つのフィールド(idとline)を所有する独自のクラスに一覧表示します。 このようにして、1つの処理を行わずに、入力と出力に予想されるデータを持つことができます。

+0

あなたの応答に感謝します。あなたは、私のプロジェクト構造で何が変更されなければならないか教えてください。私は 'バネバッチ'を初めて使っています。必要ならばgithubでプロジェクトをチェックすることができます。 –

+0

解決策は悪くありません。私はそれを保つことができると思います。 プロジェクトの構造ではなく、モデルの構造を参照しています。 しかし、あなたのParentNode構造があなたのニーズに合っていれば、それを変更することは強制されません。 対称構造が必要な場合は、出力(テーブル) – davidxxx

+0

Okに必要な数の行を入力する必要があります。ありがとう。どのようにモデル構造を変更しますか?私はベストプラクティスを勉強しようとしているだけです –

関連する問題