DiskStore #maven. Remote EJB, JNDI, Dependency management, Service client, Context root, InitialContext, MyBatis 3

Hasonló dokumentumok
Ficsor Lajos Általános Informatikai Tanszék Miskolci Egyetem

A Java EE 5 plattform

BookStore #maven. Enterprise Application, Git, EJB, EAP/EAS, Logging, PostgreSQL/MySQL, JPA, Integration testing

Enterprise JavaBeans. Ficsor Lajos Általános Informatikai Tanszék Miskolci Egyetem. Az Enterprise JavaBeans

DiskStore. EJB client app, log4j config, custom context-root. Óbudai Egyetem, Java Enterprise Edition Műszaki Informatika szak Labor 5

BookStore #maven. Enterprise Application, Git, EJB, EAP/EAS, Logging, PostgreSQL/MySQL, JPA, Integration testing

BookStore #gradle. Enterprise Application, Git, EJB, EAP/EAS, Logging, PostgreSQL/MySQL, JPA, Integration testing

Adatbázisok webalkalmazásokban

Enterprise JavaBeans 1.4 platform (EJB 2.0)

Előszó. Bevezetés. Java objektumok leképzése relációs adatbázisokra OJB-vel Viczián István Viczián István

Oracle Containers for Java - j2ee alkalmazás szerver funkciók. Molnár Balázs Oracle Hungary

Stateless Session Bean

JNDI - alapok. Java Naming and Directory Interface

Lottery. WebLogic JMS, Jersey, JMX, JNDI. Óbudai Egyetem, Java Enterprise Edition Műszaki Informatika szak Labor 8. Bedők Dávid v0.

Java. Perzisztencia. ANTAL Margit. Java Persistence API. Object Relational Mapping. Perzisztencia. Entity components. ANTAL Margit.

JEE tutorial. Zsíros Levente, 2012

MVC Java EE Java EE Kliensek JavaBeanek Java EE komponensek Web-alkalmazások Fejlesztői környezet. Java Web technológiák

CREATE TABLE student ( id int NOT NULL GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name varchar(100) NOT NULL, address varchar(100) NOT NULL )

Hello Maven. JSE vs. JEE, JEE vs Spring. Óbudai Egyetem, Java Enterprise Edition Műszaki Informatika szak Labor 2. Bedők Dávid v0.

Perzisztencia. ANTAL Margit. Sapientia - EMTE. ANTAL Margit Java technológiák 11. előadás Perzisztencia

S04-2 Elosztott alkalmazások készítése

Az osztályok csomagokba vannak rendezve, minden csomag tetszőleges. Könyvtárhierarhiát fed: Pl.: java/util/scanner.java

webalkalmazások fejlesztése elosztott alapon

WEBFEJLESZTÉS 2. ADATBÁZIS-KEZELÉS, OSZTÁLYOK

Széchenyi István Egyetem

Hello, EJB! Egy egyszerű példa

JAVA webes alkalmazások

Inventory. [gradle maven]\jbossinventory

Biztonság java web alkalmazásokban

Bevezetés: az SQL-be

Segédanyag: Java alkalmazások gyakorlat

Adatkezelés. 11. előadás (Entity Beans)

OOP és UML Áttekintés

A Java Persistence API PersistenceAPI / 3

Segédanyag: Java alkalmazások gyakorlat

Hello World Servlet. Készítsünk egy szervletet, amellyel összeadhatunk két számot, és meghívásakor üdvözlőszöveget ír a konzolra.

Szoftver Tervezési Dokumentáció. Nguyen Thai Binh

EGY NAGYBÓL HÚSZ KISEBB

Komponensek együttműködése web-alkalmazás környezetben. Jónás Richárd Debreceni Egyetem T-Soft Mérnökiroda KFT

IBM WebSphere Adapters 7. változat 5. alváltozat. IBM WebSphere Adapter for Oracle E-Business Suite felhasználói kézikönyv 7. változat 5.


Tartalom. Az EJB 2.1 problémái Az EJB 3 megoldásai

DCOM Áttekintés. Miskolci Egyetem Általános Informatikai Tanszék. Ficsor Lajos DCOM /1

Shopping. JDBC, Datasource, Jasper Report. Óbudai Egyetem, Java Enterprise Edition Műszaki Informatika szak Labor 12. Bedők Dávid v0.

API tervezése mobil környezetbe. gyakorlat

Java és web programozás

Java és web programozás

STANDARD DEVELOPMENT U.L. FACTORY SYSTEMS GROUP IT DEPARTMENT

8. rész: Implementáció JDeveloperben

Osztott alkalmazások fejlesztési technológiái Áttekintés

Kivételkezelés, naplózás. Exception handling, logging

Osztályok. 4. gyakorlat

Abstract osztályok és interface-ek. 7-dik gyakorlat

WCF, Entity Framework, ASP.NET, WPF 1. WCF service-t (adatbázissal Entity Framework) 2. ASP.NET kliens 3. WPF kliens

Adattípusok. Max. 2GByte

5. rész: A Java EE és az Enterprise Bean réteg. Bakay Árpád dr. NETvisor kft (30)

Adattípusok. Max. 2GByte

Flash és PHP kommunikáció. Web Konferencia 2007 Ferencz Tamás Jasmin Media Group Kft

MVC. Model View Controller

OO PDO. Tehát PDO használatával, könnyen átállhatunk egy másik adatbáziskezelőre, anélkül hogy a kódot teljes egészében újraírnánk.

Adatbázisok* tulajdonságai

Se S r e ial a iza z t a ion o n (in n Ja J v a a v ) a Szerializáció

Javadoc. Dokumentációs megjegyzés (2) Dokumentációs megjegyzés (1) Dokumentációs megjegyzés felépítése

Egészítsük ki a Drupal-t. Drupal modul fejlesztés

Adatbázisok. 8. gyakorlat. SQL: CREATE TABLE, aktualizálás (INSERT, UPDATE, DELETE), SELECT október október 26. Adatbázisok 1 / 17

Adatbázis alapú rendszerek gyakorlat Adatbázis alapú alkalmazásfejlesztés Java, C# környezetben

Csomag. Adatbázis-objektum Programozási eszközök gyűjteménye Két részből áll. specifikáció törzs (opcionális)

Szervlet-JSP együttműködés

Hello Gradle. TestNG, Eclipse, IntelliJ IDEA. Óbudai Egyetem, Java Enterprise Edition Műszaki Informatika szak Labor 2. Bedők Dávid v0.

MDAC - Microsoft Data Access Components

Magazine () Java Authentication and Authorization Service. Óbudai Egyetem, Java Enterprise Edition Műszaki Informatika szak Labor 7.

Java Server Pages - JSP. Web Technológiák. Java Server Pages - JSP. JSP lapok életciklusa

OOP: Java 8.Gy: Abstract osztályok, interfészek

BackupPC. Az /etc/hosts fájlba betehetjük a hosztokat, ha nem a tejles (fqdn, DNS név) névvel hivatkozunk rájuk: # /etc/hosts #

SQL. 1.rész. 1.elıadás // Adatbázisok-1 elıadás // Ullman-Widom (Stanford) tananyaga alapján // Hajas Csilla (ELTE IK) 1

és az instanceof operátor

Java VIII. Az interfacei. és az instanceof operátor. Az interfészről általában. Interfészek JAVA-ban. Krizsán Zoltán

