11. DMDLのコンパイル¶
このチュートリアルでは DMDL を利用してAsakusa Frameworkで利用する データモデル を定義する方法を説明していきます。
CSVフォーマットの定義 の続きで、ここではDMDLのコンパイルと データモデルクラス および ジョブフロー入出力基底クラス について説明します。
11.1. データモデルクラスの生成¶
DMDLによるデータモデルの定義 - データモデルクラスを生成する の手順などによってDMDLスクリプトをコンパイルすることで、データモデルクラスが生成されます。
データモデルクラスはバッチアプリケーションを構成する演算子やデータフローの実装などの様々な箇所で利用します。
生成されるデータモデルクラス用のJavaソースファイルは、プロジェクトのソースフォルダ build/generated-sources/modelgen に配置されます。
このフォルダ配下のソースファイルは自動生成の都度更新されるため、直接編集しないよう注意してください。
結合モデルと集計モデルの定義 が終了した状態でデータモデルクラスを生成した場合、
このソースフォルダ配下にはJavaパッケージ com.example.modelgen.dmdl.model を持つ次のデータモデルクラスが存在します。
| クラス名 | 説明 |
|---|---|
SalesDetail |
売上明細 ( sales_detail ) に対応するデータモデルクラス |
StoreInfo |
店舗マスタ ( store_info ) に対応するデータモデルクラス |
ItemInfo |
商品マスタ ( item_info ) に対応するデータモデルクラス |
CategorySummary |
カテゴリ別売上集計 ( category_summary ) に対応するデータモデルクラス |
ErrorRecord |
エラー情報 ( error_record ) に対応するデータモデルクラス |
JoinedSalesInfo |
結合モデル ( joined_sales_info ) に対応するデータモデルクラス |
各データモデルクラスは、DMDLスクリプトで定義したデータモデル名を、CamelCaseの形式に変換したクラス名で生成されます (例: sales_detail -> SalesDetail )。
11.1.1. データモデルクラスのアクセサメソッド¶
各データモデルクラスには、データモデルに定義したプロパティを操作するためのアクセサメソッドが作成されます。
get <プロパティ名>set <プロパティ名>get <プロパティ名> Optionset <プロパティ名> Optionget <プロパティ名> AsString(TEXT型のプロパティのみ )set <プロパティ名> AsString(TEXT型のプロパティのみ )
各メソッドは、DMDLスクリプトで定義したプロパティ名を、CamelCaseの形式に変換したメソッド名で生成されます。
例えば、 sales_detail のプロパティ store_code に対しては、以下のメソッドが作成されます。
public Text getStoreCode()public void setStoreCode(Text)public StringOption getStoreCodeOption()public void setStoreCodeOption(StringOption)public String getStoreCodeAsString()public void setStoreCodeAsString(String)
11.1.2. null値の扱いとOptionメソッド¶
メソッド名の末尾が ...Option となっているメソッドは、 Option クラス型のオブジェクトに対して操作を行うためのメソッドです。これは主に null 値を扱うために利用します。
例えば、値が null のプロパティに対して get <プロパティ名> で値を取得しようとすると NullPointerException が発生します。
一方、 get <プロパティ名> Option を使うとデータ型に対応した Option クラス型のオブジェクトが返却されます。このオブジェクトに対して null に対するチェックなどの操作を行うことができます。
例えば sales_detail ( データモデルクラス SalesDetail ) のプロパティ store_code に対して、StringOption を使った操作は以下のようになります。
private void example(SalesDetail salesDetail) {
StringOption stringOption = salesDetail.getStoreCodeOption();
// isNull メソッドを使って nullチェック
boolean result = stringOption.isNull();
// or メソッドを使って nullの場合に空文字を返す
String storeCode = salesDetail.getStoreCodeOption().or("");
}
DMDLスクリプトに定義したプロパティの型と、データモデルクラスで扱うJavaのデータ型は、以下のように対応します。
| 型の名前 | 対応する型 (Option) |
|---|---|
INT |
int (IntOption) |
LONG |
long (LongOption) |
FLOAT |
float (FloatOption) |
DOUBLE |
double (DoubleOption) |
TEXT |
Text (StringOption) |
DECIMAL |
BigDecimal (DecimalOption) |
DATE |
Date (DateOption) [1] |
DATETIME |
DateTime (DateTimeOption) [2] |
BOOLEAN |
boolean (BooleanOption) |
BYTE |
byte (ByteOption) |
SHORT |
short (ShortOption) |
| [1] | com.asakusafw.runtime.value.Date |
| [2] | com.asakusafw.runtime.value.DateTime |
11.1.3. 文字列の扱いとAsStringメソッド¶
TEXT 型のプロパティに対して、 通常の get <プロパティ名> や set <プロパティ名> で扱うJavaのデータ型はHadoopが提供する org.apache.hadoop.io.Text クラス型です。
Javaの String 型として扱う場合には、 get <プロパティ名> AsString や set <プロパティ名> AsString を使います。
private void example(SalesDetail salesDetail) {
// 通常の getter は 内部で保持する Hadoopの org.apache.hadoop.io.Text をそのまま返す
Text storeCodeAsText = salesDetail.getStoreCode();
// getXXAsString は String型に変換して返す
String storeCodeAsString = salesDetail.getStoreCodeAsString();
// StringOptionでは get は Text型、 getAsString は String型を返す
StringOption stringOption = salesDetail.getStoreCodeOption();
if (stringOption.isNull() == false) {
Text text = stringOption.get()
String str = stringOption.getAsString();
}
}
11.2. ジョブフロー入出力基底クラス¶
CSVフォーマットの定義 のようにしてデータモデルにCSVフォーマットファイルを読み書きする定義を行った場合は データモデルクラスを生成する の手順などによって、バッチアプリケーションの外部入出力情報を定義する「ジョブフロー入出力基底クラス」が合わせて生成されます。
ジョブフロー入出力基底クラスは後のチュートリアル ジョブフローの作成 で利用します。
生成されるジョブフロー入出力基底クラス用のJavaソースファイルは、データモデルクラスと同様にプロジェクトのソースフォルダ build/generated-sources/modelgen に配置されます。
このフォルダ配下のソースファイルは自動生成の都度更新されるため、直接編集しないよう注意してください。
CSVフォーマットの定義 が終了した状態でデータモデルクラスを生成した場合、
このソースフォルダ配下にはJavaパッケージ com.example.modelgen.dmdl.csv を持つ次のデータモデルクラスが存在します。
| クラス名 | 説明 |
|---|---|
AbstractSalesDetailCsvInputDescription |
売上明細 ( sales_detail ) に対応するインポータ記述の基底クラス |
AbstractSalesDetailCsvOutputDescription |
売上明細 ( sales_detail ) に対応するエクスポータ記述の基底クラス |
SalesDetailCsvFormat |
売上明細 ( sales_detail ) に対応するCSVフォーマット実装クラス |
AbstractStoreInfoCsvInputDescription |
店舗マスタ ( store_info ) に対応するインポータ記述の基底クラス |
AbstractStoreInfoCsvOutputDescription |
店舗マスタ ( store_info ) に対応するエクスポータ記述の基底クラス |
StoreInfoCsvFormat |
店舗マスタ ( store_info ) に対応するCSVフォーマット実装クラス |
AbstractItemInfoCsvInputDescription |
商品マスタ ( item_info ) に対応するインポータ記述の基底クラス |
AbstractItemInfoCsvOutputDescription |
商品マスタ ( item_info ) に対応するエクスポータ記述の基底クラス |
ItemInfoCsvFormat |
商品マスタ ( item_info ) に対応するCSVフォーマット実装クラス |
AbstractCategorySummaryCsvInputDescription |
カテゴリ別売上集計 ( category_summary ) に対応するインポータ記述の基底クラス |
AbstractCategorySummaryCsvOutputDescription |
カテゴリ別売上集計 ( category_summary ) に対応するエクスポータ記述の基底クラス |
CategorySummaryCsvFormat |
カテゴリ別売上集計 ( category_summary ) に対応するCSVフォーマット実装クラス |
AbstractErrorRecordCsvInputDescription |
エラー情報 ( error_record ) に対応するインポータ記述の基底クラス |
AbstractErrorRecordCsvOutputDescription |
エラー情報 ( error_record ) に対応するエクスポータ記述の基底クラス |
ErrorRecordCsvFormat |
エラー情報 ( error_record ) に対応するCSVフォーマット実装クラス |
各ジョブフロー入出力基底クラスは、DMDLスクリプトで定義したデータモデル名からCamelCaseの形式に変換したクラス名にして、前後に各クラスの役割に応じた名前が付加されます。
(例: sales_detail -> AbstractSalesDetailCsvInputDescription )。