JPA エンティティを Mendix に変換する
最近、Mendix を探索しているときに、API を介して mendix アプリ モデルと対話できるプラットフォーム SDK があることに気付きました。
これにより、ドメイン モデルの作成に使用できるかどうかを検討するというアイデアが生まれました。具体的には、既存の従来のアプリケーションに基づいてドメイン モデルを作成します。
さらに一般化すると、これを使用して既存のアプリケーションを Mendix に変換し、そこから開発を続けることができます。
Java/Spring Web アプリケーションを Mendix に変換する
そこで、シンプルな API とデータベース層を備えた小さな Java/Spring Web アプリケーションを作成しました。簡素化のために、組み込みの H2 データベースを使用します。
この投稿では、JPA エンティティのみを変換します。それらを見てみましょう:
@Entity @Table(name = "CAT") class Cat { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String name; private int age; private String color; @OneToOne private Human humanPuppet; ... constructor ... ... getters ... } @Entity @Table(name = "HUMAN") public class Human { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String name; ... constructor ... ... getters ... }
ご覧のとおり、それらは非常に単純です。私たちが知っているように、猫は世界を支配しているため、名前、年齢、色を持つ猫とその人間の人形です。
どちらにも自動生成された ID フィールドがあります。猫は人間と 1 対 1 で関連付けられているため、いつでも人間を呼び出すことができます。 (JPA エンティティではなかった場合は、meow() メソッドを追加したでしょうが、それは将来のために残しておきます)。
アプリは完全に機能していますが、現時点ではデータ層のみに注目しています。
json でのエンティティ メタデータの抽出
これはいくつかの異なる方法で行うことができます:
- パッケージ内のエンティティを静的に分析することによって。
- リフレクションを使用して実行時にそれらのエンティティを読み取ることによって。
オプション 2 を選択したのは、その方が早いのですが、オプション 1 を実行できるライブラリが簡単に見つからなかったためです。
次に、json をビルドしたら公開する方法を決定する必要があります。話を簡単にするために、ファイルに書き込むだけです。いくつかの代替方法は次のとおりです:
- API を通じて公開します。メタデータを公に公開してはいけないため、エンドポイントが十分に保護されていることを確認する必要があるため、これはより複雑です。
- Spring Boot Actuator や jmx などの管理ツールを通じて公開します。より安全ですが、セットアップにはまだ時間がかかります。
実際のコードを見てみましょう:
public class MendixExporter { public static void exportEntitiesTo(String filePath) throws IOException { AnnotatedTypeScanner typeScanner = new AnnotatedTypeScanner(false, Entity.class); Set<Class<?>> entityClasses = typeScanner.findTypes(JavaToMendixApplication.class.getPackageName()); log.info("Entity classes are: {}", entityClasses); List<MendixEntity> mendixEntities = new ArrayList<>(); for (Class<?> entityClass : entityClasses) { List<MendixAttribute> attributes = new ArrayList<>(); for (Field field : entityClass.getDeclaredFields()) { AttributeType attributeType = determineAttributeType(field); AssociationType associationType = determineAssociationType(field, attributeType); String associationEntityType = determineAssociationEntityType(field, attributeType); attributes.add( new MendixAttribute(field.getName(), attributeType, associationType, associationEntityType)); } MendixEntity newEntity = new MendixEntity(entityClass.getSimpleName(), attributes); mendixEntities.add(newEntity); } writeToJsonFile(filePath, mendixEntities); } ... }
まず、JPA の @Entity アノテーションが付いているアプリ内のすべてのクラスを検索します。
次に、クラスごとに次のことを行います:
- entityClass.getDeclaredFields() を使用して、宣言されたフィールドを取得します。
- そのクラスの各フィールドをループします。
各フィールドについて、次のことを行います。
-
属性のタイプを決定します:
private static final Map<Class<?>, AttributeType> JAVA_TO_MENDIX_TYPE = Map.ofEntries( Map.entry(String.class, AttributeType.STRING), Map.entry(Integer.class, AttributeType.INTEGER), ... ); // we return AttributeType.ENTITY if we cannot map to anything else
ログイン後にコピーログイン後にコピー基本的には、JAVA_TO_MENDIX_TYPE マップで検索して Java 型をカスタム列挙値と照合するだけです。
-
次に、この属性が実際に関連付け (別の @Entity を指している) であるかどうかを確認します。そうである場合、関連付けのタイプが 1 対 1、1 対多、多対多であるかどうかを判断します:
@Entity @Table(name = "CAT") class Cat { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String name; private int age; private String color; @OneToOne private Human humanPuppet; ... constructor ... ... getters ... } @Entity @Table(name = "HUMAN") public class Human { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String name; ... constructor ... ... getters ... }
ログイン後にコピーログイン後にコピーログイン後にコピーこれを行うには、以前にマップされた属性タイプを確認するだけです。 Entity の場合は、前のステップでプリミティブ Java 型、String、または Enum にマッピングできなかったことを意味します。
次に、それがどのような種類の協会であるかを決定する必要もあります。チェックは簡単です。List 型の場合は 1 対多、それ以外の場合は 1 対 1 (「多対多」はまだ実装されていません)。 次に、見つかったフィールドごとに MendixAttribute オブジェクトを作成します。
それが完了したら、属性のリストが割り当てられたエンティティの MendixEntity オブジェクトを作成するだけです。
MendixEntity と MendixAttribute は、後で json にマッピングするために使用するクラスです。
public class MendixExporter { public static void exportEntitiesTo(String filePath) throws IOException { AnnotatedTypeScanner typeScanner = new AnnotatedTypeScanner(false, Entity.class); Set<Class<?>> entityClasses = typeScanner.findTypes(JavaToMendixApplication.class.getPackageName()); log.info("Entity classes are: {}", entityClasses); List<MendixEntity> mendixEntities = new ArrayList<>(); for (Class<?> entityClass : entityClasses) { List<MendixAttribute> attributes = new ArrayList<>(); for (Field field : entityClass.getDeclaredFields()) { AttributeType attributeType = determineAttributeType(field); AssociationType associationType = determineAssociationType(field, attributeType); String associationEntityType = determineAssociationEntityType(field, attributeType); attributes.add( new MendixAttribute(field.getName(), attributeType, associationType, associationEntityType)); } MendixEntity newEntity = new MendixEntity(entityClass.getSimpleName(), attributes); mendixEntities.add(newEntity); } writeToJsonFile(filePath, mendixEntities); } ... }
最後に、List
Mendix へのエンティティのインポート
ここからが楽しい部分です。上で生成した json ファイルをどのように読み取り、そこから mendix エンティティを作成するのでしょうか?
Mendix のプラットフォーム SDK には、それと対話するための Typescript API があります。
まず、エンティティと属性を表すオブジェクトと、関連付けと属性タイプの列挙型を作成します。
private static final Map<Class<?>, AttributeType> JAVA_TO_MENDIX_TYPE = Map.ofEntries( Map.entry(String.class, AttributeType.STRING), Map.entry(Integer.class, AttributeType.INTEGER), ... ); // we return AttributeType.ENTITY if we cannot map to anything else
次に、appId を使用してアプリを取得し、一時的な作業コピーを作成し、モデルを開いて、関心のあるドメイン モデルを見つける必要があります。
private static AssociationType determineAssociationType(Field field, AttributeType attributeType) { if (!attributeType.equals(AttributeType.ENTITY)) return null; if (field.getType().equals(List.class)) { return AssociationType.ONE_TO_MANY; } else { return AssociationType.ONE_TO_ONE; } }
SDK は実際に mendix アプリを git からプルし、それに取り組みます。
json ファイルから読み取った後、エンティティをループします。
public record MendixEntity( String name, List<MendixAttribute> attributes) { } public record MendixAttribute( String name, AttributeType type, AssociationType associationType, String entityType) { public enum AttributeType { STRING, INTEGER, DECIMAL, AUTO_NUMBER, BOOLEAN, ENUM, ENTITY; } public enum AssociationType { ONE_TO_ONE, ONE_TO_MANY } }
ここでは、domainmodels.Entity.createIn(domainModel); を使用します。ドメイン モデルに新しいエンティティを作成し、それに名前を割り当てます。ドキュメント、インデックス、さらにはドメイン モデル内でエンティティがレンダリングされる場所など、より多くのプロパティを割り当てることができます。
属性は別の関数で処理します。
interface ImportedEntity { name: string; generalization: string; attributes: ImportedAttribute[]; } interface ImportedAttribute { name: string; type: ImportedAttributeType; entityType: string; associationType: ImportedAssociationType; } enum ImportedAssociationType { ONE_TO_ONE = "ONE_TO_ONE", ONE_TO_MANY = "ONE_TO_MANY" } enum ImportedAttributeType { INTEGER = "INTEGER", STRING = "STRING", DECIMAL = "DECIMAL", AUTO_NUMBER = "AUTO_NUMBER", BOOLEAN = "BOOLEAN", ENUM = "ENUM", ENTITY = "ENTITY" }
ここで少し努力しなければならない唯一のことは、属性タイプを有効な mendix タイプにマップすることです。
次に、関連付けを処理します。まず、Java エンティティでは関連付けがフィールドによって宣言されているため、どのフィールドが単純な属性であり、どのフィールドが関連付けであるかを区別する必要があります。そのためには、それが ENTITY 型であるかプリミティブ型であるかを確認するだけです:
const client = new MendixPlatformClient(); const app = await client.getApp(appId); const workingCopy = await app.createTemporaryWorkingCopy("main"); const model = await workingCopy.openModel(); const domainModelInterface = model.allDomainModels().filter(dm => dm.containerAsModule.name === MyFirstModule")[0]; const domainModel = await domainModelInterface.load();
関連付けを作成しましょう:
function createMendixEntities(domainModel: domainmodels.DomainModel, entitiesInJson: any) { const importedEntities: ImportedEntity[] = JSON.parse(entitiesInJson); importedEntities.forEach((importedEntity, i) => { const mendixEntity = domainmodels.Entity.createIn(domainModel); mendixEntity.name = importedEntity.name; processAttributes(importedEntity, mendixEntity); }); importedEntities.forEach(importedEntity => { const mendixParentEntity = domainModel.entities.find(e => e.name === importedEntity.name) as domainmodels.Entity; processAssociations(importedEntity, domainModel, mendixParentEntity); }); }
名前の他に、設定する必要のある 4 つの重要なプロパティがあります。
- 親エンティティ。これが現在のエンティティです。
-
子エンティティ。最後のステップでは、Java エンティティごとに mendix エンティティを作成しました。ここで必要なのは、エンティティ内の Java フィールドのタイプに基づいて、一致するエンティティを見つけることだけです:
function processAttributes(importedEntity: ImportedEntity, mendixEntity: domainmodels.Entity) { importedEntity.attributes.filter(a => a.type !== ImportedAttributeType.ENTITY).forEach(a => { const mendixAttribute = domainmodels.Attribute.createIn(mendixEntity); mendixAttribute.name = capitalize(getAttributeName(a.name, importedEntity)); mendixAttribute.type = assignAttributeType(a.type, mendixAttribute); }); }
ログイン後にコピー 関連付けタイプ。 1 対 1 の場合は、参照にマッピングされます。 1 対多の場合は、参照セットにマッピングされます。現時点では多対多はスキップします。
協会のオーナー。 1 対 1 の関連付けと多対多の関連付けのどちらも、同じ所有者のタイプ (両方) を持ちます。 1 対 1 の場合、所有者のタイプはデフォルトである必要があります。
Mendix プラットフォーム SDK は、Mendix アプリケーションのローカル作業コピーにエンティティを作成します。ここで、変更をコミットするように指示するだけです:
@Entity @Table(name = "CAT") class Cat { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String name; private int age; private String color; @OneToOne private Human humanPuppet; ... constructor ... ... getters ... } @Entity @Table(name = "HUMAN") public class Human { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String name; ... constructor ... ... getters ... }
数秒後、Mendix Studio Pro でアプリを開いて結果を確認できます。
これで、猫と人間の間に 1 対 1 の関連付けを持つエンティティができました。
自分で実験したい場合、または完全なコードを確認したい場合は、このリポジトリにアクセスしてください。
将来へのアイデア
- この例では、私が最も習熟している Java/Spring アプリケーションを変換元に使用しましたが、どのアプリケーションでも使用できます。 型データを (静的または実行時に) 読み取ってクラス名とフィールド名を抽出できれば十分です。
- Java ロジックを読み取って、Mendix マイクロフローにエクスポートしてみたいと思っています。ビジネス ロジック自体を実際に変換することはおそらく不可能ですが、その構造 (少なくともビジネス メソッドの署名?) は取得できるはずです。
- この記事のコードは一般化してライブラリにすることができます。json 形式は同じままで、Java 型をエクスポートするライブラリと mendix エンティティをインポートするライブラリが 1 つ存在する可能性があります。
- 同じアプローチを使用して、その逆、つまり mendix を別の言語に変換することもできます。
結論
Mendix プラットフォーム SDK は、Mendix アプリとプログラムで対話できる強力な機能です。コードのインポート/エクスポート、アプリの複雑さの分析など、いくつかのサンプル ユースケースがリストされています。
ご興味がございましたら、ぜひご覧ください。
この記事の完全なコードはここにあります。
以上がJPA エンティティを Mendix に変換するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











一部のアプリケーションが適切に機能しないようにする会社のセキュリティソフトウェアのトラブルシューティングとソリューション。多くの企業は、内部ネットワークセキュリティを確保するためにセキュリティソフトウェアを展開します。 ...

多くのアプリケーションシナリオでソートを実装するために名前を数値に変換するソリューションでは、ユーザーはグループ、特に1つでソートする必要がある場合があります...

システムドッキングでのフィールドマッピング処理は、システムドッキングを実行する際に難しい問題に遭遇することがよくあります。システムのインターフェイスフィールドを効果的にマッピングする方法A ...

intellijideaultimatiateバージョンを使用してスプリングを開始します...

データベース操作にMyBatis-Plusまたはその他のORMフレームワークを使用する場合、エンティティクラスの属性名に基づいてクエリ条件を構築する必要があることがよくあります。あなたが毎回手動で...

Javaオブジェクトと配列の変換:リスクの詳細な議論と鋳造タイプ変換の正しい方法多くのJava初心者は、オブジェクトのアレイへの変換に遭遇します...

eコマースプラットフォーム上のSKUおよびSPUテーブルの設計の詳細な説明この記事では、eコマースプラットフォームでのSKUとSPUのデータベース設計の問題、特にユーザー定義の販売を扱う方法について説明します。

Redisキャッシュソリューションは、製品ランキングリストの要件をどのように実現しますか?開発プロセス中に、多くの場合、ランキングの要件に対処する必要があります。
