Wiki-Quellcode von IPluginEntities


Zeige letzte Bearbeiter
1 {{content/}}
2
3 == Schnittstelle IPluginEntities ==
4
5 {{figure image="plugin_entities_demo.png"}}
6 Ein Beispiel für ein Entities-Plugin, das eine einzelne Entität namens //ProgrammingLanguage// hinzufügt. Auf der linken Seite sehen Sie die neue Datenbanktabelle, die in derselben Datenbank erstellt wurde, die auch von {{formcycle/}} verwendet wird. Auf der rechten Seite veranschaulicht ein einfaches Portal-Plugin, wie diese Entität verwendet werden kann. Die Portalseite zeigt eine Liste aller verfügbaren Programmiersprachen und lässt den Benutzer auch neue Sprachen erstellen.
7 {{/figure}}
8
9 Die Schnittstelle für ein Entity-Plugin. Mit dieser Art von Plugin können Sie benutzerdefinierte JPA (Java Persistence API) Entitäten zu {{formcycle/}} hinzufügen. Sie können diese Entitäten dann in anderen Plugins verwenden, wie z. B. //IPluginPortal// oder [[IPluginFormPreRender>>doc:IPluginFormPreRender]]. Ein häufiger Anwendungsfall sind Portal-Plugins mit oder ohne //IPluginMenuEntries//, die Konfigurationsdaten oder eine Liste von Elementen in der Datenbank speichern müssen. Bitte beachten Sie, dass Plugin-Entities auf einem Frontend-Server nicht unterstützt werden - sie funktionieren nur auf einem Master-Server.
10
11 Jedes Entity-Plugin besteht aus den folgenden Komponenten:
12
13 * einer oder mehreren Entitätsklassen, die die {{jpath path="javax.persistence.Entity"/}} Annotation haben müssen
14 * einem [[Liquibase>>url:http://www.liquibase.org]]-Skript, das die erforderlichen Datenbanktabellen erstellt und für Updates verwendet werden kann, und
15 * eine {{jpath path="javax.sql.DataSource"/}} mit den Verbindungsdetails zu einer Datenbank (standardmäßig die FORMCYCLE-Datenbank)
16
17 Die Entitätsklassen werden automatisch übernommen, sofern sie mit der Annotation {{jpath path="javax.persistence.Entity"/}} versehen sind.
18
19 {{info}}
20 Wichtig! Stellen Sie keine harten Referenzen zwischen einer Plugin-Entität und einer {{formcycle/}}-Entität oder zwischen Entitäten verschiedener Plugins her. Eine harte Referenz zwischen zwei Entitäten wird durch eine Annotation wie {{jpath path="javax.persistence.OneToMany"/}} oder {{jpath path="javax.persistence.ManyToMany"/}} usw. hergestellt. Sie können jedoch Referenzen zwischen Entitäten eines einzelnen Entitäten-Plugins hinzufügen. Diese Einschränkung besteht, weil für jedes Plugin ein eigener {{jpath path="javax.persistence.EntityManager"/}} verwendet werden muss; und ein Entity-Manager weiß nicht, welche Entitäten einem anderen Entity-Manager zur Verfügung stehen. Wenn Sie {{formcycle/}}-Entitäten referenzieren müssen, sollten Sie die Verwendung von Soft-Referenzen in Betracht ziehen (d. h., Sie speichern einfach die //IEntity.getId()// oder //IUUIDEntity.getUUID()// einer Entität ohne Fremdschlüssel-Beschränkung).
21
22 Beachten Sie auch, dass es möglich wäre, eine Fremdschlüssel-Beschränkung in der Datenbank zwischen einer Plugin-Entität und einer {{formcycle/}}-Entität hinzuzufügen. Dies wird offiziell nicht unterstützt und sollte vermieden werden, da es unnötige Abhängigkeiten schafft, die Plugin-Isolation verletzt, die Migration eines Entity-Plugins auf eine andere Datenbank erschwert und bei zukünftigen Updates von {{formcycle/}} kaputt gehen kann.
23 {{/info}}
24
25 === Anwendungsfälle ===
26
27 * Speichern von Konfigurationsdaten durch ein Portal oder ein anderes Plugin
28 * Speichern von Elementen, die für eine Portalansicht benötigt werden
29
30 {{warning}}
31 Wenn Sie sich dafür entscheiden, die Entitäten in der gleichen Datenbank zu speichern, die auch vom {{formcycle/}}-System verwendet wird, stellen Sie sicher, dass Sie eindeutige Namen verwenden, die nicht mit den von {{formcycle/}} verwendeten Namen in Konflikt stehen. Dazu gehören Tabellennamen, aber auch andere Namen wie Fremd- oder Primärschlüssel-Constraints sowie die ID für das Liquibase Changeset.
32 {{/warning}}
33
34 === Methodensignaturen ===
35
36 {{panel title="{{code language='java'~}~}default IPluginEntitiesConnectionRetVal getConnectionDetails(){{/code~}~}" triggerable="true" fullwidth="true" styleClass="xm-code-panel"}}
37 (((
38 Standardmäßig werden Plugin-Entitäten in der Systemdatenbank gespeichert, d.h. in der gleichen Datenbank, die auch {{formcycle/}} verwendet. Stellen Sie in diesem Fall sicher, dass die Tabellennamen für die Plugin-Entitäten nicht mit bereits vorhandenen {{formcycle/}}-Tabellennamen kollidieren. Wir empfehlen Ihnen, jedem Tabellennamen ein eigenes Präfix hinzuzufügen.
39 )))
40
41 {{html}}<br>{{/html}}
42
43 (((
44 Falls erforderlich, können Sie diese Methode überschreiben und benutzerdefinierte Verbindungsdetails zurückgeben, um eine Verbindung zu einer anderen Datenbank herzustellen, in der Sie die Plugin-Entitäten speichern möchten.
45 )))
46
47 ; Rückgabewert
48 : Die Verbindungsdetails zu der Datenbank, in der die Plugin-Entitäten gespeichert werden sollen. Wenn //null//, wird die Systemdatenbank von {{formcycle/}} verwendet.
49 {{/panel}}
50
51 {{panel title="{{code language='java'~}~}default List<String> getLiquibaseScripts(){{/code~}~}" triggerable="true" fullwidth="true" styleClass="xm-code-panel"}}
52 (((
53 Diese Methode kann verwendet werden, um eine Liste von Liquibase-Skripten zur Initialisierung oder Aktualisierung der Datenbank zurückzugeben. Die Liquibase-Skripte werden in der Reihenfolge ausgeführt, wie sie von dieser Methode zurückgegeben werden. Ein Liquibase-Skript besteht aus einer Liste von Change-Sets. Jedes Changeset ist für eine einzelne logische Datenbankänderung verantwortlich, z. B. das Erstellen einer Tabelle oder das Hinzufügen einiger neuer Spalten zu einer Tabelle. Wenn eine leere Liste zurückgegeben wird, wird kein Liquibase-Skript ausgeführt.
54 )))
55
56 {{html}}<br>{{/html}}
57
58 (((
59 Wenn das Plugin zum ersten Mal installiert wird, werden die Skripte ausgeführt, um die anfängliche Datenbankkonfiguration zu erstellen. Wenn dieses Plugin dann auf eine neue Version aktualisiert wird und Sie auch die Datenbank aktualisieren müssen, können Sie dem Liquibase-Skript zusätzliche Änderungssätze hinzufügen. Alle Änderungssätze, die bereits ausgeführt wurden, werden nicht erneut ausgeführt. Damit dies funktioniert, stellen Sie sicher, dass Sie keine bestehenden Change Sets verändern, da Liquibase einen Hash des Quellcodes jedes Change Sets erstellt.
60 )))
61
62 {{html}}<br>{{/html}}
63
64 (((
65 In einigen Fällen kann Ihre Datenbankeinrichtung von der Version von {{formcycle/}} abhängen. Wenn dies der Fall ist und Sie bestimmte Liquibase-Skripte nur für bestimmte Versionen ausführen möchten, können Sie über {{jpath path="de.xima.fc.VersionsInfo"/}}#sdkVersion überprüfen, welche Version von {{formcycle/}} aktuell installiert ist.
66 )))
67
68 {{html}}<br>{{/html}}
69
70 (((
71 Weitere Informationen finden Sie auf den [[Dokumentationsseiten von Liquibase>>url:https://www.liquibase.org/documentation/changeset.html]].
72 )))
73
74 ; Rückgabewert
75 : Eine Liste von Liquibase-Skripten zum Initialisieren oder Aktualisieren der Datenbank. Kann eine leere Liste sein, falls Sie die Datenbank einrichten müssen. Jeder Eintrag muss ein Pfad zu einer Liquibase-XML-Datei sein, in dem Format, das von {{jpath path="java.lang.ClassLoader"/}}#getResources akzeptiert wird.
76
77 {{/panel}}
78
79 {{panel title="{{code language='java'~}~}void onDatabaseReady(IPluginEntitiesParams params) throws FCPluginException{{/code~}~}" triggerable="true" fullwidth="true" styleClass="xm-code-panel"}}
80
81 (((
82 Diese Callback-Methode wird aufgerufen, nachdem das Plugin initialisiert wurde und nachdem die Datenbank eingerichtet wurde und bereit ist, verwendet zu werden. Sie können die {{jpath path="javax.persistence.EntityManagerFactory"/}}, die an diese Methode übergeben wird, verwenden, um neue Entitäten zu erstellen oder bestehende zu holen, zu aktualisieren und zu löschen. Dies geschieht normalerweise durch Anlegen eines neuen {{jpath path="javax.persistence.EntityManager"/}} über {{jpath path="javax.persistence.EntityManagerFactory"/}}#createEntityManager.
83 )))
84
85 {{html}}<br>{{/html}}
86
87 (((
88 Es kann jedoch sein, dass die vom EntityManager angebotene API für Sie schwer zu bedienen ist. In diesem Fall können Sie die von {{formcycle/}} bereitgestellte DAO (Database Access Objects)-API verwenden, um einfacher mit Ihren Entitäten zu arbeiten. Verwenden Sie zunächst //IPluginEntitiesParams#getPluginEmManager// und speichern Sie den EM-Manager in einem statischen Feld zur späteren Verwendung in einer Bean oder einem Filter. Wenn Sie später auf die Datenbank zugreifen müssen, verwenden Sie {{jpath path="de.xima.fc.interfaces.plugin.param.entities.IPluginEmManager"/}}#newEntityContext, um einen neuen Entity-Kontext zu erstellen und diesen Kontext an die von {{jpath path="de.xima.cmn.dao.interfaces.IAbstractDao"/}} angebotenen Methoden zu übergeben. Zum Beispiel, wenn Sie eine Entitätsklasse //MyEntity// haben und eine Liste aller Entitäten abrufen wollen:
89 )))
90
91 {{html}}<br>{{/html}}
92
93 (((
94 {{code language="java"}}
95 try (final IBaseEntityContext ec = pluginEmManager.newEntityContext()) {
96 // Entitätskontext mit einem DAO verwenden
97 // dies holt alle vorhandenen MyEntity
98 new AbstractDao(MyEntity.class) {}.all(null, new QueryCriteriaManager());
99 }
100 {{/code}}
101 )))
102
103 {{html}}<br>{{/html}}
104
105 (((
106 Wenn Sie nur eine Teilmenge von Entitäten abrufen wollen, die einem bestimmten Kriterium entsprechen, verwenden Sie die {{jpath path="de.xima.cmn.criteria.QueryCriteriaManager"/}} API, die von {{formcycle/}} angeboten wird. Und schließlich können Sie, anstatt ein neues DAO zu erstellen, Ihre eigenen DAO-Klassen erstellen, indem Sie {{jpath path="de.xima.cmn.dao.interfaces.IAbstractDao"/}} erweitern.
107 )))
108
109 ; Parameter
110 : Diese Methode nimmt die folgenden Parameter entgegen:
111 :; params
112 :: Die Parameter, von denen diese Methode Gebrauch machen kann. Enthält die {{jpath path="javax.persistence.EntityManagerFactory"/}} für die Arbeit mit den Entitäten, sowie den {{jpath path="de.xima.fc.interfaces.plugin.param.entities.IPluginEmManager"/}}, um diese Arbeit zu erleichtern.
113 ; Throws
114 : Diese Methode darf die folgenden Exceptions werfen:
115 :; FCPluginException
116 :: Wenn diese Methode eine Ersteinrichtung durchführt, z. B. das Erstellen neuer Entitäten, und diese Einrichtung fehlschlägt. Wenn diese Ausnahme ausgelöst wird, wird dieses Plugin deaktiviert und nicht in Betrieb genommen.
117 {{/panel}}