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に追加]で見つけることができます。