国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

ホームページ Java &#&チュートリアル JPA エンティティを Mendix に変換する

JPA エンティティを Mendix に変換する

Jan 13, 2025 pm 06:04 PM

最近、Mendix を探索しているときに、API を介して mendix アプリ モデルと対話できるプラットフォーム SDK があることに気付きました。

これにより、ドメイン モデルの作成に使用できるかどうかを検討するというアイデアが生まれました。具體的には、既存の従來のアプリケーションに基づいてドメイン モデルを作成します。

さらに一般化すると、これを使用して既存のアプリケーションを Mendix に変換し、そこから開発を続けることができます。

Java/Spring Web アプリケーションを Mendix に変換する

そこで、シンプルな API とデータベース層を備えた小さな Java/Spring Web アプリケーションを作成しました。簡(jiǎn)素化のために、組み込みの 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 ...
}

ご覧のとおり、それらは非常に単純です。私たちが知っているように、貓は世界を支配しているため、名前、年齢、色を持つ貓とその人間の人形です。

どちらにも自動(dòng)生成された ID フィールドがあります。貓は人間と 1 対 1 で関連付けられているため、いつでも人間を呼び出すことができます。 (JPA エンティティではなかった場(chǎng)合は、meow() メソッドを追加したでしょうが、それは將來のために殘しておきます)。

アプリは完全に機(jī)能していますが、現(xiàn)時(shí)點(diǎn)ではデータ層のみに注目しています。

json でのエンティティ メタデータの抽出

これはいくつかの異なる方法で行うことができます:

  1. パッケージ內(nèi)のエンティティを靜的に分析することによって。
  2. リフレクションを使用して実行時(shí)にそれらのエンティティを読み取ることによって。

オプション 2 を選択したのは、その方が早いのですが、オプション 1 を?qū)g行できるライブラリが簡(jiǎn)単に見つからなかったためです。

次に、json をビルドしたら公開する方法を決定する必要があります。話を簡(jiǎn)単にするために、ファイルに書き込むだけです。いくつかの代替方法は次のとおりです:

  • API を通じて公開します。メタデータを公に公開してはいけないため、エンドポイントが十分に保護(hù)されていることを確認(rèn)する必要があるため、これはより複雑です。
  • Spring Boot Actuator や jmx などの管理ツールを通じて公開します。より安全ですが、セットアップにはまだ時(shí)間がかかります。

実際のコードを見てみましょう:

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 アノテーションが付いているアプリ內(nèi)のすべてのクラスを検索します。
次に、クラスごとに次のことを行います:

  1. entityClass.getDeclaredFields() を使用して、宣言されたフィールドを取得します。
  2. そのクラスの各フィールドをループします。

各フィールドについて、次のことを行います。

  1. 屬性のタイプを決定します:

    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 型をカスタム列挙値と照合するだけです。

  2. 次に、この屬性が実際に関連付け (別の @Entity を指している) であるかどうかを確認(rèn)します。そうである場(chǎng)合、関連付けのタイプが 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 ...
    }
    

    これを行うには、以前にマップされた屬性タイプを確認(rèn)するだけです。 Entity の場(chǎng)合は、前のステップでプリミティブ Java 型、String、または Enum にマッピングできなかったことを意味します。
    次に、それがどのような種類の協(xié)會(huì)であるかを決定する必要もあります。チェックは簡(jiǎn)単です。List 型の場(chǎng)合は 1 対多、それ以外の場(chǎng)合は 1 対 1 (「多対多」はまだ実裝されていません)。

  3. 次に、見つかったフィールドごとに MendixAttribute オブジェクトを作成します。

それが完了したら、屬性のリストが割り當(dāng)てられたエンティティの 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 を保存します。 jackson.

を使用して json ファイルに変換します。

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 を使用してアプリを取得し、一時(shí)的な作業(yè)コピーを作成し、モデルを開いて、関心のあるドメイン モデルを見つける必要があります。

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); を使用します。ドメイン モデルに新しいエンティティを作成し、それに名前を割り當(dāng)てます。ドキュメント、インデックス、さらにはドメイン モデル內(nèi)でエンティティがレンダリングされる場(chǎng)所など、より多くのプロパティを割り當(dāng)てることができます。

屬性は別の関數(shù)で処理します。

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 エンティティでは関連付けがフィールドによって宣言されているため、どのフィールドが単純な屬性であり、どのフィールドが関連付けであるかを區(qū)別する必要があります。そのためには、それが ENTITY 型であるかプリミティブ型であるかを確認(rèn)するだけです:

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);
    });
}

