Rumah > Java > javaTutorial > Menukar entiti JPA kepada Mendix

Menukar entiti JPA kepada Mendix

Linda Hamilton
Lepaskan: 2025-01-13 18:04:42
asal
319 orang telah melayarinya

Baru-baru ini semasa menerokai Mendix, saya dapati mereka mempunyai Platform SDK yang membolehkan anda berinteraksi dengan model aplikasi mendix melalui API.

Ini memberi saya idea untuk meneroka sama ada ia boleh digunakan untuk mencipta model domain kami. Khususnya, untuk mencipta model domain berdasarkan aplikasi tradisional sedia ada.

Jika digeneralisasikan lagi, ini boleh digunakan untuk menukar mana-mana aplikasi sedia ada kepada Mendix dan meneruskan pembangunan dari sana.

Menukar aplikasi web Java/Spring kepada Mendix

Jadi, saya mencipta aplikasi web Java/Spring yang kecil dengan API dan lapisan pangkalan data yang mudah. Ia menggunakan pangkalan data H2 terbenam untuk kesederhanaan.

Dalam siaran ini, kami hanya akan menukar entiti JPA. Jom tengok mereka:

@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 ...
}
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Seperti yang anda lihat, ia agak mudah: Kucing dengan nama, umur, warna dan boneka Manusianya, kerana kucing memerintah dunia seperti yang kita tahu.

Kedua-duanya mempunyai medan ID yang dijana secara automatik. Kucing mempunyai perkaitan satu sama lain dengan Manusia supaya ia boleh memanggil manusianya pada bila-bila masa ia mahu. (Jika ia bukan entiti JPA, saya akan meletakkan kaedah meow() tetapi biarkan itu untuk masa hadapan).

Apl berfungsi sepenuhnya tetapi sekarang kami hanya berminat dengan lapisan data.

Mengekstrak metadata Entiti dalam json

Ini boleh dilakukan dalam beberapa cara berbeza:

  1. Dengan menganalisis entiti secara statik dalam pakej mereka.
  2. Dengan menggunakan refleksi untuk membaca entiti tersebut pada masa jalan.

Saya telah memilih pilihan 2 kerana ia lebih cepat dan saya tidak dapat mencari perpustakaan yang boleh melakukan pilihan 1 dengan mudah.

Seterusnya, kita perlu memutuskan cara untuk mendedahkan json sebaik sahaja kita membinanya. Untuk memudahkan, kami hanya akan menulisnya ke dalam fail. Beberapa cara alternatif boleh jadi:

  • Mendedahkannya melalui api. Ini lebih rumit kerana anda juga perlu memastikan titik akhir terjamin dengan baik kerana kami tidak boleh mendedahkan metadata kami secara terbuka.
  • Mendedahkannya melalui beberapa alat pengurusan, seperti penggerak but spring atau jmx. Ia lebih selamat, tetapi masih memerlukan masa untuk menyediakan.

Mari kita lihat kod sebenar:

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);
    }
    ...
}
Salin selepas log masuk
Salin selepas log masuk

Kami bermula dengan mencari semua kelas dalam apl kami yang ditandakan dengan anotasi @Entity JPA.
Kemudian, untuk setiap kelas, kami:

  1. Dapatkan medan yang diisytiharkan dengan entityClass.getDeclaredFields().
  2. Gelung setiap medan kelas itu.

Untuk setiap medan, kami:

  1. Tentukan jenis atribut:

    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
    
    Salin selepas log masuk
    Salin selepas log masuk

    Pada asasnya kami hanya memadankan jenis java dengan nilai enum tersuai kami dengan mencarinya dalam peta JAVA_TO_MENDIX_TYPE.

  2. Seterusnya, kami menyemak sama ada atribut ini sebenarnya adalah perkaitan (menunjuk kepada @Entity lain). Jika ya, kami menentukan jenis persatuan itu: satu-dengan-satu, satu-ke-banyak, banyak-ke-banyak:

    @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 ...
    }
    
    Salin selepas log masuk
    Salin selepas log masuk
    Salin selepas log masuk

    Untuk berbuat demikian, kami hanya menyemak jenis atribut yang dipetakan sebelum ini. Sekiranya ia adalah Entiti, yang bermaksud bahawa dalam langkah sebelum ini kami tidak dapat memetakannya kepada mana-mana jenis java primitif, String atau Enum.
    Kemudian kita juga perlu memutuskan jenis persatuan itu. Semakannya mudah: jika ia adalah jenis Senarai, maka ia adalah satu-ke-banyak, sebaliknya satu-dengan-satu (belum melaksanakan 'banyak-ke-banyak' lagi).

  3. Kami kemudian mencipta objek MendixAttribute untuk setiap medan yang ditemui.

Setelah itu selesai, kami hanya mencipta objek MendixEntity untuk entiti dengan senarai atribut yang diberikan.
MendixEntity dan MendixAttribute ialah kelas yang akan kami gunakan untuk memetakan ke json nanti:

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);
    }
    ...
}
Salin selepas log masuk
Salin selepas log masuk

Akhir sekali, kami menyimpan Senarai ke fail json menggunakan jackson.

