モデルコード、永続性コード、およびサービスコードの生成
サービスビルダーを使用すると、モデルを簡単に定義し、モデルコード、永続性コード、およびサービスコードを生成できます。 これは、Y7G4Entry
というモデルを定義し、サービスビルダーを使用してコードを生成することで体験できます。 次に、コードをDXPにデプロイし、そのコードを使用するサービスを呼び出します。
サンプルプロジェクトをダウンロードする
サンプルプロジェクトをダウンロードして解凍します。
curl https://resources.learn.liferay.com/dxp/latest/ja/building-applications/data-frameworks/service-builder/service-builder-basics/liferay-y7g4.zip -O
unzip liferay-y7g4.zip
liferay-y7g4
プロジェクトには、次の2つのモジュールがあります。
y7g4-api
y7g4-service
APIモジュール(-api
)は、パブリックインターフェイスとユーティリティを提供します。 サービスモジュール(-service
)は実装を提供します。
APIモジュールを調べる
APIモジュールには、bndメタデータファイルとGradleビルドファイルしかありません。
y7g4-api
├── bnd.bnd // Defines the module artifact, package exports, and includes the service XML file
└── build.gradle // Declares dependencies
bnd.bnd
ファイルは次のとおりです。
Bundle-Name: Acme Y7G4 API
Bundle-SymbolicName: com.acme.y7g4.api
Bundle-Version: 1.0.0
Export-Package:\
com.acme.y7g4.exception,\
com.acme.y7g4.model,\
com.acme.y7g4.service,\
com.acme.y7g4.service.persistence
Bundle-
ヘッダーはモジュールアーティファクトを説明します。 Export-Package
ヘッダーは公開するAPIパッケージを指定します。 bndメタデータの詳細とその使用方法については モジュールプロジェクト を参照してください。
build.gradle
ファイルは、モジュールのDXP/Portalへの依存を宣言します。
dependencies {
compileOnly group: "com.liferay.portal", name: "release.portal.api"
}
サービスモジュールを調べる
サービスモジュールには、bndメタデータファイル、Gradleビルドファイル、およびサービス定義ファイルがあります。
y7g4-service
├── bnd.bnd // Defines the module artifact, data schema version, and more
├── build.gradle // Declares dependencies and code generation parameters
└── service.xml // Specifies models and their relationships
bnd.bnd
ファイルは次のとおりです。
Bundle-Name: Acme Y7G4 Service
Bundle-SymbolicName: com.acme.y7g4.service
Bundle-Version: 1.0.0
Liferay-Require-SchemaVersion: 1.0.0
Liferay-Service: true
-dsannotations-options: inherit
繰り返しになりますが、Bundle-
ヘッダーはモジュールアーティファクトを説明します。 サービスメタデータとディレクティブが続きます。
メタデータ | 説明 |
---|---|
Liferay-Require-SchemaVersion: 1.0.0 |
アプリケーションのデータスキーマバージョン。 データベーススキーマの変更を伴うアプリケーションのバージョンをリリースする場合、バージョンをインクリメントすることになります。 |
Liferay-Service: true |
このモジュールはLiferay Serviceを提供します。 |
-dsannotations-options: inherit |
OSGiサービスコンポーネントクラスは、クラス階層から OSGi宣言型サービスのアノテーションを継承しています。 例えば、拡張クラスは @Reference アノテーションを介して、祖先のフィールドが参照するすべてのサービスにアクセスすることができます。 |
build.gradle
ファイルはこちら:
buildService {
apiDir = "../y7g4-api/src/main/java"
}
dependencies {
compileOnly group: "com.liferay.portal", name: "release.portal.api"
compileOnly project(":y7g4-api")
}
buildService
タスクは、サービスのAPIクラスをapiDir
で指定されたAPIモジュールのJavaソースフォルダに生成します。 サービスモジュールは、DXP/PortalおよびAPIモジュール(兄弟フォルダy7g4-api
内)に依存します。
サービスモデルの定義を調べる
service.xml
ファイルは、Y7G4Entry
モデルエンティティを定義します。 サービスビルダーは、service.xml
ファイルの仕様に従って、モデル、永続性、およびサービスクラスを生成します。
service.xml
ファイルは次のとおりです。
<?xml version="1.0"?>
<!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 7.4.0//EN" "http://www.liferay.com/dtd/liferay-service-builder_7_4_0.dtd">
<service-builder dependency-injector="ds" package-path="com.acme.y7g4" short-no-such-exception-enabled="false">
<namespace>Y7G4</namespace>
<entity local-service="true" name="Y7G4Entry" remote-service="false">
<!-- PK fields -->
<column name="y7g4EntryId" primary="true" type="long" />
<!-- Other fields -->
<column name="description" type="String" />
<column name="name" type="String" />
</entity>
</service-builder>
このファイルでは、ID(主キー)、名前、説明を持つ Y7G4Entry
というモデルを定義します。
service-builder
要素
service-builder
要素の属性は service.xml
ファイル内のすべてのモデルエンティティに影響します。
service-builder 属性 |
説明 |
---|---|
dependency-injector |
依存性インジェクターの種類を宣言します。 宣言型サービス (ds ) がデフォルトです。 |
package-path |
生成されるクラスの先頭のパッケージパスを宣言します。 |
short-no-such-exception-enabled |
true に設定すると、 NoSuchY7G4EntryException メッセージでエンティティ名の短縮版を使用し、それ以外の場合は完全なエンティティ名を使用します。 |
namespace
要素
グローバルなnamespace
要素は、すべてのモデルエンティティデータベーステーブルの接頭辞を指定します。
entity
要素
entity
要素は、モデルデータベースのテーブルとサービスタイプを定義します。
entity 属性 |
説明 |
---|---|
name |
エンティティの名前。 サービスビルダーは、[namespace]_[name] という命名形式(例えば、Y7G4_Y7G4Entry など)でエンティティテーブルを生成します。 |
local-service |
true の場合、JVM内から呼び出すサービスクラスを生成します。 |
| remote-service | true の場合、Webサービスクラスを含むサービスクラスを生成し、JVMの外から呼び出せるようにします。 |
column
要素
各 column
要素は、エンティティのテーブル内のカラムを定義します。 以下は Y7G4Entry
のエンティティ列の要素です。
列 | 説明 |
---|---|
y7g4EntryId |モデルインスタンスのID (長整数) とプライマリーキーです。 |
|
name |
インスタンスの名前(文字列)です。 |
description |
インスタンスの説明 (文字列) です。 |
service.xml
要素の詳細については、 Liferayサービスビルダー DTD を参照してください。
永続化コードの生成
サービスビルダーを起動し、永続化コードとデータベーススクリプトを生成します。
cd liferay-y7g4
./gradlew y7g4-service:buildService
出力:
> Task :y7g4-service:buildService
Building Y7G4Entry
Writing src/main/java/com/acme/y7g4/service/persistence/impl/Y7G4EntryPersistenceImpl.java
Writing ../y7g4-api/src/main/java/com/acme/y7g4/service/persistence/Y7G4EntryPersistence.java
Writing ../y7g4-api/src/main/java/com/acme/y7g4/service/persistence/Y7G4EntryUtil.java
Writing src/main/java/com/acme/y7g4/service/persistence/impl/Y7G4EntryModelArgumentsResolver.java
Writing src/main/java/com/acme/y7g4/model/impl/Y7G4EntryModelImpl.java
Writing src/main/java/com/acme/y7g4/model/impl/Y7G4EntryBaseImpl.java
Writing src/main/java/com/acme/y7g4/model/impl/Y7G4EntryImpl.java
Writing ../y7g4-api/src/main/java/com/acme/y7g4/model/Y7G4EntryModel.java
Writing ../y7g4-api/src/main/java/com/acme/y7g4/model/Y7G4Entry.java
Writing src/main/java/com/acme/y7g4/model/impl/Y7G4EntryCacheModel.java
Writing ../y7g4-api/src/main/java/com/acme/y7g4/model/Y7G4EntryWrapper.java
Writing ../y7g4-api/src/main/java/com/acme/y7g4/model/Y7G4EntrySoap.java
Writing ../y7g4-api/src/main/java/com/acme/y7g4/model/Y7G4EntryTable.java
Writing src/main/java/com/acme/y7g4/service/impl/Y7G4EntryLocalServiceImpl.java
Writing src/main/java/com/acme/y7g4/service/base/Y7G4EntryLocalServiceBaseImpl.java
Writing ../y7g4-api/src/main/java/com/acme/y7g4/service/Y7G4EntryLocalService.java
Writing ../y7g4-api/src/main/java/com/acme/y7g4/service/Y7G4EntryLocalServiceUtil.java
Writing ../y7g4-api/src/main/java/com/acme/y7g4/service/Y7G4EntryLocalServiceWrapper.java
Writing src/main/resources/META-INF/module-hbm.xml
Writing src/main/resources/META-INF/portlet-model-hints.xml
Writing ../y7g4-api/src/main/java/com/acme/y7g4/exception/NoSuchY7G4EntryException.java
Writing src/main/java/com/acme/y7g4/service/persistence/impl/constants/Y7G4PersistenceConstants.java
Writing src/main/resources/META-INF/sql/tables.sql
Writing src/main/resources/META-INF/sql/tables.sql
Writing src/main/resources/service.properties
BUILD SUCCESSFUL in 3s
1 actionable task: 1 executed
サービスビルダーは、モデル、永続性、およびサービス用のJavaクラス、データベーススクリプト、および構成ファイルを生成します。 ファイルパスは、y7g4-service
モジュールからの相対パスです。
生成されたストラクチャーの概要は次のとおりです。
liferay-y7g4
├── y7g4-api
│ └── src
│ └── main
│ └── java
│ └── com
│ └── acme
│ └── y7g4
│ ├── exception // Public exception classes & interfaces
│ ├── model // Public model classes & interfaces
│ └── service // Public persistence and service classes
│ // & interfaces
└── y7g4-service
└── src/main
├── java/com/acme/y7g4
│ ├── model // Model implementation
│ └── service // Persistence and service implementation
└── resources
├── META-INF
│ ├── module-hbm.xml // Hibernate object relational map configuration
│ ├── portlet-model-hints.xml // Provides field type information for the UI
│ └── sql
│ ├── indexes.sql
│ ├── sequences.sql
│ └── tables.sql
└── service.properties // Tracks the service build version
モデル、永続性、およびサービス実装クラスは、Javaパッケージパスcom.acme.y7g4
に対して生成されました。 クラスについては、生成されたクラスの理解と拡張をご覧ください。
SQLスクリプトと永続性構成がresources/META-INF
フォルダに生成されました。
module-hbm.xml
ファイルは、Hibernateオブジェクトリレーショナルマップを指定します。
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping auto-import="false" default-lazy="false">
<import class="com.acme.y7g4.model.Y7G4Entry" />
<class name="com.acme.y7g4.model.impl.Y7G4EntryImpl" table="Y7G4_Y7G4Entry">
<id access="com.liferay.portal.dao.orm.hibernate.LiferayPropertyAccessor" name="y7g4EntryId" type="long">
<generator class="assigned" />
</id>
<property access="com.liferay.portal.dao.orm.hibernate.LiferayPropertyAccessor" name="description" type="com.liferay.portal.dao.orm.hibernate.StringType" />
<property access="com.liferay.portal.dao.orm.hibernate.LiferayPropertyAccessor" name="name" type="com.liferay.portal.dao.orm.hibernate.StringType" />
</class>
</hibernate-mapping>
module-hbm.xml
ファイルは、Y7G4EntryImpl
オブジェクトをY7G4_Y7G4Entry
テーブルにマップします。 Hibernateでのマッピングの詳細については、 Hibernate をご覧ください。
tables.sql
スクリプトは、Y7G4_Y7G4Entry
テーブルを指定します。
create table Y7G4_Y7G4Entry (
y7g4EntryId LONG not null primary key,
description VARCHAR(75) null,
name VARCHAR(75) null
);
y7g4EntryId
はプライマリーキーです。 name
とdescription
は属性です。 モジュールをデプロイすると、DXP/Portalはtables.sql
スクリプトを実行してテーブルを作成します。
このservice.xml
ファイルの要素はインデックスまたはシーケンスを指定しないため、indexes.sql
またはsequences.sql
スクリプトは空です。
永続レイヤーとサービスをデプロイする
次に、生成されたコードをDXPサーバーにデプロイして、永続レイヤーとサービスを作成します。 サーバーは、別のMariaDBデータベースサーバー上のデータソースを使用します。バンドルされているHypersonicサーバーよりもMariaDB上のデータベースを調べる方が簡単です。 すべてをデプロイした後、テーブルを検証し、サービスをテストします。
データベースを作成する
MariaDB Dockerコンテナを起動します。
docker run --name some-mariadb -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mariadb:10.2
MariaDB Dockerコンテナ内からDXPデータベースを作成します。
データベースサーバーにサインインします。
docker exec -it some-mariadb bash -c "/usr/bin/mysql -uroot -pmy-secret-pw"
DXP用のデータベースを作成します。
create database dxp_db character set utf8;
データベースセッションを終了します。
quit
デフォルトのネットワーク(
bridge
)でDockerのnetwork inspect
](https://docs.docker.com/engine/reference/commandline/network_inspect/)コマンドを呼び出して、MariaDBコンテナのIPアドレスを取得します。Dockerネットワークはブリッジを実行します。
出力例:
"Containers": {
"162f5350ee9ba7c47c1ba91f54a84543aeada7feb35eb8153743b13ef54cb491": {
"Name": "some-mariadb",
"EndpointID": "8e97e35fb118e2024a52f2ecbfd40b0a879eba8dc3bc5ffceea8bb117c10bebc",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
},
some-mariadb
コンテナのIPv4Address
値の最初の部分を使用します。 例のIPアドレスは172.17.0.2
です。
サーバーを起動する
別の端末で、次のコマンドを使用してDXPを起動します。 必ず[IP address]
をsome-mariadb
コンテナのIPアドレスに置き換えてください。
docker run -it \
--add-host some-mariadb:[IP address] \
-e LIFERAY_JDBC_PERIOD_DEFAULT_PERIOD_JNDI_PERIOD_NAME="" \
-e LIFERAY_JDBC_PERIOD_DEFAULT_PERIOD_DRIVER_UPPERCASEC_LASS_UPPERCASEN_AME=org.mariadb.jdbc.Driver \
-e LIFERAY_JDBC_PERIOD_DEFAULT_PERIOD_URL="jdbc:mariadb://some-mariadb:3306/dxp_db?useUnicode=true&characterEncoding=UTF-8&useFastDateParsing=false" \
-e LIFERAY_JDBC_PERIOD_DEFAULT_PERIOD_USERNAME=root \
-e LIFERAY_JDBC_PERIOD_DEFAULT_PERIOD_PASSWORD=my-secret-pw \
-m 8g \
-p 8080:8080 \
liferay/portal:7.4.2-ga3
モジュールをデプロイする
モジュールをデプロイしてデータベーステーブルを作成し、サービスをインストールします。
./gradlew deploy -Ddeploy.docker.container.id=$(docker ps -lq)
コンソール出力:
STARTED com.acme.y7g4.service_1.0.0 [1423]
STARTED com.acme.y7g4.api_1.0.0 [1422]
テーブルを確認する
データベーステーブルを確認し、検証します。
データベースサーバーにサインインします。
docker exec -it some-mariadb bash -c "/usr/bin/mysql -uroot -pmy-secret-pw"
データベースに接続します。
connect dxp_db;
データベーステーブルを一覧表示して、
Y7G4_Y7G4Entry
テーブルを確認します。show tables;
結果:
+--------------------------------+ | Tables_in_dxp_db | +--------------------------------++ | AMImageEntry | | AccountEntry | | AccountEntryOrganizationRel | | ... | | Y7G4_Y7G4Entry | +--------------------------------+
Y7G4_Y7G4Entry
テーブルの列を一覧表示します。SHOW COLUMNS FROM Y7G4_Y7G4Entry;
結果:
+-------------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------------+-------------+------+-----+---------+-------+ | y7g4EntryId | bigint(20) | NO | PRI | NULL | | | description | varchar(75) | YES | | NULL | | | name | varchar(75) | YES | | NULL | | +-------------+-------------+------+-----+---------+-------+
すべてが揃っています。
データベースセッションを終了します。
quit
サービスをテストする
サービスを呼び出して、データベースにY7G4Entry
データを入力します。
ブラウザでDXPにアクセスします(
http://localhost:8080
)。デフォルトの認証情報を使用してサインインします。
ユーザー名 :
[email protected]
パスワード:
test
[コントロールパネル] → [サーバ管理] → [スクリプト] でスクリプトコンソールに移動します。
次のスクリプトを実行して、エントリーを追加します。
import com.acme.y7g4.service.Y7G4EntryLocalServiceUtil; import com.liferay.portal.kernel.dao.orm.QueryUtil; entry = Y7G4EntryLocalServiceUtil.createY7G4Entry(1234); entry.setName("Mop floors"); entry.setDescription("Mop the kitchen and bathroom floors with soap and water."); Y7G4EntryLocalServiceUtil.addY7G4Entry(entry); entries = Y7G4EntryLocalServiceUtil.getY7G4Entries(QueryUtil.ALL_POS, QueryUtil.ALL_POS); for (entry in entries){ out.println(entry); }
出力:
{y7g4EntryId=1234, description=Mop the kitchen and bathroom floors with soap and water., name=Mop floors}
新しく追加されたY7G4EntryはJSON形式で印刷されます。
スクリプトが行ったことは次のとおりです。
- 生成された静的ユーティリティクラス
Y7G4EntryLocalServiceUtil
をインポートしました。 - ID(
long
)1234
でY7G4Entry
インスタンスを作成しました。 Y7G4Entry
インスタンスのname
とdescription
の属性を入力しました。Y7G4Entry
をデータベースに追加しました。- データベースからすべての
Y7G4Entry
インスタンスを取得し、それらを印刷しました。
次のステップ
モデルを定義し、その永続コードとサービスコードを生成する方法がわかったので、生成されたサービスクラスを調べる必要があります。 生成されたクラスの理解と拡張に進んでください。