名前の他に、設(shè)定する必要のある 4 つの重要なプロパティがあります。

  1. 親エンティティ。これが現(xiàn)在のエンティティです。
  2. 子エンティティ。最後のステップでは、Java エンティティごとに mendix エンティティを作成しました。ここで必要なのは、エンティティ內(nèi)の 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);
        });
    }
    
  3. 関連付けタイプ。 1 対 1 の場(chǎng)合は、參照にマッピングされます。 1 対多の場(chǎng)合は、參照セットにマッピングされます?,F(xiàn)時(shí)點(diǎn)では多対多はスキップします。

  4. 協(xié)會(huì)のオーナー。 1 対 1 の関連付けと多対多の関連付けのどちらも、同じ所有者のタイプ (両方) を持ちます。 1 対 1 の場(chǎng)合、所有者のタイプはデフォルトである必要があります。

Mendix プラットフォーム SDK は、Mendix アプリケーションのローカル作業(yè)コピーにエンティティを作成します。ここで、変更をコミットするように指示するだけです:

@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 ...
}

數(shù)秒後、Mendix Studio Pro でアプリを開いて結(jié)果を確認(rèn)できます。
Converting JPA entities to Mendix

これで、貓と人間の間に 1 対 1 の関連付けを持つエンティティができました。

自分で実験したい場(chǎng)合、または完全なコードを確認(rèn)したい場(chǎng)合は、このリポジトリにアクセスしてください。

將來へのアイデア

  1. この例では、私が最も習(xí)熟している Java/Spring アプリケーションを変換元に使用しましたが、どのアプリケーションでも使用できます。 型データを (靜的または実行時(shí)に) 読み取ってクラス名とフィールド名を抽出できれば十分です。
  2. Java ロジックを読み取って、Mendix マイクロフローにエクスポートしてみたいと思っています。ビジネス ロジック自體を?qū)g際に変換することはおそらく不可能ですが、その構(gòu)造 (少なくともビジネス メソッドの署名?) は取得できるはずです。
  3. この記事のコードは一般化してライブラリにすることができます。json 形式は同じままで、Java 型をエクスポートするライブラリと mendix エンティティをインポートするライブラリが 1 つ存在する可能性があります。
  4. 同じアプローチを使用して、その逆、つまり mendix を別の言語に変換することもできます。

結(jié)論

Mendix プラットフォーム SDK は、Mendix アプリとプログラムで対話できる強(qiáng)力な機(jī)能です。コードのインポート/エクスポート、アプリの複雑さの分析など、いくつかのサンプル ユースケースがリストされています。
ご興味がございましたら、ぜひご覧ください。
この記事の完全なコードはここにあります。

以上がJPA エンティティを Mendix に変換するの詳細(xì)內(nèi)容です。詳細(xì)については、PHP 中國語 Web サイトの他の関連記事を參照してください。

このウェブサイトの聲明
この記事の內(nèi)容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰屬します。このサイトは、それに相當(dāng)する法的責(zé)任を負(fù)いません。盜作または侵害の疑いのあるコンテンツを見つけた場(chǎng)合は、admin@php.cn までご連絡(luò)ください。

ホットAIツール

Undress AI Tool

Undress AI Tool

脫衣畫像を無料で

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード寫真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

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

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

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

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中國語版

SublimeText3 中國語版

中國語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強(qiáng)力な PHP 統(tǒng)合開発環(huán)境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

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

ハッシュマップとハッシュテーブルの違いは? ハッシュマップとハッシュテーブルの違いは? Jun 24, 2025 pm 09:41 PM

ハッシュマップとハッシュテーブルの違いは、主にスレッドの安全性、ヌル価値のサポート、パフォーマンスに反映されます。 1.スレッドの安全性の観點(diǎn)から、ハッシュテーブルはスレッドセーフであり、その方法はほとんど同期メソッドであり、ハッシュマップはスレッドセーフではない同期処理を?qū)g行しません。 2。ヌル値のサポートに関しては、ハッシュマップは1つのnullキーと複數(shù)のヌル値を許可しますが、ハッシュテーブルはnullキーや値を許可しません。 3.パフォーマンスの観點(diǎn)から、ハッシュマップは同期メカニズムがないため、より効率的です。ハッシュテーブルは、各操作のロックパフォーマンスが低いです。代わりにconcurrenthashmapを使用することをお?jiǎng)幛幛筏蓼埂?/p>

なぜラッパークラスが必要なのですか? なぜラッパークラスが必要なのですか? Jun 28, 2025 am 01:01 AM

Javaは、基本的なデータ型がオブジェクト指向の操作に直接參加できないため、ラッパークラスを使用し、実際のニーズでオブジェクトフォームが必要になることが多いためです。 1.コレクションクラスは、リストが自動(dòng)ボクシングを使用して數(shù)値を保存するなど、オブジェクトのみを保存できます。 2。ジェネリックは基本的なタイプをサポートしておらず、パッケージングクラスはタイプパラメーターとして使用する必要があります。 3.パッケージングクラスは、null値を表して、データまたは欠落データを區(qū)別できます。 4.パッケージングクラスは、データの解析と処理を容易にするための文字列変換などの実用的な方法を提供するため、これらの特性が必要なシナリオでは、パッケージングクラスは不可欠です。

