最近、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); } ... } </mendixattribute></mendixentity></class>
まず、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 </class>
基本的には、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); } ... } </mendixattribute></mendixentity></class>
最後に、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 </class>
次に、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 } } </mendixattribute>
ここでは、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 サイトの他の関連記事を参照してください。

この記事では、カフェインとグアバキャッシュを使用してJavaでマルチレベルキャッシュを実装してアプリケーションのパフォーマンスを向上させています。セットアップ、統合、パフォーマンスの利点をカバーし、構成と立ち退きポリシー管理Best Pra

この記事では、Lambda式、Streams API、メソッド参照、およびオプションを使用して、機能プログラミングをJavaに統合することを調べます。 それは、簡潔さと不変性を通じてコードの読みやすさと保守性の改善などの利点を強調しています

Javaのクラスロードには、ブートストラップ、拡張機能、およびアプリケーションクラスローダーを備えた階層システムを使用して、クラスの読み込み、リンク、および初期化が含まれます。親の委任モデルは、コアクラスが最初にロードされ、カスタムクラスのLOAに影響を与えることを保証します

この記事では、キャッシュや怠zyなロードなどの高度な機能を備えたオブジェクトリレーショナルマッピングにJPAを使用することについて説明します。潜在的な落とし穴を強調しながら、パフォーマンスを最適化するためのセットアップ、エンティティマッピング、およびベストプラクティスをカバーしています。[159文字]

この記事では、Javaプロジェクト管理、自動化の構築、依存関係の解像度にMavenとGradleを使用して、アプローチと最適化戦略を比較して説明します。

この記事では、単一のスレッドで複数の接続を効率的に処理するためにセレクターとチャネルを使用して、非ブロッキングI/O用のJavaのNIO APIについて説明します。 プロセス、利点(スケーラビリティ、パフォーマンス)、および潜在的な落とし穴(複雑さ、

この記事では、MavenやGradleなどのツールを使用して、適切なバージョン化と依存関係管理を使用して、カスタムJavaライブラリ(JARファイル)の作成と使用について説明します。

この記事では、ネットワーク通信のためのJavaのソケットAPI、クライアントサーバーのセットアップ、データ処理、リソース管理、エラー処理、セキュリティなどの重要な考慮事項をカバーしています。 また、パフォーマンスの最適化手法も調査します


ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

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

PhpStorm Mac バージョン
最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

WebStorm Mac版
便利なJavaScript開発ツール

ZendStudio 13.5.1 Mac
強力な PHP 統合開発環境

MinGW - Minimalist GNU for Windows
このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

ホットトピック