Mengimport entiti ke dalam Mendix

Inilah bahagian yang menyeronokkan, bagaimana kita membaca fail json yang kita hasilkan di atas dan mencipta entiti mendix daripadanya?

SDK Platform Mendix mempunyai API Typescript untuk berinteraksi dengannya.
Mula-mula kita akan mencipta objek untuk mewakili entiti dan atribut kita, serta enum untuk jenis perkaitan dan atribut:

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
Salin selepas log masuk
Salin selepas log masuk

Seterusnya, kami perlu mendapatkan apl kami dengan appId, membuat salinan kerja sementara, membuka model dan mencari model domain yang kami minati:

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;
    }
}
Salin selepas log masuk

SDK sebenarnya akan menarik apl mendix kami daripada git dan mengusahakannya.

Selepas membaca daripada fail json, kami akan menggelungkan entiti:

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
    }
}
Salin selepas log masuk

Di sini kami menggunakan domainmodels.Entity.createIn(domainModel); untuk mencipta entiti baharu dalam model domain kami dan memberikan nama kepadanya. Kami boleh menetapkan lebih banyak sifat, seperti dokumentasi, indeks, malah lokasi tempat entiti akan dipaparkan dalam model domain.

Kami memproses atribut dalam fungsi berasingan:

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"
}
Salin selepas log masuk

Satu-satunya perkara di sini yang perlu kita lakukan ialah memetakan jenis atribut kepada jenis mendix yang sah.

Seterusnya kami memproses persatuan. Pertama, memandangkan dalam entiti Java kami persatuan telah diisytiharkan oleh medan, kami perlu membezakan medan mana yang merupakan atribut mudah, dan mana yang merupakan persatuan. Untuk melakukannya, kita hanya perlu menyemak sama ada ia jenis ENTITI atau jenis primitif:

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();
Salin selepas log masuk

Mari kita wujudkan persatuan:

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);
    });
}
Salin selepas log masuk

Kami ada 4 sifat penting untuk ditetapkan, selain nama:

  1. Entiti induk. Ini ialah entiti semasa.
  2. Entiti kanak-kanak. Dalam langkah terakhir, kami mencipta entiti mendix untuk setiap entiti java. Sekarang kita hanya perlu mencari entiti yang sepadan berdasarkan jenis medan java dalam entiti kita:

    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);
        });
    }
    
    Salin selepas log masuk
  3. Jenis persatuan. Jika ia satu-dengan-satu, ia memetakan kepada Rujukan. Jika ia satu-ke-banyak, ia memetakan kepada Set Rujukan. Kami akan melangkau banyak-ke-banyak buat masa ini.

  4. Pemilik persatuan. Kedua-dua persatuan satu-dengan-satu dan banyak-ke-banyak mempunyai jenis pemilik yang sama: Kedua-duanya. Untuk satu sama satu, jenis pemilik mestilah Lalai.

SDK Platform Mendix akan mencipta entiti dalam salinan kerja tempatan aplikasi mendix kami. Sekarang kita hanya perlu memberitahunya untuk melakukan perubahan:

@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 ...
}
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Selepas beberapa saat, anda boleh membuka apl dalam Mendix Studio Pro dan mengesahkan keputusan:
Converting JPA entities to Mendix

Begitulah: entiti Kucing dan Manusia dengan perkaitan satu dengan satu di antara mereka.

Jika anda ingin mencuba sendiri atau melihat kod penuh, pergi ke repo ini.

Idea untuk masa hadapan

  1. Dalam contoh ini saya telah menggunakan aplikasi Java/Spring untuk menukar daripadanya kerana saya paling mahir dalam penggunaannya tetapi sebarang aplikasi boleh digunakan. Cukup sekadar dapat membaca data jenis (secara statik atau semasa masa jalan) untuk mengekstrak nama kelas dan medan.
  2. Saya ingin tahu untuk mencuba membaca dan mengeksport beberapa logik java ke aliran mikro Mendix. Kita mungkin tidak benar-benar boleh menukar logik perniagaan itu sendiri tetapi kita sepatutnya boleh mendapatkan strukturnya (sekurang-kurangnya tandatangan kaedah perniagaan?).
  3. Kod daripada artikel ini boleh digeneralisasikan dan dijadikan perpustakaan: format json boleh kekal sama, dan mungkin terdapat satu perpustakaan untuk mengeksport jenis java dan satu lagi untuk mengimport entiti mendix.
  4. Kita boleh menggunakan pendekatan yang sama untuk melakukan sebaliknya: menukar mendix kepada bahasa lain.

Kesimpulan

Mendix Platform SDK ialah ciri berkuasa yang membolehkan anda berinteraksi dengan apl mendix secara pengaturcaraan. Mereka menyenaraikan beberapa contoh kes penggunaan seperti mengimport/mengeksport kod, menganalisis kerumitan apl.
Sila lihat mereka sekiranya anda berminat.
Untuk artikel ini, anda boleh mendapatkan kod penuh di sini.

Atas ialah kandungan terperinci Menukar entiti JPA kepada Mendix. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan