前回(第2章-①)では、CDSとは何かという基礎知識と、最初のEntity「Books」の作成、そして基本データ型の考え方について整理しました。
今回は、主キーの定義方法をもう少し詳しく見たうえで、String・Decimal・Date・Timestampといった主要なデータ型を実際にBooksエンティティに追加し、さらにcuid・managedというアスペクトを使って、ABAPで毎回手作業だった共通項目を自動化する方法を見ていきます。
主キーを定義する|key・Integer・UUIDの使い分け
CDSでは、keyキーワードをフィールドの前に付けることで、そのフィールドを主キーとして定義します。
entity Books {
key ID : Integer;
...
}
copy
ABAPのテーブル定義では、キー項目をキー項目群として先頭にまとめて定義しますが、CDSでは各フィールドの前に個別にkeyを付けていく点が異なります。
複合キーにしたい場合は、複数のフィールドにkeyを付けます。
entity BookGenres {
key book : Integer;
key genre : String(40);
}
copy
主キーの型としてよく使われるのは、Integer(連番)とUUIDの2つです。それぞれの特徴を整理します。
Integerを主キーにする場合
entity Books {
key ID : Integer;
...
}
copy
ABAPで言えば、採番オブジェクト(NUMBER RANGE)で連番を発行し、それをキーにするイメージに近いです。
ただし注意点として、CDSのInteger型キーは自動採番(オートインクリメント)にはなりません。
値の採番は、アプリケーション側(Java)で自分で行う必要があります。
UUIDを主キーにする場合
entity Books {
key ID : UUID;
...
}
copy
UUID型は、値そのものはString(36)として保持されますが、「これは一意識別子である」という意味を明示する型です。
CAPの世界では、後述するcuidという仕組みを使うことで、UUIDの主キーを自動生成してくれるため、実務上はこちらが標準的な選択になることが多いです。
ABAPの世界でも、GUID型(SYSUUID_X16など)をキーに使うテーブル設計はありますが、多くのSAP標準テーブルは連番ベースの伝票番号などをキーにしてきたと思います。
CAPでは、分散環境(複数のインスタンスが同時にレコードを作成する可能性がある環境)を前提に設計されているため、採番の重複が起こり得るInteger連番よりも、UUIDが標準的に好まれる傾向があります。
この設計思想の違いは、最初に少し意識しておくとよいポイントです。
String・Decimal・Date・Timestampを使ってみる
主キー以外のフィールドも増やして、Booksエンティティをもう少し実用的な形にしてみましょう。
namespace my.bookshop;
entity Books {
key ID : UUID;
title : String(30);
stock : Integer;
price : Decimal(9,2);
releaseDate : Date;
}
copy
- title:本のタイトル。文字列なのでString
- stock:在庫数。小数を扱わないのでInteger
- price:価格。金額なので誤差の出ないDecimal(全体で9桁、小数点以下2桁)
- releaseDate:発売日。日付のみを扱うのでDate
Decimal(9,2)のような書き方は、ABAPでDEC 9,2のように精度と小数桁数を指定してきた感覚とほぼ同じです。
金額項目にDouble(浮動小数点)を使ってはいけない、という感覚も、ABAPでの経験がそのまま活きるポイントだと思います。
Timestamp型については、次に説明するmanagedアスペクトを通じて自然に登場するので、ここでは型の存在だけ押さえておいてください。
Timestampは日付+時刻に加えてタイムゾーン情報を持つ点が、ABAPのTIMESTAMPL(UTC基準のロングタイムスタンプ)に近い性質です。
cuidとmanagedを使って共通項目を自動追加する
ABAP開発では、多くのテーブルに「作成日」「作成者」「変更日」「変更者」といった項目を、ほぼお決まりのパターンとして毎回追加してきたのではないかと思います。CDSには、こうした定型項目をまとめて追加できる仕組みが標準で用意されています。それがアスペクト(Aspect)と呼ばれる機能です。
CAPが標準で提供している@sap/cds/commonパッケージには、代表的なアスペクトとしてcuidとmanagedがあります。
namespace my.bookshop;
using { cuid, managed } from '@sap/cds/common';
entity Books : cuid, managed {
title : String(30);
stock : Integer;
price : Decimal(9,2);
releaseDate : Date;
}
copy
entity Books : cuid, managed { … }という書き方で、Booksエンティティにcuidとmanagedというアスペクトをそれぞれ「継承」させています。
cuidアスペクトの中身
aspect cuid {
key ID : UUID;
}
copy
cuidを継承すると、key ID : UUID;という主キー定義が自動的に追加されます。
しかも、レコードを新規作成する際にUUIDの値を自分で採番する必要はありません。CAPのフレームワークが、レコード作成時に自動的にUUIDを生成して設定してくれます。
managedアスペクトの中身
aspect managed {
createdAt : Timestamp @cds.on.insert: $now;
createdBy : User @cds.on.insert: $user;
modifiedAt : Timestamp @cds.on.insert: $now @cds.on.update: $now;
modifiedBy : User @cds.on.insert: $user @cds.on.update: $user;
}
copy
managedを継承すると、作成日時・作成者・更新日時・更新者の4項目が自動で追加され、レコードの作成・更新時にフレームワークが自動的に値をセットしてくれます。
これは、ABAPでいうところの「ERDAT/ERNAM/AEDAT/AENAM のような標準項目を、新規テーブルを作るたびに手作業で追加し、さらにユーザーイグジットやBAdIで値をセットしていた作業」が、アスペクトを1行継承するだけで完結してしまうというイメージです。長年、同じような定型項目を何度も追加してきたABAPerであれば、この便利さはすぐに実感できるはずです。
次の記事(第2章-③)では、テーブル同士の関係を表すAssociationとComposition、CDS Viewの作成方法、そしてCSVファイルからの初期データ登録について見ていきます。
引き続き、頑張っていきましょう。頑張れABAPer。

コメント