Tranzakciókezelés PL/SQL-ben

Excel ODBC-ADO API. Tevékenységpontok: - DBMS telepítés. - ODBC driver telepítése. - DSN létrehozatala. -Excel-ben ADO bevonása

Szálkezelés. Melyik az a hívás, amelynek megtörténtekor már biztosak lehetünk a deadlock kialakulásában?

Mobil Informatikai Rendszerek

Webes alkalmazások fejlesztése 12. fejezet. Szolgáltatás alapú kommunikáció (WCF) Giachetta Roberto. Eötvös Loránd Tudományegyetem Informatikai Kar

1. Gyakorlat: Telepítés: Windows Server 2008 R2 Enterprise, Core, Windows 7

Üdvözli Önöket A PGY3 tantárgy! Bakay Árpád dr. NETvisor kft (30) arpad.bakay@netvisor.hu

Junior Java Képzés. Tematika

SQLServer. DB Recovery modes

5. téma XML DB. Az adatkezelés és XML kapcsolata. Miért fontos az XML használata az adatbázis kezelésben?

Bánsághi Anna

Bevezető. Servlet alapgondolatok

Adatbázis-kezelés. Harmadik előadás

JUnit. JUnit használata. IDE támogatás. Parancssori használat. Teszt készítése. Teszt készítése

Teszt topológia E1/1 E1/0 SW1 E1/0 E1/0 SW3 SW2. Kuris Ferenc - [HUN] Cisco Blog -

Az internet ökoszisztémája és evolúciója. Gyakorlat 1

Osztott rendszerek, Java EE. Általános bevezető

Bevezetés a Seam keretrendszer használatába

SQL Server High Availability

OBJEKTUM ORIENTÁLT PROGRAMOZÁS JAVA NYELVEN. vizsgatételek

ADATBÁZIS-KEZELÉS - BEVEZETŐ - Tarcsi Ádám, ade@inf.elte.hu

A J2EE fejlesztési si platform (application. model) 1.4 platform. Ficsor Lajos Általános Informatikai Tanszék Miskolci Egyetem

BEVEZETÉS Az objektum fogalma

Átírás:

DiskStore #maven Remote EJB, JNDI, Dependency management, Service client, Context root, InitialContext, MyBatis 3 Óbudai Egyetem, Java Enterprise Edition Műszaki Informatika szak Labor 4 Bedők Dávid 2018-01-17 v1.1 Bedők Dávid (UNI-OBUDA) DiskStore (template.tex) 2018-01-17 v1.1 1 / 48

Local vs Remote EJB Bedők Dávid (UNI-OBUDA) DiskStore (overview.tex) 2018-01-17 v1.1 2 / 48

Előkövetelmények Mire van szükség ahhoz hogy egy EJB service-t távolról meghívjunk? Ismernünk kell a kiszolgáló server futásának helyét (gép, port) Ismernünk kell a server típusát, esetleg konfigurációs körülményeit (application server, jndi rules,...) Ismernünk kell a enterprise alkalmazás meta/descriptor adatait (application name, ejb module name,...) Ismernünk kell a meghívandó service aláírását, és rendelkeznünk kell azokkal az osztályokkal, melyek mindehhez szükségesek (szerializálható paraméterek, visszatérési értékek és kivételek, illetve mindezek által hivatkozott (fordításukhoz szükséges) típusok) A forráskódot érintő függőségek (EJB Service Client) miatt a Remote EJB használata legtöbbször olyan fejlesztési igényeknél jelentkezik, ahol a kliens és a szerver oldali fejlesztés is egy kézben van (a kliens kódja is a termék része). Ahhoz hogy ezen függőségek redundancia mentesen legyenek megvalósítva, az enterpise alkalmazás csomagolásának átszervezésére van szükség. Bedők Dávid (UNI-OBUDA) DiskStore (prerequisites.tex) 2018-01-17 v1.1 3 / 48

JNDI Java Naming and Directory Interface A JNDI segítségével elosztott alkalmazások absztrakt, erőforrás-független módon képesek szolgáltatásokat vagy regisztrált erőforrásokat keresni és kikérni. Objektumok halmazát tartja karban, tipikusan könyvtár (fa) strukúrában Biztosítja az elemek regisztrációját, keresését, lekérését Képes értesíteni a klienst egy elem megváltozásáról (eseményküldés) A kulcs tipikusan String, de egyébként egy Name interface-t implementáló példány Használat tipikus esete: Konfigurációs paraméterek beállítása/megadása (jndi.properties vagy egy Hashtable<String, String> feltöltése) Meg kell adni a szerver host nevét, port-ját, a kommunikáció protocol-ját Meg kell adni az InitialContextFactory osztály full qualified nevét (az osztálynak a classpath-on kell lennie) kiegészítő pl. authentikációs adatok megadása InitialContext létrehozása szerver specifikus factory-n keresztül javax.naming.context példány lookup( [JNDI name] ) metódusának segítségével a keresett erőforrás kikérése Bedők Dávid (UNI-OBUDA) DiskStore (jndi.tex) 2018-01-17 v1.1 4 / 48

JNDI használata Remote: a konfigurációról gondoskodni szükséges (lehet jndi.properties állományt is használni és a classpath-ra elhelyezni). 1 Hashtable < String, String > jndiproperties = new Hashtable < >(); 2 jndiproperties. put (" java. naming. factory. initial ", " org. jboss. naming. remote. client. InitialContextFactory "); 3 jndiproperties. put (" java. naming. provider. url ", " remote :// localhost :4447 "); 4 Context context = new InitialContext ( jndiproperties ); 5 context. lookup ("... "); Az itt megadott értékek JBoss 6.4 specifikusak, a hivatkozott InitialContextFactory osztálynak a classpath-on kell lennie. A String kulcsok helyett lehet használni az alábbi konstansokat is: javax.naming.context.initial_context_factory javax.naming.context.provider_url Local: a konfigurációt biztosítja a container (a beállított jndi.properties állomány már a classpath-on van). 1 Context context = new InitialContext (); 2 context. lookup ("... "); Bedők Dávid (UNI-OBUDA) DiskStore (jndi-usage.tex) 2018-01-17 v1.1 5 / 48

EJB JNDI név JNDI nevek szerkezete JNDI név [context]/[application-name]/[module-name]/[bean-name]![full-qualified-interface-name] context JavaEE standard java:comp: az adott komponens számára érhető el (ejb-n belül) java:module: az adott modul számára érhető el (ejb module-on belül) java:app: az adott alkalmazás számára érhető el (ear-on belül) java:global: az adott alkalmazás szerver domain számára érhető el (standalone domain-en belül) JBoss specifikus java:jboss/exported: container-en kívülről érhető el application-name Az ear deployment descriptorán (application.xml) keresztül állítható be. module-name Az EJB module deployment descriptorén (ejb-jar.xml) keresztül állítható be. bean-name A @Stateless( name = "[BEAN_NAME]") annotáció name értékén keresztül állítható be. Bedők Dávid (UNI-OBUDA) DiskStore (jndi-name.tex) 2018-01-17 v1.1 6 / 48

