Reladomoの紹介
1概要
-
Reladomo(以前のMithra)
は、
Goldman Sachs__で開発され、現在オープンソースプロジェクトとしてリリースされているJava用のオブジェクトリレーショナルマッピング(ORM)フレームワークです。 。フレームワークは、いくつかの追加の機能と同様に、ORMから一般的に必要とされる機能を提供します。
Reladomo
の主な機能をいくつか見てみましょう。
-
DDLスクリプトだけでなくJavaクラスも生成可能
-
XMLファイルに書かれたメタデータによって動かされます
-
生成されたコードは拡張可能です
-
問い合わせ言語はオブジェクト指向で強く型付けされている
-
フレームワークはシャーディングのサポートを提供します(同じスキーマ、異なる
データセット)
** テストのサポートも含まれています
-
パフォーマンスキャッシングやトランザクションなどの便利な機能を提供します。
次のセクションでは、設定と基本的な使用例を紹介します。
2
天国
セットアップ
ORMを使い始めるには、
pom.xml
ファイルに
reladomo
依存関係を追加する必要があります。
<dependency>
<groupId>com.goldmansachs.reladomo</groupId>
<artifactId>reladomo</artifactId>
<version>16.5.1</version>
</dependency>
例として
H2
データベースを使用しますので、https://search.maven.org/classic/#search%7Cga%7C1%7Ca%3A%22h2%22%20AND%20g%3A%22comも追加します。 h2database%22[
h2
]依存関係:
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.196</version>
</dependency>
-
これに加えて、クラスとSQLファイルを生成するプラグインをセットアップし、実行中にそれらをロードする必要があります。
ファイル生成には、
maven-antrun-plugin
を使って実行されるタスクを使うことができます。まず、Javaクラスを生成するためのタスクを定義する方法を見てみましょう。
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>generateMithra</id>
<phase>generate-sources</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<property name="plugin__classpath"
refid="maven.plugin.classpath"/>
<taskdef name="gen-reladomo"
classpath="plugin__classpath"
classname="com.gs.fw.common.mithra.generator.MithraGenerator"/>
<gen-reladomo
xml="${project.basedir}/src/main/resources/reladomo/ReladomoClassList.xml"
generateGscListMethod="true"
generatedDir="${project.build.directory}/generated-sources/reladomo"
nonGeneratedDir="${project.basedir}/src/main/java"/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
-
gen-reladomo
タスクは提供された
MithraGenerator
を使用して
ReladomoClassList.xml
ファイルの設定に基づいてJavaファイルを作成します。** このファイルの内容については後のセクションで詳しく見ていきます。
タスクには、生成されたファイルの場所を定義する2つのプロパティもあります。
-
generatedDir
– 変更してはいけないクラスや
バージョン管理
**
nonGeneratedDir
– 生成可能な具象オブジェクトクラス
さらにカスタマイズおよびバージョン管理
Javaオブジェクトに対応するデータベーステーブルは、2番目の
Ant
タスクによって生成されたDDLスクリプトを使用して手動または自動で作成できます。
<taskdef
name="gen-ddl"
classname = "com.gs.fw.common.mithra.generator.dbgenerator.MithraDbDefinitionGenerator"
loaderRef="reladomoGenerator">
<classpath refid="maven.plugin.classpath"/>
</taskdef>
<gen-ddl
xml="${project.basedir}/src/main/resources/reladomo/ReladomoClassList.xml"
generatedDir="${project.build.directory}/generated-db/sql"
databaseType="postgres"/>
このタスクでは、前述の
ReladomoClassList.xml
ファイルと同じ
MithraDbDefinitionGenerator
を使用します。 SQLスクリプトは
generated-db/sql
ディレクトリに配置されます。
このプラグインの定義を完成させるために、作成に使用される2つの依存関係も追加する必要があります。
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
//...
</executions>
<dependencies>
<dependency>
<groupId>com.goldmansachs.reladomo</groupId>
<artifactId>reladomogen</artifactId>
<version>16.5.1</version>
</dependency>
<dependency>
<groupId>com.goldmansachs.reladomo</groupId>
<artifactId>reladomo-gen-util</artifactId>
<version>16.5.1</version>
</dependency>
</dependencies>
</plugin>
最後に、
build-helper-maven-plugin
を使用して、生成されたファイルをクラスパスに追加できます。
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${project.build.directory}/generated-sources/reladomo</source>
</sources>
</configuration>
</execution>
<execution>
<id>add-resource</id>
<phase>generate-resources</phase>
<goals>
<goal>add-resource</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>${project.build.directory}/generated-db/</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
DDLスクリプトの追加はオプションです。この例では、インメモリデータベースを使用するので、テーブルを作成するためにスクリプトを実行します。
3 XML設定
Reladomo
フレームワークのメタデータは、いくつかのXMLファイルで定義できます。
3.1. オブジェクトXMLファイル
作成したい各エンティティはXMLファイルで定義する必要があります。
部署と従業員という2つのエンティティからなる簡単な例を作成しましょう。これがドメインモデルの視覚的表現です。
リンク:/uploads/tables.png%20526w[]
最初の
Department.xml
ファイルを定義しましょう。
<MithraObject objectType="transactional">
<PackageName>com.baeldung.reladomo</PackageName>
<ClassName>Department</ClassName>
<DefaultTable>departments</DefaultTable>
<Attribute name="id" javaType="long"
columnName="department__id" primaryKey="true"/>
<Attribute name="name" javaType="String"
columnName="name" maxLength="50" truncate="true"/>
<Relationship name="employees" relatedObject="Employee"
cardinality="one-to-many"
reverseRelationshipName="department"
relatedIsDependent="true">
Employee.departmentId = this.id
</Relationship>
</MithraObject>
上記のように、エンティティは
MithraObject
** というルート要素内で定義されています。次に、パッケージ、クラス、および対応するデータベーステーブルの名前を指定しました。
型の各プロパティは
Attribute
要素を使用して定義され、その名前、Java型、および列名を指定できます。
-
Relationship
タグを使ってオブジェクト間の関係を記述することができます** この例では、次の式に基づいて
Department
オブジェクトと
Employee
オブジェクトの間に1対多の関係を定義しました。
Employee.departmentId = this.id
-
reverseRelationshipName
属性を使用すると、関係を2回定義せずに関係を双方向にすることができます。
relatedIsDependent
属性を使用すると、操作をカスケードできます。
次に、
Employee.xml
ファイルを同じように作成しましょう。
<MithraObject objectType="transactional">
<PackageName>com.baeldung.reladomo</PackageName>
<ClassName>Employee</ClassName>
<DefaultTable>employees</DefaultTable>
<Attribute name="id" javaType="long"
columnName="employee__id" primaryKey="true"/>
<Attribute name="name" javaType="String"
columnName="name" maxLength="50" truncate="true"/>
<Attribute name="departmentId" javaType="long"
columnName="department__id"/>
</MithraObject>
3.2.
ReladomoClassList.xml
ファイル
Reladomo
は生成すべきオブジェクトについて知らされる必要があります。
Maven
セクションでは、生成タスクのソースとして
ReladomoClassList.xml
ファイルを定義したので、次にファイルを作成します。
<Mithra>
<MithraObjectResource name="Department"/>
<MithraObjectResource name="Employee"/>
</Mithra>
これは、XML構成に基づいてクラスが生成されるエンティティのリストを含む単純なファイルです。
4生成されたクラス
これで、コマンド
mvn clean install
を使用して
Maven
アプリケーションをビルドすることによってコード生成を開始するために必要なすべての要素が揃いました。
具象クラスは、指定されたパッケージの
src/main/java
フォルダーに生成されます。
リンク:/uploads/classes.png[]
これらはカスタムコードを追加できる単純なクラスです。たとえば、
Department
クラスには、削除してはいけないコンストラクタしか含まれていません。
public class Department extends DepartmentAbstract {
public Department() {
super();
//You must not modify this constructor. Mithra calls this internally.
//You can call this constructor. You can also add new constructors.
}
}
このクラスにカスタムコンストラクタを追加したい場合は、親コンストラクタも呼び出す必要があります。
public Department(long id, String name){
super();
this.setId(id);
this.setName(name);
}
これらのクラスは、
generated-sources/reladomo
フォルダー内のabstractクラスとutilityクラスに基づいています。
リンク:/uploads/gen-classes.png%20303w[]
このフォルダ内のクラスの主な種類は次のとおりです。
-
DepartmentAbstract
および
EmployeeAbstract
クラス – これには
定義されたエンティティを操作するためのメソッド
**
DepartmentListAbstract
および
EmployeeListAbstract
– これには
部署と従業員のリストを扱う方法
**
DepartmentFinder
と
EmployeeFinder
– これらは以下のメソッドを提供します。
エンティティの照会
** 他のユーティリティクラス
これらのクラスを生成することによって、私たちのエンティティに対してCRUD操作を実行するのに必要なコードの大部分は、私たちのためにすでに作成されています。
5 Reladomoアプリケーション
データベースで操作を実行するには、データベース接続を取得できるようにする接続マネージャクラスが必要です。
5.1. 接続マネージャ
単一のデータベースを扱う場合は、
SlesslessConnectionManager
インターフェースを実装できます。
public class ReladomoConnectionManager implements SourcelessConnectionManager {
private static ReladomoConnectionManager instance;
private XAConnectionManager xaConnectionManager;
public static synchronized ReladomoConnectionManager getInstance() {
if (instance == null) {
instance = new ReladomoConnectionManager();
}
return instance;
}
private ReladomoConnectionManager() {
this.createConnectionManager();
}
//...
}
ReladomoConnectionManager
クラスはシングルトンパターンを実装しており、トランザクション接続マネージャ用のユーティリティクラスである
XAConnectionManager
に基づいています。
createConnectionManager()
メソッドを詳しく見てみましょう。
private XAConnectionManager createConnectionManager() {
xaConnectionManager = new XAConnectionManager();
xaConnectionManager.setDriverClassName("org.h2.Driver");
xaConnectionManager.setJdbcConnectionString("jdbc:h2:mem:myDb");
xaConnectionManager.setJdbcUser("sa");
xaConnectionManager.setJdbcPassword("");
xaConnectionManager.setPoolName("My Connection Pool");
xaConnectionManager.setInitialSize(1);
xaConnectionManager.setPoolSize(10);
xaConnectionManager.initialisePool();
return xaConnectionManager;
}
このメソッドでは、
H2
インメモリデータベースへの接続を作成するために必要なプロパティを設定します。
また、
SlesslessConnectionManager
インターフェースからいくつかのメソッドを実装する必要があります。
@Override
public Connection getConnection() {
return xaConnectionManager.getConnection();
}
@Override
public DatabaseType getDatabaseType() {
return H2DatabaseType.getInstance();
}
@Override
public TimeZone getDatabaseTimeZone() {
return TimeZone.getDefault();
}
@Override
public String getDatabaseIdentifier() {
return "myDb";
}
@Override
public BulkLoader createBulkLoader() throws BulkLoaderException {
return null;
}
最後に、データベーステーブルを作成する生成されたDDLスクリプトを実行するためのカスタムメソッドを追加しましょう。
public void createTables() throws Exception {
Path ddlPath = Paths.get(ClassLoader.getSystemResource("sql").toURI());
try (
Connection conn = xaConnectionManager.getConnection();
Stream<Path> list = Files.list(ddlPath)) {
list.forEach(path -> {
try {
RunScript.execute(conn, Files.newBufferedReader(path));
}
catch (SQLException | IOException exc){
exc.printStackTrace();
}
});
}
}
もちろん、これは実行時にテーブルが再作成されるわけではない本番アプリケーションには必要ありません。
5.2.
Reladomo
を初期化しています
Reladomo
初期化プロセスは、接続マネージャクラスと使用されるオブジェクトタイプを指定する設定ファイルを使用します。
ReladomoRuntimeConfig.xml
ファイルを定義しましょう。
<MithraRuntime>
<ConnectionManager
className="com.baeldung.reladomo.ReladomoConnectionManager ">
<MithraObjectConfiguration
className="com.baeldung.reladomo.Department" cacheType="partial"/>
<MithraObjectConfiguration
className="com.baeldung.reladomo.Employee " cacheType="partial"/>
</ConnectionManager>
</MithraRuntime>
次に、最初に
createTables()
メソッドを呼び出すメインクラスを作成し、次に
MithraManager
クラスを使用して設定を読み込み、
Reladomo
** を初期化します。
public class ReladomoApplication {
public static void main(String[]args) {
try {
ReladomoConnectionManager.getInstance().createTables();
} catch (Exception e1) {
e1.printStackTrace();
}
MithraManager mithraManager = MithraManagerProvider.getMithraManager();
mithraManager.setTransactionTimeout(120);
try (InputStream is = ReladomoApplication.class.getClassLoader()
.getResourceAsStream("ReladomoRuntimeConfig.xml")) {
MithraManagerProvider.getMithraManager()
.readConfiguration(is);
//execute operations
}
catch (IOException exc){
exc.printStackTrace();
}
}
}
5.3. CRUD操作を実行する
それでは、__Reladomoで生成されたクラスを使用して、私たちのエンティティに対していくつかの操作を実行しましょう。
まず、2つの
Department
オブジェクトと
Employee
オブジェクトを作成し、次に
cascadeInsert()
メソッドを使用して両方を保存します。
Department department = new Department(1, "IT");
Employee employee = new Employee(1, "John");
department.getEmployees().add(employee);
department.cascadeInsert();
各オブジェクトは、
insert()
メソッドを呼び出すことによって個別に保存することもできます。この例では、
relatedIsDependent = true
属性をリレーション定義に追加したため、
cascadeInsert()
を使用することができます。
-
オブジェクトを問い合わせるために、生成された
Finder
クラスを使うことができます。
Department depFound = DepartmentFinder
.findByPrimaryKey(1);
Employee empFound = EmployeeFinder
.findOne(EmployeeFinder.name().eq("John"));
この方法で取得されたオブジェクトは「ライブ」オブジェクトです。つまり、セッターを使用してオブジェクトに変更を加えると、すぐにデータベースに反映されます。
empFound.setName("Steven");
この動作を回避するために、デタッチオブジェクトを取得することができます。
Department depDetached = DepartmentFinder
.findByPrimaryKey(1).getDetachedCopy();
オブジェクトを削除するには、
delete()
メソッドを使います。
empFound.delete();
5.4. 取引管理
一連の操作を1つの単位として実行したくない場合は、トランザクションでラップできます。
mithraManager.executeTransactionalCommand(tx -> {
Department dep = new Department(2, "HR");
Employee emp = new Employee(2, "Jim");
dep.getEmployees().add(emp);
dep.cascadeInsert();
return null;
});
6.
Reladomo
テストサポート
上のセクションでは、例をJavaのメインクラスで書きました。
アプリケーション用にテストを書きたい場合、これを行う1つの方法は、単純にテストクラスに同じコードを書くことです。
ただし、
テストサポートを改善するために、Reladomoは
MithraTestResource
クラスも提供しています
これにより、テスト用に異なる構成とインメモリデータベースを使用できます。
まず、
reladomo-test-util
依存関係を追加します。
junit
依存関係:
<dependency>
<groupId>com.goldmansachs.reladomo</groupId>
<artifactId>reladomo-test-util</artifactId>
<version>16.5.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
次に、
ConnectionManagerForTests
クラスを使用する
ReladomoTestConfig.xml
ファイルを作成する必要があります。
<MithraRuntime>
<ConnectionManager
className="com.gs.fw.common.mithra.test.ConnectionManagerForTests">
<Property name="resourceName" value="testDb"/>
<MithraObjectConfiguration
className="com.baeldung.reladomo.Department" cacheType="partial"/>
<MithraObjectConfiguration
className="com.baeldung.reladomo.Employee " cacheType="partial"/>
</ConnectionManager>
</MithraRuntime>
この接続マネージャは、テストにのみ使用されるインメモリ
H2
データベースを構成します。
-
MithraTestResource
クラスの便利な機能は、テキストファイルに次の形式でテストデータを** 提供できることです。
class com.baeldung.reladomo.Department
id, name
1, "Marketing"
class com.baeldung.reladomo.Employee
id, name
1, "Paul"
JUnit
テストクラスを作成し、
@ Before
メソッドで
MithraTestResource
インスタンスを設定しましょう。
public class ReladomoTest {
private MithraTestResource mithraTestResource;
@Before
public void setUp() throws Exception {
this.mithraTestResource
= new MithraTestResource("reladomo/ReladomoTestConfig.xml");
ConnectionManagerForTests connectionManager
= ConnectionManagerForTests.getInstanceForDbName("testDb");
this.mithraTestResource.createSingleDatabase(connectionManager);
mithraTestResource.addTestDataToDatabase("reladomo/test-data.txt",
connectionManager);
this.mithraTestResource.setUp();
}
}
それからテストデータがロードされたことを検証する簡単な
@ Test
メソッドを書くことができます。
@Test
public void whenGetTestData__thenOk() {
Employee employee = EmployeeFinder.findByPrimaryKey(1);
assertEquals(employee.getName(), "Paul");
}
テストが実行された後、テストデータベースはクリアされる必要があります:
@After
public void tearDown() throws Exception {
this.mithraTestResource.tearDown();
}
7. 結論
この記事では、
Reladomo
ORMフレームワークの主な機能、および一般的な使用方法の設定と例について説明しました。
例のソースコードはhttps://github.com/eugenp/tutorials/tree/master/libraries-data[GitHubに追加]で見つけることができます。