Rumah >Java >javaTutorial >Menukar entiti JPA kepada Mendix
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.
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 ... }
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.
Ini boleh dilakukan dalam beberapa cara berbeza:
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:
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); } ... }
Kami bermula dengan mencari semua kelas dalam apl kami yang ditandakan dengan anotasi @Entity JPA.
Kemudian, untuk setiap kelas, kami:
Untuk setiap medan, kami:
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
Pada asasnya kami hanya memadankan jenis java dengan nilai enum tersuai kami dengan mencarinya dalam peta JAVA_TO_MENDIX_TYPE.
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 ... }
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).
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); } ... }
Akhir sekali, kami menyimpan Senarai
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
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; } }
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 } }
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" }
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();
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); }); }
Kami ada 4 sifat penting untuk ditetapkan, selain nama:
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); }); }
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.
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 ... }
Selepas beberapa saat, anda boleh membuka apl dalam Mendix Studio Pro dan mengesahkan keputusan:
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.
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!