Követelmények technikai részletei A szerver oldali üzleti komponenst kiszolgáló alkalmazás szerver ún. kliens könyvtára, mely elsősorban az adott verziójú alkalmazás szerverrel való kommunikáció végett fontos (protokollok, szerver specifikus konfigurációs beállítások,...) (JBoss client library / WebLogic (full)client jar). Az alkalmazott alkalmazás szerver által használt EJB implementáció (a kliens oldal enterprise container nélkül fog futni, így a JavaEE 6.0 API nem lesz elegendő, helyette ezen (teljes) API JBoss/WebLogic implementációját fogjuk a kliens oldalon a classpath-ra elhelyezni). A Remote kommunikációban részt vevő típusok példányai a hálózaton keresztül fognak közlekedni, így ezek szerializálhatósága/deszerializálhatósága elengedhetetlen lesz, erről programozottan gondoskodni szükséges (Java-ban ehhez legtöbbször elegendő a Serializable interface-t implementálni, és esetleg a nem szerializálható mezők esetén a transient kulcsszót használni). Bedők Dávid (UNI-OBUDA) DiskStore (technical-details.tex) 2018-01-17 v1.1 7 / 48

DiskStore Lemezbolt Feladat: azonos módon a "BookStore"-hoz hozzunk létre egy lemezboltot. EJB service-eken keresztül valósítsuk meg a lemezekre nézve a CRUD műveleteket. Az adatbázis schema felépítése teljesen azonos lehet a "BookStore" projektben megismerttel. A webfelület kialakítása hasonló lehet a "BookStore" projektben megvalósított felülettel. A perzisztens réteg ne JPA-t használjon ORM-ként, hanem egy egyszerűbb, natív lekérdezésekre épülő (de type-safe) megoldást mutasson be a MyBatis 3 3 rd party library segítségével. A lemez egyedi azonosítójának (reference) ismeretében lehessen lekéri a lemez adatait távolról is (remote ejb call). Bedők Dávid (UNI-OBUDA) DiskStore (diskstore.tex) 2018-01-17 v1.1 8 / 48

Project stuktúra Alprojektek, modulok diskstore (root project) ds-weblayer (EAR web module) DiskPingServlet MVC minta szerint Servlet és JSP alapokon megvalósított webfelület ds-ejbservice (EAR ejb module) Üzleti metódusok implementációja Local EJB interface ds-persistence (EAR ejb module) ORM réteg (MyBatis 3) ds-ejbserviceclient (EAR library) Szerializálható domain osztályok (stub-ok), kivételek Remote EJB interface ds-client (EJB client alkalmazás) Része az EAR-nak: project + project Része az EJB client alkalmazásnak: project + project Bedők Dávid (UNI-OBUDA) DiskStore (subprojects.tex) 2018-01-17 v1.1 9 / 48

EJB Modulok közötti kör függőség Nem működő megoldás Bedők Dávid (UNI-OBUDA) DiskStore (modules-with-circles.tex) 2018-01-17 v1.1 10 / 48

EJB Modulok közötti kör függőség Működő megoldás (körök feloldása) Bedők Dávid (UNI-OBUDA) DiskStore (modules-without-circles.tex) 2018-01-17 v1.1 11 / 48

Modulok közötti függőségek DiskStore project A ds-ejbserviceclient kiszervezése a ds-ejbservice projektből jelenleg kizárólag a távoli EJB hívás végett történt. Általános esetben a módszer alkalmas a függőségi körök elkerülésére is, de most ez itt nem merült fel (gyakorlati hibát nem okozna az, ha a kliens classpath-ára feltennénk a teljes ds-ejbservice projekt artifactját, azonban ezzel súlyos elvi hibát okoznánk). Mivel a ds-ejbservice module-ban megmaradnak @Local EJB-k (lokálisan a teljes CRUD műveletet végre tudjuk hajtani, míg távolról csak egy lekérdezései lehetőségünk lesz), a ds-weblayer projekt függni fog a ds-ejbservice projekttől is a ds-ejbserviceclient mellett. A ds-ejbservice üzleti műveleteinek implementációja használni fogja a perzisztens réteget, csakúgy mint a BookStore példájában, így e téren a függőségi lánc a már megismerttel azonos. Bedők Dávid (UNI-OBUDA) DiskStore (modules-dependencies.tex) 2018-01-17 v1.1 12 / 48

Adatbázis schema Lemez és kategóriája 1 CREATE TABLE diskcategory ( 2 diskcategory_id INTEGER NOT NULL, 3 diskcategory_name CHARACTER VARYING (100) NOT NULL, 4 CONSTRAINT PK_DISKCATEGORY_ID PRIMARY KEY ( diskcategory_id ) 5 ); 6 7 CREATE TABLE disk ( 8 disk_id SERIAL NOT NULL, 9 disk_reference CHARACTER VARYING (100) NOT NULL, 10 disk_author CHARACTER VARYING (100) NOT NULL, 11 disk_title CHARACTER VARYING (100) NOT NULL, 12 disk_diskcategory_id INTEGER NOT NULL, 13 disk_price REAL NOT NULL, 14 disk_number_of_songs INTEGER NOT NULL, 15 CONSTRAINT PK_DISK_ID PRIMARY KEY ( disk_id ), 16 CONSTRAINT FK_DISK_DISKCATEGORY FOREIGN KEY ( disk_diskcategory_id ) 17 REFERENCES diskcategory ( diskcategory_id ) MATCH SIMPLE ON UPDATE RESTRICT ON DELETE RESTRICT 18 ); create-schema.sql Bedők Dávid (UNI-OBUDA) DiskStore (schema.tex) 2018-01-17 v1.1 13 / 48

EJB Service client A szerver és a kliens oldal számára is szükséges típusok Domain osztályok DiskStub DiskCategoryStub Mivel az Enum ősosztály implements Serializable, semmi kiemelt figyelmet nem érdemel ez az osztály. Kivétel osztály ServiceException Mivel az Exception ősosztály implements Serializable, semmi kiemelt figyelmet nem érdemel ez az osztály. Remote interface DiskFacadeRemote Bedők Dávid (UNI-OBUDA) DiskStore (ejbserviceclient.tex) 2018-01-17 v1.1 14 / 48

EJB Service client Build script 1 < p r o j e c t xmlns=" h t t p : // maven. apache. o r g /POM/ 4. 0. 0 " x m l n s : x s i=" h t t p : //www. w3. o r g /2001/XMLSchema i n s t a n c e " 2 x s i : s c h e m a L o c a t i o n=" h t t p : // maven. apache. o r g /POM/ 4. 0. 0 h t t p : // maven. apache. o r g /maven v4_0_0. x s d "> 3 4 <modelversion>4. 0. 0</ modelversion> 5 < a r t i f a c t I d>ds e j b s e r v i c e c l i e n t</ a r t i f a c t I d> 6 <packaging>j a r</ packaging> 7 <name>d i s k S t o r e EJB S e r v i c e s C l i e n t</name> 8 9 <p a r e n t> 10 <g r o u p I d>hu. q w a e v i s z. d i s k s t o r e</ g r o u p I d> 11 < a r t i f a c t I d> d i s k s t o r e</ a r t i f a c t I d> 12 <v e r s i o n>1. 0</ v e r s i o n> 13 </ p a r e n t> 14 15 <d e p e n d e n c i e s> 16 <dependency> 17 <g r o u p I d>o r g. j b o s s. s p e c</ g r o u p I d> 18 < a r t i f a c t I d>j b o s s j a v a e e 6.0</ a r t i f a c t I d> 19 <t y p e>pom</ t y p e> 20 </ d e pendency> 21 </ d e p e n d e n c i e s> 22 23 </ p r o j e c t> pom.xml Compile time csupán a @Remote annotáció miatt szükséges egy Java EE 6.0 API vagy implementáció, Run time azonban az EJB specifikáció további része is betöltésre kerül az EJB kliens oldaláról! Bedők Dávid (UNI-OBUDA) DiskStore (ejbserviceclient-maven.tex) 2018-01-17 v1.1 15 / 48

