LoginSignup
4
4

More than 5 years have passed since last update.

BeanIOでCSVや固定長データとJavaクラスをマッピング

Last updated at Posted at 2016-07-16

BeanIOとは

ApacheのJavaライブラリ。CSV・固定長データ・XMLなどをJavaクラスにマッピングできる。
ここ数年更新されておらず、日本語の記事も皆無なので、このライブラリを使うのがベストなのか分からないけど、特定の場面では有効かなと思います。

リファレンス(英語)はこちら。
http://beanio.org/2.1/docs/reference/index.html#FixedLengthStreamFormat
英語読める人はリファレンス読めばいいけど、所どころサンプルコードに間違いがあったので注意して下さい。

導入

Mavenの場合。

<dependency>
  <groupId>org.beanio</groupId>
  <artifactId>beanio</artifactId>
  <version>2.1.0</version>
</dependency>

zipはこちら。
https://code.google.com/archive/p/beanio/downloads

CSV→オブジェクト

手始めにCSV→オブジェクトのマッピングをしてみる。
まず、CSVファイルと、CSVの各項目に対応するフィールドを持つクラスを作成する。

CSVファイル

employee.csv
Joe,Smith,11000000,20091001,Developer
Jane,Doe,12000000,20080115,Architect
Jon,Anderson,6000000,20100318,Manager

マッピングするクラス

Employee.java
package example;
import java.util.Date;

public class Employee {
    String firstName;
    String lastName;
    int salary;
    Date hireDate;
    String title;
    // 省略しているが、getter,setterも必要
}

で、CSVとクラスのマッピング定義を作成する。

マッピング定義

mapping.xml
<beanio xmlns="http://www.beanio.org/2012/03"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.beanio.org/2012/03 http://www.beanio.org/2012/03/mapping.xsd">

    <stream name="employeeFile" format="csv" >
        <parser>
            <property name="delimiter" value="," />
        </parser>
        <record name="employee" class="example.Employee" >
            <field name="firstName" />
            <field name="lastName" />
            <field name="salary" />
            <field name="hireDate" format="yyyyMMdd" />
            <field name="title" />
        </record>
    </stream>
</beanio>

fieldの定義順が対象データの順番と対応している。
デフォルトで区切り文字がカンマなので、この場合parserタグは無くてもいい。
区切り文字を変えたい場合はvalueの値を変更して下さい。

これで準備OK。実際の変換処理を書いてみる。

BeanReaderExample.java
package example;

import org.beanio.BeanReader;
import org.beanio.StreamFactory;
import java.io.File;

public class BeanReaderExample {
    public static void main(String[] args) {
        // マッピング定義を指定して、ファクトリを生成
        StreamFactory factory = StreamFactory.newInstance();
        factory.load("src/main/resources/mapping.xml");
        // ファクトリからBeanReaderを生成
        // 第1引数にマッピング定義のstream名を指定する
        BeanReader reader = factory.createReader("employeeFile", new File("src/main/resources/employee.dat"));
        // BeanReaderを使ってCSVの内容をオブジェクトにセット
        Employee employee;
        while ((employee = (Employee) reader.read()) != null) {
            System.out.println("FirstName : " + employee.getFirstName());
            System.out.println("LastName  : " + employee.getLastName());
            System.out.println("Salary    : " + employee.getSalary());
            System.out.println("HireDate  : " + employee.getHireDate());
            System.out.println("Title     : " + employee.getTitle());
            System.out.println();
        }
        reader.close();
    }
}

実行すると、出力結果は以下のようになる。

FirstName : Joe
LastName  : Smith
Salary    : 11000000
HireDate  : Thu Oct 01 00:00:00 JST 2009
Title     : Developer

FirstName : Jane
LastName  : Doe
Salary    : 12000000
HireDate  : Tue Jan 15 00:00:00 JST 2008
Title     : Architect

FirstName : Jon
LastName  : Anderson
Salary    : 6000000
HireDate  : Thu Mar 18 00:00:00 JST 2010
Title     : Manager

マッピングできてますね。

固定長データ→オブジェクト

固定長データ

employee.dat
Joe       Smith     01100000020091001Developer
Jane      Doe       01200000020080115Architect
Jon       Anderson  00600000020100318Manager

データ長の定義は、
名前=10桁, 姓=10桁, 年収=9桁, 雇用日=8桁, 肩書き=可変長
としています。

固定長と言いつつ、末尾だけは可変長です。
マッピングするクラス(Employee.java)はCSVの時と同じ。

マッピング定義は固定長用に変更する必要があります。

マッピング定義

mapping.xml
<beanio xmlns="http://www.beanio.org/2012/03"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.beanio.org/2012/03 http://www.beanio.org/2012/03/mapping.xsd">

    <stream name="employeeFile" format="fixedlength" >
        <record name="employee" class="example.Employee" >
            <field name="firstName" length="10" />
            <field name="lastName" length="10" />
            <field name="salary" length="9" />
            <field name="hireDate" length="8" format="yyyyMMdd" />
            <field name="title" length="unbounded" />
        </record>
    </stream>
</beanio>

streamタグのformatを"csv"から"fixedlength"に変更し、fieldタグにlengthを追加。
末尾のみ可変長にできるので、"unbounded"を指定しています。

実際の変換処理(BeanReaderExample.java)と出力結果はCSVの時と同じ。

その他

今回はCSV、固定長データ→オブジェクトへのマッピングのみでしたが、XMLのマッピングも当然可能です。
ただ、XMLについてはJAXBとかあるし、BeanIO使う利点が分かっていないので、扱っていません。

また、オブジェクト→CSV等への変換も可能です。気が向いたら後日まとめるかも。

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4