Springバッチの例 - MongoDBデータベースへのXMLファイル

Spring Batchの例– XMLファイルからMongoDBデータベースへ

このチュートリアルでは、XMLファイル(XStreamライブラリ)からSQLなしのデータベース(MongoDB)にデータを読み取るようにSpringBatchジョブを構成する方法を示します。 さらに、単体テストケースを作成して、バッチジョブを起動およびテストします。

使用するツールとライブラリ

  1. メーベン3

  2. Eclipse 4.2

  3. JDK 1.6

  4. Spring Core 3.2.2.RELEASE

  5. Spring Batch 2.2.0.RELEASE

  6. Spring Batch Test 2.2.0.RELEASE

  7. Spring OXM 3.2.2.RELEASE

  8. MongoDB Javaドライバー2.11.2

  9. MongoDB 2.2.3

  10. jUnit 4.11

  11. TestNG 6.8.5

P.S This example – XML file (reader) – MongoDB (writer).

1. シンプルなJavaプロジェクト

1. MavenでクイックスタートJavaプロジェクトを作成し、変換してEclipse IDEにインポートします。

$ mvn archetype:generate -DgroupId=com.example -DartifactId=SpringBatchExample2
  -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
$ cd SpringBatchExample/
$ mvn eclipse:eclipse

2. プロジェクトの依存関係

pom.xmlですべてのプロジェクトの依存関係を宣言します

pom.xml


    4.0.0
    com.example
    SpringBatchExample
    jar
    1.0-SNAPSHOT
    SpringBatchExample
    http://maven.apache.org

    
        1.6
        3.2.2.RELEASE
        2.2.0.RELEASE
        1.2.1.RELEASE
        2.11.2
    

    

        
        
            org.springframework
            spring-core
            ${spring.version}
        

        
        
            org.springframework
            spring-oxm
            ${spring.version}
        

        
        
            org.springframework.batch
            spring-batch-core
            ${spring.batch.version}
        
        
            org.springframework.batch
            spring-batch-infrastructure
            ${spring.batch.version}
        

        
        
            org.springframework.batch
            spring-batch-test
            ${spring.batch.version}
        

        
        
            org.mongodb
            mongo-java-driver
            ${mongodb.driver.version}
        

        
        
            org.springframework.data
            spring-data-mongodb
            ${spring.data.version}
        

        
        
            junit
            junit
            4.11
            test
        

        
        
            org.testng
            testng
            6.8.5
            test
        

    
    
        spring-batch
        
        
            org.apache.maven.plugins
            maven-eclipse-plugin
            2.9
            
                true
                false
            
        
        
            org.apache.maven.plugins
            maven-compiler-plugin
            2.3.2
            
                ${jdk.version}
                ${jdk.version}
            
        
        
    

3. プロジェクトのディレクトリ構造

最終的なプロジェクト構造を確認し、次に何が起こるのか概要を把握します。

spring batch - xml to mongodb

4. XMLファイル

これは、リソースフォルダー内のXMLファイルです。

resources/xml/report.xml


    
        6/1/2013
        139,237
        40
        220.90
    
    
        6/2/2013
        339,100
        60
        320.88
    
    
        6/3/2013
        431,436
        76
        270.80
    

5. XMLファイルを読み取る

Springバッチでは、StaxEventItemReaderを使用してXMLファイルを読み取り、XStreamMarshallerを使用してXML値と属性をオブジェクトにマップできます。

resources/spring/batch/jobs/job-report.xml

    
    
    
    
    
    

    

    
        
        
        
    
    
        
        
        
    

    

    

Report.java

package com.example.model;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Report {

    private int id;
    private Date date;
    private long impression;
    private int clicks;
    private BigDecimal earning;

    //getter and setter methods

}

XML値をDateBigDecimalなどの「複雑な」データ型にマップするには、カスタムconverterをアタッチして、値を手動で変換およびマップする必要があります。

ReportConverter.java

package com.example.converter;

import java.math.BigDecimal;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

import com.example.model.Report;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;

public class ReportConverter implements Converter {

    @Override
    public boolean canConvert(Class type) {
        //we only need "Report" object
        return type.equals(Report.class);
    }

    @Override
    public void marshal(Object source,
            HierarchicalStreamWriter writer, MarshallingContext context) {
        //do nothing
    }