Remote interface Disk adatainak lekérdezése egyedi azonosító alapján 1 package hu. qwaevisz. diskstore. ejbserviceclient ; 2 3 import javax.ejb. Remote ; 4 5 import hu. qwaevisz. diskstore. ejbserviceclient. domain. DiskStub ; 6 import hu. qwaevisz. diskstore. ejbserviceclient. exception. ServiceException ; 7 8 @Remote 9 public interface DiskFacadeRemote { 10 11 String BEAN_NAME = " DiskStoreService "; 12 13 DiskStub getdisk ( String reference ) throws ServiceException ; 14 15 } DiskFacadeRemote.java A BEAN_NAME egy publikus konstans, mely része lesz az EJB service JNDI nevének. Mivel a Remote interface publikus, szokás ezt az értéket itt tárolni. A @Local interface-hez képest a lényegi különbség a @Remote annotáció használata. Egy interface-en jelen lehet egyszerre mindkét annotáció, arra azonban figyeljünk hogy ez esetben minden későbbi változásnál (új business method készítésénél) megvizsgálandó hogy az új funkció elérhető-e távolról is. Bedők Dávid (UNI-OBUDA) DiskStore (diskfacaderemote.tex) 2018-01-17 v1.1 16 / 48

Domain osztály Disk adatai A BookStore példában megismert BookStub-hoz képest a különbség csupán a Serializable interface implementálása annak érdekében, hogy a típus példányai a hálózaton keresztül közlekedni tudjanak. 1 package hu. qwaevisz. diskstore. ejbserviceclient. domain ; 2 3 import java. io. Serializable ; 4 5 public class DiskStub implements Serializable { 6 7 private String reference ; 8 private String author ; 9 private String title ; 10 private DiskCategoryStub category ; 11 private double price ; 12 private int numberofsongs ; 13 14 [..] 15 } DiskStub.java Bedők Dávid (UNI-OBUDA) DiskStore (diskstub.tex) 2018-01-17 v1.1 17 / 48

EAR finomhangolása Néhány apró ám annál fontosabb finomhangolási lehetőséget érdemes megvizsgálni az EAR összeállítása során. EAR 3 rd party library-k használata (Gradle esetén earlib dependency configuration. Maven esetén jar type dependency) (melyek nem ejb/web module-jai az EAR-nak, azonban olyan erőforrások, melyeket az elindított server domain nem töltött be (mivel legtöbbször csak ezen EAR artifact számára fontosak)). EJB Service client (nem transitive függőség!) MyBatis 3 EAR Java EE verziójának (version), megjelenítési (displayname) és hivatkozási nevének (applicationname) beállítása. Utóbbi része az EAR-on belüli szolgáltatások JNDI nevének (alapértelmezetten az ear fizikai file nevével egyezik meg). EAR-on belüli webalkalmazás(ok) context root tulajdonságának beállítása A context root segítségével lehet elérni a webalkalmazások Servlet osztályait, kiemelten publikus adat. Értékét az application.xml-ben definiáljuk, alapértelmezés szerint legtöbbször az ear-on belüli war fizikai file neve (alkalmazott build rendszer függvénye). Bedők Dávid (UNI-OBUDA) DiskStore (ear-customization.tex) 2018-01-17 v1.1 18 / 48

EAR Deployment descriptor 1 <? xml version =" 1.0 "?> 2 < application xmlns =" http: // java. sun. com / xml /ns/ javaee " xsi:schemalocation =" http: // java. sun. com / xml /ns/ javaee http: // java. sun. com / xml /ns/ javaee / application_6. xsd " xmlns:xsi =" http: // www.w3.org /2001/ XMLSchema - instance " version ="6"> 3 <application - name > diskstoreapp </ application - name > 4 <display - name >Disk Store Application </ display - name > 5 < module > 6 <web > 7 <web - uri >ds - weblayer. war </web - uri > 8 <context - root > diskstore </ context - root > 9 </ web > 10 </ module > 11 < module > 12 <ejb >ds - persistence. jar </ ejb > 13 </ module > 14 < module > 15 <ejb >ds - ejbservice. jar </ ejb > 16 </ module > Gradle esetén a projectek verziószáma empty String, míg Maven esetén tipikusan jelöljük pl. 1.0-ként. Utóbbi esetben a jar file nevek tartalmazni fogják a verziószámot. Legyen az alkalmazás hivatkozási neve diskstoreapp, míg a ds-weblayer webmodule context root-ja diskstore. A 3 rd party library-kat a library alkönyvtárba helyezzük el. 17 <library - directory > library </ library - directory > 18 </ application > application.xml Bedők Dávid (UNI-OBUDA) DiskStore (application-xml.tex) 2018-01-17 v1.1 19 / 48

EAR finomhangolása - I ds-ear build script 1 < project [..] > A <type> értéke jar, mely jelöli hogy az EAR számára ez 2 [..] csupán 3 rd party library, nem module. A ds-persistence 3 < dependencies > project MyBatis 3 függősége viszont automatikusan bekerül az EAR library-jai közé. 4 [..] 5 < dependency > 6 < groupid >hu. qwaevisz. diskstore </ groupid > 7 < artifactid >ds - ejbserviceclient </ artifactid > 8 < version >${ project. parent. version }</ version > 9 <type >jar </ type > 10 < exclusions > 11 < exclusion > 12 < groupid >org. jboss. spec </ groupid > 13 < artifactid >jboss - javaee -6.0 </ artifactid > 14 </ exclusion > 15 </ exclusions > 16 </ dependency > 17 </ dependencies > 18 [..] 19 </ project > A ds-ejbserviceclient nem szabad hogy transitive függőségként legyen része az EAR-nak, hiszen akkor a JBoss specifikus Java EE 6.0 API implementációját is tartalmazná a deployment. Ugyanezt az <exclusions> blockot szerepeltetni kell majd a ds-weblayer project esetén is (mivel a Maven a webapp lib könyvtárába is bemásolná a függőségeket). pom.xml Bedők Dávid (UNI-OBUDA) DiskStore (ear-maven.tex) 2018-01-17 v1.1 20 / 48

EAR finomhangolása - II ds-ear build script 1 < project [..] > A version alapértelmezett értéke 3, míg a librarydirectory-é root könyvtár 2 [..] (nem ajánlott ezt alkalmazni). 3 <build > 4 < directory >build </ directory > 5 < finalname >${ project. parent. artifactid } -${ project. version }</ finalname > 6 < plugins > 7 < plugin > 8 < groupid >org. apache. maven. plugins </ groupid > 9 <artifactid >maven -ear - plugin</ artifactid > 10 < version >${ version. plugin.ear }</ version > 11 <configuration > 12 <applicationname >diskstoreapp </ applicationname > 13 <displayname >Disk Store Application </ displayname > 14 < version >6</ version > 15 <defaultlibbundledir >library</ defaultlibbundledir > 16 < modules > 17 < webmodule > 18 < groupid >hu. qwaevisz. diskstore </ groupid > 19 <artifactid >ds - weblayer</ artifactid > 20 <contextroot >diskstore</ contextroot > 21 </ webmodule > 22 </ modules > 23 </ configuration > 24 </ plugin > 25 </ plugins > 26 </ build > 27 </ project > A JNDI név részét képző applicationname értéke diskstoreapp lesz, míg a pontos artifact URI-val megcímzett ds-weblayer context root-ja diskstore. pom.xml Bedők Dávid (UNI-OBUDA) DiskStore (ear-maven.tex) 2018-01-17 v1.1 21 / 48