インターフェイスの靜的メソッドとは何ですか? インターフェイスの靜的メソッドとは何ですか? Jun 24, 2025 pm 10:57 PM

StaticMethodsinInterfaceswereIntroducatedinjava8toalowutilityは、interfaceitself.beforejava8、そのような導(dǎo)入のために導(dǎo)入されたコード、rediveTodisorgedCode.now、statecmethodssprovidreebenefits:1)彼らの可能性のある測(cè)定di

JITコンパイラはどのようにコードを最適化しますか? JITコンパイラはどのようにコードを最適化しますか? Jun 24, 2025 pm 10:45 PM

JITコンパイラは、メソッドインライン、ホットスポット検出とコンピレーション、タイプの投機(jī)と偏見、冗長操作の排除の4つの方法を通じてコードを最適化します。 1。メソッドインラインで呼び出しのオーバーヘッドを減らし、頻繁に小さな方法と呼ばれる挿入をコールに直接直接挿入します。 2。ホットスポットの検出と高周波コードの実行とそれを中央に最適化して、リソースを節(jié)約します。 3。タイプ投機(jī)は、敬v的な呼び出しを達(dá)成するためにランタイムタイプ情報(bào)を収集し、効率を向上させます。 4.冗長操作は、運(yùn)用データの削除に基づいて役に立たない計(jì)算と検査を排除し、パフォーマンスを向上させます。

インスタンスイニシャルイザーブロックとは何ですか? インスタンスイニシャルイザーブロックとは何ですか? Jun 25, 2025 pm 12:21 PM

インスタンス初期化ブロックは、Javaで使用され、コンストラクターの前に実行されるオブジェクトを作成するときに初期化ロジックを?qū)g行します。複數(shù)のコンストラクターが初期化コード、複雑なフィールド初期化、または匿名のクラス初期化シナリオを共有するシナリオに適しています。靜的初期化ブロックとは異なり、インスタンス化されるたびに実行されますが、靜的初期化ブロックはクラスがロードされたときに1回のみ実行されます。

工場(chǎng)のパターンとは何ですか? 工場(chǎng)のパターンとは何ですか? Jun 24, 2025 pm 11:29 PM

ファクトリーモードは、オブジェクトの作成ロジックをカプセル化するために使用され、コードをより柔軟でメンテナンスしやすく、ゆるく結(jié)合します。コアの答えは、オブジェクトの作成ロジックを一元的に管理し、実裝の詳細(xì)を隠し、複數(shù)の関連オブジェクトの作成をサポートすることです。特定の説明は次のとおりです。工場(chǎng)モードは、NewClass()の使用を直接回避し、処理のための特別な工場(chǎng)クラスまたは方法にオブジェクトの作成を手渡します。複數(shù)のタイプの関連オブジェクトが作成され、作成ロジックが変更され、実裝の詳細(xì)を非表示にする必要があるシナリオに適しています。たとえば、支払いプロセッサでは、Stripe、PayPal、その他のインスタンスが工場(chǎng)を通じて作成されます。その実裝には、入力パラメーターに基づいて工場(chǎng)クラスによって返されるオブジェクトが含まれ、すべてのオブジェクトは共通のインターフェイスを?qū)g現(xiàn)します。一般的なバリアントには、単純な工場(chǎng)、工場(chǎng)法、抽象的な工場(chǎng)が含まれます。これらは異なる複雑さに適しています。

変數(shù)の「ファイナル」キーワードは何ですか? 変數(shù)の「ファイナル」キーワードは何ですか? Jun 24, 2025 pm 07:29 PM

Injava、thefinalkeywordpreventsavariaibleのValue frombeingededafterassignment、ButiTsbehiviordiffersforprimitivesandobjectReferences

タイプキャストとは何ですか? タイプキャストとは何ですか? Jun 24, 2025 pm 11:09 PM

変換には、暗黙的で明示的な変換には2つのタイプがあります。 1.暗黙的な変換は、INTを2倍に変換するなど、自動(dòng)的に発生します。 2。明示的な変換には、(int)mydoubleの使用など、手動(dòng)操作が必要です。タイプ変換が必要な場(chǎng)合には、ユーザー入力の処理、數(shù)學(xué)操作、または関數(shù)間のさまざまなタイプの値の渡されます。注意する必要がある問題は次のとおりです。浮動(dòng)小數(shù)點(diǎn)數(shù)を整數(shù)に変換すると、分?jǐn)?shù)部分が切り捨てられ、大きなタイプを小さなタイプに変えるとデータの損失につながる可能性があり、一部の言語では特定のタイプの直接変換ができません。言語変換ルールを適切に理解することは、エラーを回避するのに役立ちます。

See all articles