    @Override
    public Object unmarshal(
            HierarchicalStreamReader reader, UnmarshallingContext context) {

        Report obj = new Report();

        //get attribute
        obj.setId(Integer.valueOf(reader.getAttribute("id")));
        reader.moveDown(); //get date

        Date date = null;
        try {
            date = new SimpleDateFormat("M/d/yyyy").parse(reader.getValue());
        } catch (ParseException e) {
            e.printStackTrace();
        }
        obj.setDate(date);
        reader.moveUp();

        reader.moveDown(); //get impression

        String impression = reader.getValue();
        NumberFormat format = NumberFormat.getInstance(Locale.US);
                Number number = 0;
        try {
            number = format.parse(impression);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        obj.setImpression(number.longValue());

        reader.moveUp();

        reader.moveDown(); //get click
        obj.setClicks(Integer.valueOf(reader.getValue()));
        reader.moveUp();

        reader.moveDown(); //get earning
        obj.setEarning(new BigDecimal(reader.getValue()));
                reader.moveUp();

                return obj;

    }
}

6. MongoDBデータベース

mongodbインスタンスと、mongoTemplateを定義します。

resources/spring/batch/config/database.xml



        
    
    

    
        
    

7. Spring Batchコア設定

jobRepositoryjobLauncherを定義します。

resources/spring/batch/config/context.xml



    
    
    
    

    


    
    
    

8. 春のバッチジョブ

Springバッチジョブ。report.xmlファイルを読み取り、Reportオブジェクトにマップして、MongoDBに書き込みます。 コメントを読んでください、それは自明であるべきです。

resources/spring/batch/jobs/job-report.xml



    
    
      
        
        
      
    
    

    
    
    
    
    
    

    
    
    
      
        
      
    

        
    
      
        
      
    

    

    

    //write it to MongoDB, 'report' collection (table)
    
    
    
    

9. 単体テスト

jUnitまたはTestNGフレームワークを使用して単体テストを行います。最初に、JobLauncherTestUtilsを手動で宣言する必要があります。

test/resources/spring/batch/config/test-context.xml



    
    

jUnitの例

AppTest.java

package com.example;

import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.test.JobLauncherTestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
    "classpath:spring/batch/jobs/job-report.xml",
    "classpath:spring/batch/config/context.xml",
    "classpath:spring/batch/config/database.xml",
    "classpath:spring/batch/config/test-context.xml"})
public class AppTest {

    @Autowired
    private JobLauncherTestUtils jobLauncherTestUtils;

    @Test
    public void launchJob() throws Exception {

        //JobExecution jobExecution = jobLauncherTestUtils.launchJob();

        JobExecution jobExecution = jobLauncherTestUtils.launchStep("step1");

        assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus());

    }
}

TestNGの例

AppTest2.java

package com.example;

import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.test.JobLauncherTestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.testng.Assert;
import org.testng.annotations.Test;

@ContextConfiguration(locations = {
    "classpath:spring/batch/jobs/job-report.xml",
    "classpath:spring/batch/config/context.xml",
    "classpath:spring/batch/config/database.xml",
    "classpath:spring/batch/config/test-context.xml"})
public class AppTest2 extends AbstractTestNGSpringContextTests {

    @Autowired
    private JobLauncherTestUtils jobLauncherTestUtils;

    @Test
    public void launchJob() throws Exception {

        JobExecution jobExecution = jobLauncherTestUtils.launchJob();
        Assert.assertEquals(jobExecution.getStatus(), BatchStatus.COMPLETED);

    }
}

出力。 XML値がMongoDBに挿入されます。

mongo
MongoDB shell version: 2.2.3
connecting to: test

> use yourdb
switched to db yourdb
> show collections
report
system.indexes

> db.report.find()
{ "_id" : 1, "_class" : "com.example.model.Report",
"date" : ISODate("2013-05-31T16:00:00Z"), "impression" : NumberLong(139237),
"clicks" : 40, "earning" : "220.90" }

{ "_id" : 2, "_class" : "com.example.model.Report",
"date" : ISODate("2013-06-01T16:00:00Z"), "impression" : NumberLong(339100),
"clicks" : 60, "earning" : "320.88" }

{ "_id" : 3, "_class" : "com.example.model.Report",
"date" : ISODate("2013-06-02T16:00:00Z"), "impression" : NumberLong(431436),
"clicks" : 76, "earning" : "270.80" }
>

10. ジョブメタデータはどうですか?

申し訳ありませんが、これに対する解決策はまだありません。 私が知っているように、ジョブの再起動性とロールバックを保証するために、ジョブメタデータにはリレーショナルデータベースが必要です。 MongoDBには、設計上、「強固な」トランザクション管理がありません。

解決策1:別のリレーショナルデータベースを作成して、ジョブメタデータを保存します。 もっと良いアイデアはありますか?

解決策2:Springのチームがこの解決策を発表するのを待ちます。

ソースコードをダウンロード

ダウンロード–SpringBatch-XML-MongoDB-Example.zip(81 kb)