EJB module deployment descriptor ds-ejbservice subproject src main resources META-INF ejb-jar.xml 1 <ejb - jar xmlns =" http: // xmlns. jcp. org / xml /ns/ javaee " xmlns:xsi =" http: // www.w3.org /2001/ XMLSchema - instance " 2 xsi:schemalocation =" http: // xmlns. jcp. org / xml /ns/ javaee http: // xmlns. jcp. org / xml /ns/ javaee /ejb - jar_3_2. xsd " 3 version =" 3.2 "> 4 <module - name > dsservicemodule </ module - name > 5 </ejb - jar > ejb-jar.xml Bedők Dávid (UNI-OBUDA) DiskStore (module-name.tex) 2018-01-17 v1.1 22 / 48

Bean név konfiguráció ds-ejbservice subproject 1 package hu. qwaevisz. diskstore. ejbservice. facade ; 2 [..] 3 @Stateless ( mappedname = "ejb / diskfacade ", name = DiskFacadeRemote. BEAN_NAME ) 4 public class DiskFacadeImpl implements DiskFacade, DiskFacadeRemote { 5 6 [..] 7 8 } DiskFacadeImpl.java Bedők Dávid (UNI-OBUDA) DiskStore (bean-name.tex) 2018-01-17 v1.1 23 / 48

DiskStore remote service JNDI név összeépítése JNDI név [context]/[application-name]/[module-name]/[bean-name]![full-qualified-interface-name] DiskStore remote JNDI név context: java:jboss/exported/ application-name: diskstoreapp/ module-name: dsservicemodule/ bean-name: DiskStoreService! full-qualified-interface-name: hu.qwaevisz.diskstore.ejbserviceclient.diskfacaderemote Bedők Dávid (UNI-OBUDA) DiskStore (disk-jndi-name.tex) 2018-01-17 v1.1 24 / 48

Deployment diskstore.ear [JBOSS_HOME] standalone log server.log 18:08:08,665 INFO [org. jboss.as.ejb3. deployment. processors. EjbJndiBindingsDeploymentUnitProcessor ] (MSC service thread 1-6) JNDI bindings for session bean named DiskStoreService in deployment unit subdeployment "ds - ejbservice.jar " of deployment " diskstore.ear " are as follows : java : global / diskstoreapp / dsservicemodule / DiskStoreService!hu. qwaevisz. diskstore. ejbservice java :app / dsservicemodule / DiskStoreService!hu. qwaevisz. diskstore. ejbservice. facade. DiskFaca java : module / DiskStoreService!hu. qwaevisz. diskstore. ejbservice. facade. DiskFacade java : global / diskstoreapp / dsservicemodule / DiskStoreService!hu. qwaevisz. diskstore. ejbservice java :app / dsservicemodule / DiskStoreService!hu. qwaevisz. diskstore. ejbserviceclient. DiskFacad java : module / DiskStoreService!hu. qwaevisz. diskstore. ejbserviceclient. DiskFacadeRemote java : jboss / exported / diskstoreapp / dsservicemodule / DiskStoreService!hu. qwaevisz. diskstore. e server.log ds-weblayer tesztelése: http://localhost:8080/diskstore/diskping http://localhost:8080/diskstore/disklist Bedők Dávid (UNI-OBUDA) DiskStore (deploy.tex) 2018-01-17 v1.1 25 / 48

EJB Client Build script 1 < p r o j e c t [.. ] > 2 [.. ] 3 <d e p e n d e n c i e s> 4 <dependency> 5 <g r o u p I d>hu. q w a e v i s z. d i s k s t o r e</ g r o u p I d> 6 < a r t i f a c t I d>ds e j b s e r v i c e c l i e n t</ a r t i f a c t I d> 7 <v e r s i o n>${ p r o j e c t. p a r e n t. v e r s i o n }</ v e r s i o n> 8 <s c o p e>c o m p i l e</ s c o p e> 9 </ d e pendency> 10 <dependency> 11 <groupid>l o g 4 j</ groupid> 12 < a r t i f a c t I d> l o g 4 j</ a r t i f a c t I d> 13 <v e r s i o n>${ v e r s i o n. l o g 4 j }</ v e r s i o n> 14 <s c o p e>c o m p i l e</ s c o p e> 15 </ d e pendency> 16 <dependency> 17 <groupid>j b o s s</ groupid> 18 < a r t i f a c t I d> c l i e n t</ a r t i f a c t I d> 19 <v e r s i o n>1. 0</ v e r s i o n> 20 <s c o p e>s y s t e m</ s c o p e> található lib könyvtárból). 21 <s y stempath>${ p r o j e c t. b a s e d i r }/ l i b / j b o s s c l i e n t. j a r</ s y s t e m P a t h> 22 </ d e pendency> 23 </ d e p e n d e n c i e s> 24 </ p r o j e c t> pom.xml A JBoss specifikus kommunikáció (nevezéktan, protocol) felépítéséhez szükséges a jboss-client.jar megtalálható a [JBOSS-HOME]\bin\client\ jboss-client.jar elérési úton. Ezen 3 rd party elegánsabb módja lehet egy JBoss repository-ból való kikérése artifact uri alapján. Demonstrációs céllal most ezt egy helyi könyvtárból olvassuk be (az EJB Client project gyökerében Bedők Dávid (UNI-OBUDA) DiskStore (ejbclient-maven.tex) 2018-01-17 v1.1 26 / 48

EJB Client Pszeudokód InitialContext létrehozása Programozott módon, Hashtable<String, String> feltöltésével vagy Classpath-ra elhelyezett jndi.properties segítségével Mindkét esetben szükség lesz egy JBoss specifikus kulcsra is: Kulcs: jboss.naming.client.ejb.context Érték: true DiskService (DiskFacadeRemote proxy) kikérése JNDI-ból context.lookup([jndi name]) metódus segítségével Disk lekérése (DiskStub példány) diskfacaderemote.getdisk([disk reference]) metódus segítségével Bedők Dávid (UNI-OBUDA) DiskStore (ejbclient.tex) 2018-01-17 v1.1 27 / 48

Initial Context létrehozása Programozott megoldás 1 package hu. qwaevisz. diskstore. client. context ; 2 [..] 3 public class ProgrammedContextFactory implements ContextFactory { 4 5 private static final String JBOSS_NAMING_CLIENT_EJB_CONTEXT_KEY = " jboss. naming. client. ejb. context "; 6 7 @Override 8 public Context getcontext () throws NamingException { 9 final Hashtable < String, String > jndiproperties = new Hashtable < String, String >() ; 10 jndiproperties. put ( Context. INITIAL_CONTEXT_FACTORY, " org. jboss. naming. remote. client. InitialContextFactory "); 11 jndiproperties. put ( Context. PROVIDER_URL, " remote :// localhost :4447 "); 12 jndiproperties. put ( JBOSS_NAMING_CLIENT_EJB_CONTEXT_KEY, " true "); 13 return new InitialContext ( jndiproperties ); 14 } 15 } ProgrammedContextFactory.java Bedők Dávid (UNI-OBUDA) DiskStore (initial-context-programmed.tex) 2018-01-17 v1.1 28 / 48

Initial Context létrehozása jndi.properties alapú konfiguráció src main resources jndi.properties 1 java. naming. factory. initial = org. jboss. naming. remote. client. InitialContextFactory 2 java. naming. provider.url=remote :// localhost :4447 3 jboss. naming. client.ejb. context = true jndi.properties 1 package hu. qwaevisz. diskstore. client. context ; 2 [..] 3 public class JndiPropertiesContextFactory implements ContextFactory { 4 5 @Override 6 public Context getcontext () throws NamingException { 7 return new InitialContext (); 8 } 9 } JndiPropertiesContextFactory.java Bedők Dávid (UNI-OBUDA) DiskStore (initial-context-jndi-properties.tex) 2018-01-17 v1.1 29 / 48

JNDI lookup 1 package hu. qwaevisz. diskstore. client ; 2 [..] 3 public class DiskClient { 4 5 private ContextFactory contextfactory ; 6 7 public DiskClient ( ContextFactory contextfactory ) { 8 this. contextfactory = contextfactory ; 9 } 10 11 public DiskStub getdisk ( final String reference ) { 12 DiskStub disk = null ; 13 try { 14 final DiskFacadeRemote facade = this. getdiskservice (this. contextfactory. getcontext ()); 15 disk = facade. getdisk ( reference ); 16 LOGGER. info ( disk ); 17 } catch ( final ServiceException e) { 18 LOGGER. error (e, e); 19 } catch ( final NamingException e) { 20 LOGGER. error (e, e); 21 } 22 return disk ; 23 } 24 25 private DiskFacadeRemote getdiskservice ( Context context ) throws NamingException { 26 return ( DiskFacadeRemote ) context. lookup ("[JNDI -NAME ]"); 27 } 28 } diskstoreapp/dsservicemodule/diskstoreservice! hu.qwaevisz.diskstore.ejbserviceclient.diskfacaderemote DiskClient.java Bedők Dávid (UNI-OBUDA) DiskStore (diskclient.tex) 2018-01-17 v1.1 30 / 48

Kliens oldali naplózás Log4J src main resources log4j.xml 1 <? xml version =" 1.0 " encoding ="UTF -8"?> 2 <! DOCTYPE log4j:configuration SYSTEM " log4j. dtd " > 3 < log4j:configuration debug =" true " 4 xmlns:log4j = http: // jakarta. apache. org / log4j / > 5 6 < appender name =" console " class =" org. apache. log4j. ConsoleAppender "> 7 < layout class =" org. apache. log4j. PatternLayout "> 8 <param name =" ConversionPattern " 9 value ="%d{yyyy -MM -dd HH:mm:ss } % -5p %c {1} :%L - %m%n" /> 10 </ layout > 11 </ appender > 12 13 <root > 14 <level value =" DEBUG " / > 15 <appender - ref ref =" console " /> 16 </ root > 17 18 </ log4j:configuration > log4j.xml Bedők Dávid (UNI-OBUDA) DiskStore (diskclient-log4j.tex) 2018-01-17 v1.1 31 / 48

Kliens alkalmazás tesztelése Futtatás Alkalmazás futtatása pl. az IDE által indított JVM-ből. 1 2017-11 -08 16:48:53 DEBUG EJBClientContext :720 - org. jboss. ejb. client. RandomDeploymentNodeSelector@37374a5e deployment node selector selected qwaevisz - mac node for appname = diskstoreapp, modulename = dsservicemodule, distinctname = 2 2017-11 -08 16:48:53 INFO DiskClient :28 - DiskStub [ reference = WAM124, author = Mozart, title = Requiem Mass in D minor, category =ROCK, price =2850.0, numberofsongs =4] 3 4 DiskStub [ reference = WAM124, author = Mozart, title = Requiem Mass in D minor, category =ROCK, price =2850.0, numberofsongs =4] 5 6 2017-11 -08 16:48:53 DEBUG RemoteNamingStoreV1 :263 - Channel end notification received, closing channel Channel ID c1d5c67d ( outbound ) of Remoting connection 5 ed31789 to localhost /127.0.0.1:4447 7 2017-11 -08 16:48:53 INFO remoting :445 - EJBCLIENT000016 : Channel Channel ID d1b9a950 ( outbound ) of Remoting connection 5 ed31789 to localhost /127.0.0.1:4447 can no longer process messages Bedők Dávid (UNI-OBUDA) DiskStore (diskclient-run.tex) 2018-01-17 v1.1 32 / 48

Alternatív ORM megoldások Van-e élet a JPA-n kívül? A BookStore project során megismerkedtünk a JPA-vel "Hello World" szinten. Ezt a Java EE standard részeként élő és fejlődő rendszert fogjuk a későbbiekben is használni, nagyvállalati környezetben ismerete elengedhetetlen. A JPA-nak azonban van egy viszonylag nagyobb tanulási görbéje, illetve - ami talán még veszélyesebb - egy olyan jellemzője, mi szerint komolyabb elméleti (itt értve ANSI SQL, ORM és JPA ismeretek hiányát) tudás nélkül is el lehet benne érni "futó kódrészleteket" (melyeket alkalmazásnak szándékosan nem neveznék). Főleg ez utóbbi miatt elég sok project belefut abba, hogy a JPA által generált lekérdezések, az entity manager által végrehajtott műveletek nem optimálisak, sőt a rendszer bottleneck-jeként hivatkoznak rá. Bedők Dávid (UNI-OBUDA) DiskStore (alternative-orm-1.tex) 2018-01-17 v1.1 33 / 48

Alternatív ORM megoldások type-safe, native SQL, JavaEE kompatibilitás A DiskStore project bemutat egy alternatív ORM megoldást, mely támogatja a Java EE integrációt és type-safe kódolást biztosít a JDBC felett. Előnye hogy kizárólag ANSI SQL ismeret szükséges hozzá, sokkal gyorsabban és könnyebben átlátható, ezáltal optimalizálható, mellőzi a gazdag automatizmust, és az ebből eredő problémákat. Nagy hátránya hogy native SQL utasításokat használ (ezáltal nem vendor független) és egy professzionális JPA alapú rendszerrel összehasonlítva egy idő után borzasztó kényelmetlen és számos boiler plate kódot eredményez(het). Bár ORM nélkül, egyszerűen a JDBC implementáció segítségével is tudunk adatbázis műveleteket végezni Java EE környezetben, ez lehetőleg sose legyen végcél (egy nem type-safe kódbázis karbantartása nagyvállalati környezetben szinte lehetetlen). Bedők Dávid (UNI-OBUDA) DiskStore (alternative-orm-2.tex) 2018-01-17 v1.1 34 / 48

MyBatis 3 Alternatív ORM megoldás http://www.mybatis.org/mybatis-3/ Verzió: 3.4.6-SNAPSHOT (2017-08-20) Artifact URI: org.mybatis:mybatis:3.4.6-snapshot A perzisztencia konfigurációs állománya egy config.xml, mely felelősségben hasonlatos a JPA-nál megismert persistence.xml-hez. Ezen xml dokumentum hivatkoz(hat) számos mapper.xml-re, melyben natív SQL utasításokat definiálhatunk. Az XML alapú konfigurációs elemek jelentős része itt is megtalálható annotáció formájában is. Java EE integrációhoz szükséges egy MyBatis CDI függőség használata is http://www.mybatis.org/cdi/ Verzió: 1.0.2 (2017-10-13) Artifact URI: org.mybatis:mybatis-cdi:1.0.2 A CDI része a Java EE-nek, és később részletesebben lesz szó róla. Egyelőre arra figyeljünk majd, hogy a beans.xml állományunk elérhető legyen a classpath-on. Bedők Dávid (UNI-OBUDA) DiskStore (mybatis.tex) 2018-01-17 v1.1 35 / 48

MyBatis 3 TransactionManager és Datasource konfiguráció 1 < transactionmanager type =" MANAGED " > 2 < property name =" closeconnection " value =" true " / > 3 </ transactionmanager > TransactionManager type lehetséges értékei: JDBC: A JDBC commit/rollback lehetőségeit direktben használja MANAGED: A MyBatis semmit nem fog ez esetben a tranzakcióval kezdeni (nem lesz soha commit vagy rollback) 1 < datasource type =" POOLED " > 2 < property name =" driver " value ="${ driver }"/> 3 < property name =" url " value ="${ url }"/> 4 < property name =" username " value ="${ username }"/> 5 < property name =" password " value ="${ password }"/> 6 </ datasource > Datasource type lehetséges értékei: UNPOOLED: minden egyes alkalommal nyitja/csukja a kapcsolatot POOLED: webalkalmazás fejlesztésnél gyakran használt, hatékony JNDI: a datasource-ot egy JavaEE container biztosítja JNDI-on keresztül (ezt fogjuk alkalmazni) Bedők Dávid (UNI-OBUDA) DiskStore (mybatis-datasource.tex) 2018-01-17 v1.1 36 / 48

MyBatis 3 Konfiguráció ds-persistence src main resources mybatis-config.xml 1 <? xml version=" 1.0 " encoding="utf -8"?> 2 <! DOCTYPE configuration PUBLIC " -// mybatis.org // DTD Config 3.0// EN" " http: // mybatis.org /dtd /mybatis -3 - config.dtd "> 3 <configuration > 4 <typealiases > 5 < typealias type ="hu. qwaevisz. diskstore. persistence. entity.disk " alias ="Disk " /> 6 < package name ="hu. qwaevisz. diskstore. persistence. entity "/> 7 </ typealiases > 8 <typehandlers > 9 < typehandler handler ="org. apache. ibatis.type. EnumOrdinalTypeHandler " javatype ="hu. qwaevisz. diskstore. persistence. entity. trunk. DiskCategory "/> 10 </ typehandlers > 11 < environments default =" development "> 12 < environment id=" development "> 13 < transactionmanager type =" MANAGED "> 14 < property name =" closeconnection " value ="true " /> 15 </ transactionmanager > 16 < datasource type =" JNDI "> 17 < property name =" data_source " value =" java:jboss / datasources / diskstoreds " /> 18 </ datasource > 19 </ environment > 20 </ environments > 21 < mappers > 22 < mapper resource ="hu/ qwaevisz / diskstore / persistence / mapper / DiskMapper.xml " /> 23 </ mappers > 24 </ configuration > mybatis-config.xml Bedők Dávid (UNI-OBUDA) DiskStore (mybatis-config.tex) 2018-01-17 v1.1 37 / 48

MyBatis 3 Néhány konfigurációs részlet Type alias: a mapper.xml állományokban a típusok full qualified neve helyett egy rövidebb változat is használható, ha megadunk egy alias-t. Annotáció is létezik minderre @Alias néven. Type handler: ha egy típus átalakítása nem egyértelmű (Java SQL), akkor type handler-t szükséges készíteni. Ha egy enum értéknek az ordinal-ját szeretnénk táblába beszúrni a neve helyett, erre létezik egy előre készített type handler (org.apache.ibatis.type.enumordinaltypehandler), melyet a példában használunk is. Environment: A tranzakció kezelés és az adatforrás konfigurációja. Mapper: konfigurációs állományok listája, melyben a natív SQL-ek szerepelnek (illetve a resultmap-ek). Itt lehet megadni mapper osztály okat is, amennyiben a konfiguráció annotáció alapú. Bedők Dávid (UNI-OBUDA) DiskStore (mybatis-details.tex) 2018-01-17 v1.1 38 / 48

Disk entitás 1 package hu. qwaevisz. diskstore. persistence. entity ; 2 [..] 3 @Alias (" Disk ") 4 public class Disk { 5 6 private Integer id; 7 private String reference ; 8 private String author ; 9 private String title ; 10 private DiskCategory category ; 11 private Double price ; 12 private Integer numberofsongs ; 13 14 public Disk () { 15 [..] 16 } 17 18 [..] 19 } Disk.java Bedők Dávid (UNI-OBUDA) DiskStore (disk.tex) 2018-01-17 v1.1 39 / 48

MyBatis 3 Mapper Mapper A konfiguráció által meghivatkozott mapper.xml állományok natív SQL utasításokat, illetve resultmap-eket tartalmaznak a megadott névtér alatt. A MyBatis 3 feladata alapvetően az, hogy az entitásokból és a mapper.xml állományokból az adatmanipulációhoz szükséges boilerplate kódokat elkészítse (attól lesz a történet type-safe, hogy ezen generált kódrészeket nem nekünk kell karbantartanunk). ds-persistence src main resources hu qwaevisz diskstore persistence mapper DiskMapper.xml 1 <? xml version=" 1.0 " encoding="utf -8"?> 2 <! DOCTYPE mapper PUBLIC " -// mybatis.org // DTD Mapper 3.0// EN" " http: // mybatis.org /dtd /mybatis -3 - mapper.dtd "> 3 < mapper namespace ="hu. qwaevisz. diskstore. persistence. mapper. DiskMapper "> 4 5 < resultmap [..] >[..] </ resultmap > 6 < select [..] >[..] </ select > 7 < insert [..] >[..] </ insert > 8 < update [..] >[..] </ update > 9 < delete [..] >[..] </ delete > 10 11 </ mapper > DiskMapper.xml Bedők Dávid (UNI-OBUDA) DiskStore (mybatis-mapper.tex) 2018-01-17 v1.1 40 / 48

Mapper állomány - count core input, core output 1 < select id=" count " parametertype =" String " resulttype =" int " > 2 SELECT COUNT (1) 3 FROM disk 4 WHERE disk_reference = #{ reference } 5 </ select > DiskMapper.xml Ezzel a deklarációval egy count nevű metódust definiáltunk, melynek String bementi paramétere lesz és egy int értékkel fog visszatérni. Bedők Dávid (UNI-OBUDA) DiskStore (mapper-count.tex) 2018-01-17 v1.1 41 / 48

Mapper állomány - readbyreference core input, entity output 1 < select id=" readbyreference " parametertype =" String " resulttype =" Disk "> 2 SELECT 3 disk_id AS id, 4 disk_reference AS reference, 5 disk_author AS author, 6 disk_title AS title, 7 disk_diskcategory_id AS category, 8 disk_price AS price, 9 disk_number_of_songs AS numberofsongs 10 FROM disk 11 WHERE disk_reference = #{ reference } 12 </ select > Ezzel a deklarációval egy readbyreference nevű metódust definiáltunk, melynek String bementi paramétere lesz és egy Disk entitás példányával fog visszatérni. Mivel a config.xml-ben definiáltunk egy alias-t, elegendő csupán Disk-et írni az entitás full qualified neve helyett. A lekérdezésben használt AS hozza létre a kapcsolatot az entitás mutator (setter) metódusával (Java bean elnevezési szabályok szerint). Bedők Dávid (UNI-OBUDA) DiskStore (mapper-readbyreference.tex) 2018-01-17 v1.1 42 / 48

Mapper állomány - readall - input, list of resultmap output 1 < resultmap type =" Disk " id=" DiskResult " > 2 <id property =" id" column =" disk_id " / > 3 < result property =" reference " column =" disk_reference " / > 4 < result property =" author " column =" disk_author " / > 5 < result property =" title " column =" disk_title " / > 6 < result property =" category " column =" disk_diskcategory_id " / > 7 < result property =" price " column =" disk_price " / > 8 < result property =" numberofsongs " column =" disk_number_of_songs " /> 9 </ resultmap > 10 11 < select id=" readall " resultmap =" DiskResult " > 12 SELECT * FROM disk 13 </ select > Egyedi (pl. több táblát érintő, vagy aggregált, esetleg egyedi asszociációkat tartalmazó) lekérdezés esetén nem tudjuk direktben entitásként definiálni a visszatérési értéket. Ezt a problémát hidalja át a resultmap definiálásának lehetősége. Itt csupán egy "hello world" mintát mutat, lehetőségei ennél sokkal szélesebbek. Értelemszerűen a property attribútum a megadott type mögött egy mutator metódust vár el. Bedők Dávid (UNI-OBUDA) DiskStore (mapper-readall.tex) 2018-01-17 v1.1 43 / 48

Mapper állomány - insert entity input, - output 1 < insert id=" create " parametertype ="Disk " usegeneratedkeys ="true " keyproperty ="id"> 2 INSERT INTO disk ( 3 disk_reference, 4 disk_author, 5 disk_title, 6 disk_diskcategory_id, 7 disk_price, 8 disk_number_of_songs 9 ) VALUES ( 10 #{ reference }, 11 #{ author }, 12 #{ title }, 13 #{ category }, 14 #{ price }, 15 #{ numberofsongs } 16 ) 17 </ insert > Ezen deklaráció által create néven fogunk tudni elérni egy Disk bementi értékkel bíró metódust. A bemenet különféle értékeinek itt már jelentősége van, pl. a {#author} egy getauthor() accessor metódust vár el a bemeneti entitásban. A példában az ID oszlop értékét sequence fogja generálni, a natív lekérdezésbe így nem szerepeltetjük az ID oszlopot. Ezt a usegeneratedkeys attribútummal tudjuk jelezni. Bedők Dávid (UNI-OBUDA) DiskStore (mapper-insert.tex) 2018-01-17 v1.1 44 / 48

Mapper állomány - update és delete hiányzó CRUD műveletek bemutatása 1 < update id=" update " parametertype =" Disk " > 2 UPDATE disk SET 3 disk_reference = #{ reference }, 4 disk_author = #{ author }, 5 disk_title = #{ title }, 6 disk_diskcategory_id = #{ category }, 7 disk_price = #{ price }, 8 disk_number_of_songs = #{ numberofsongs } 9 WHERE disk_id = #{ id} 10 </ update > 1 < delete id=" delete " parametertype =" int " > 2 DELETE FROM disk WHERE disk_id = #{ id} 3 </ delete > Bedők Dávid (UNI-OBUDA) DiskStore (mapper-update-and-delete.tex) 2018-01-17 v1.1 45 / 48

Mapper interface Az interface-ben megadott abstract metódusok pontosan illeszkednek a mögöttes xml konfigurációban definiált műveletekre. Ellenkező esetben futás idejű hibát kapunk (itt ez JDBC-s hatás, mely messze nem hibatűrő, azonban mégis kezelhetőbb, mintha minden Java-ban lenne). 1 package hu. qwaevisz. diskstore. persistence. mapper ; 2 3 import java. util. List ; 4 import hu. qwaevisz. diskstore. persistence. entity. Disk ; 5 6 public interface DiskMapper { 7 8 int count ( String reference ); 9 int create ( Disk disk ); 10 Disk readbyid ( Integer id); 11 Disk readbyreference ( String reference ); 12 List <Disk > readall (); 13 int update ( Disk disk ); 14 int delete ( Integer id); 15 } DiskMapper.java Bedők Dávid (UNI-OBUDA) DiskStore (mapper-interface.tex) 2018-01-17 v1.1 46 / 48

MyBatis konfiguráció betöltése A konfig állomány betöltésének egyszer meg kell történnie runtime. Ezt hivatott megoldani eme Provider osztály @Produces annotációval ellátott metódusa. A két annotáció a standard CDI része, nincs köze a MyBatis 3 library-hoz. Céljuk hogy bárhol elérhető legyen az SqlSessionFactory inject-álása, és az első ilyen esetben ezen metódus fusson le. A CDI-ról később lesz szó. 1 package hu. qwaevisz. diskstore. persistence. config ; 2 [..] 3 import javax. enterprise. context. ApplicationScoped ; 4 import javax. enterprise. inject. Produces ; 5 import org. apache. ibatis.io. Resources ; 6 import org. apache. ibatis. session. SqlSessionFactory ; 7 import org. apache. ibatis. session. SqlSessionFactoryBuilder ; 8 [..] 9 public class SqlSessionFactoryProvider { 10 11 @Produces 12 @ApplicationScoped 13 public SqlSessionFactory producefactory () throws IOException { 14 final InputStream inputstream = Resources. getresourceasstream ("mybatis - config.xml "); 15 final SqlSessionFactory factory = new SqlSessionFactoryBuilder (). build ( inputstream ); 16 return factory ; 17 } 18 19 } SqlSessionFactoryProvider.java Bedők Dávid (UNI-OBUDA) DiskStore (mybatis-load-configuration.tex) 2018-01-17 v1.1 47 / 48

MyBatis JavaEE környezetben 1 package hu. qwaevisz. diskstore. persistence. service ; 2 [..] 3 import javax. inject. Inject ; 4 import org. mybatis.cdi. Mapper ; 5 [..] 6 @Stateless ( mappedname = "ejb / diskservice ") 7 public class DiskServiceImpl implements DiskService { 8 9 @Inject 10 @Mapper 11 private DiskMapper mapper ; 12 13 @Override 14 public Disk readbyreference ( final String reference ) throws PersistenceServiceException { 15 LOGGER. debug ("Read Disk by reference (" + reference + ")"); 16 try { 17 return this. mapper. readbyreference ( reference ); 18 } catch ( final Exception e) { 19 LOGGER. error (e, e); 20 throw new PersistenceServiceException (" Failed to read Disk by reference (" + 21 } 22 } 23 [..] 24 } reference A @Inject a CDI megfelelője a @EJB annotációnak, míg a @Mapper itt egy CDI qualifernek használt annotáció, melyet a MyBatis CDI library definiál. + ")! " + e. getmessage (), e); DiskServiceImpl.java Bedők Dávid (UNI-OBUDA) DiskStore (mybatis-use-in-container.tex) 2018-01-17 v1.1 48 / 48