miskolci egyetem gépészmérnöki és informatikai kar

53
Általános Informatikai Intézeti Tanszék Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez Szakdolgozat Miskolci Egyetem Gépészmérnöki és Informatikai Kar Mérnökinformatikus Szak (Bsc) Készítette: Burai Gergő NEPTUN kód: FGPRDE Tervezésvezető: Dr. Baksáné dr. Varga Erika

Upload: others

Post on 02-Feb-2022

2 views

Category:

Documents


0 download

TRANSCRIPT

Általános Informatikai Intézeti Tanszék

Az adattárolási modell és a modell osztályok

kidolgozása elektronikus kézirat feltöltő

rendszerhez

Szakdolgozat

Miskolci Egyetem Gépészmérnöki és Informatikai Kar

Mérnökinformatikus Szak (Bsc)

Készítette: Burai Gergő

NEPTUN kód: FGPRDE

Tervezésvezető: Dr. Baksáné dr. Varga Erika

I

Tartalomjegyzék

1. Bevezetés ......................................................................................................... 1

2. Felhasznált technológiák .................................................................................. 3

2.1 Spring és Spring MVC ............................................................................................................. 3

2.2 Maven ....................................................................................................................................... 6

2.3 MySQL ..................................................................................................................................... 6

2.4 ORM rendszerek és a MyBatis ................................................................................................. 7

2.5 JUnit ....................................................................................................................................... 10

2.6 SVN ........................................................................................................................................ 10

3. Specifikáció .................................................................................................... 13

3.1 Általános követelmények ....................................................................................................... 13

3.2 Részletes specifikáció ............................................................................................................ 13

3.3 Rendszerkövetelmények ......................................................................................................... 18

4. Tervezés ......................................................................................................... 19

4.1 Modulok ................................................................................................................................. 19

4.2 Adatbázis tervezés .................................................................................................................. 21

4.2.1 Felhasználó ......................................................................................................................... 23

4.2.2 Cikk .................................................................................................................................... 23

4.2.3 További egyedek ................................................................................................................ 24

4.2.4 Felhasználó és cikk közötti kapcsolatok ............................................................................ 24

4.3 Java osztályok tervezése ......................................................................................................... 25

4.4 Adathozzáférési interfészek ................................................................................................... 28

4.4.1 ConfigDAO ........................................................................................................................ 29

4.4.2 UserDAO ............................................................................................................................. 29

4.4.3 SubmissionDAO................................................................................................................. 30

4.4.4 HistoryDAO ....................................................................................................................... 33

5. Implementáció ................................................................................................ 34

5.1 Az adatbázis ................................................................................................................................. 34

5.2 Az adathozzáférési osztályok ....................................................................................................... 36

5.2.1 Modul felépítése ........................................................................................................................ 36

5.2.2 MyBatis konfiguráció ................................................................................................................ 37

II

5.2.3 MyBatis implementáció ............................................................................................................ 38

6. Tesztelés ......................................................................................................... 45

7. Összegzés ....................................................................................................... 48

8. Summary ........................................................................................................ 49

9. Irodalomjegyzék............................................................................................. 50

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

1

1. Bevezetés

A szakdolgozatom témája egy elektronikus kéziratfeltöltő rendszer adattárolási modelljének

kidolgozása, valamint az adathozzáférési réteg megtervezése és implementálása.

Csoportmunkában dolgoztunk hárman, Károlyi Máté, Fogt Tamás és jómagam. A feladatunk

célja a Miskolci Egyetem PSAIE (Production Systems and Information Engineering)

folyóiratához a webes felület kidolgozása és a mögötte lévő üzleti logikát, valamint az

adattárolást megvalósító kéziratkezelő rendszer létrehozása volt. Az én részem a feladatban a

rendszer legalsó rétegének, az adattárolási rétegnek a megtervezése és implementálása volt. Ez

magában foglalja az adattárolási modell osztályainak megtervezését, a relációs adatbázis

táblaszerkezeteinek kidolgozását, az adathozzáférési interfészek létrehozását, valamint az

ezeket megvalósító osztályok implementálását, ezáltal a különböző táblamódosítási és

lekérdezési adatbázis-műveletek megírását.

A PSAIE folyóirat célja magas színvonalú kutatási anyagok publikálása a termelési rendszerek

és a mérnök informatika területén. A tudományos folyóiratok általános célja a tudományos

témájú publikációk széleskörű terjesztése. Az elektronikus formában publikált kutatási

eredmények díjmentes rendelkezésre bocsátása a közzétett információt jobban láthatóvá és

könnyebben elérhetővé teszi, ezáltal gyorsabban hivatkozhatnak rájuk. A magas hivatkozási

arány megnöveli a folyóirat elismertségét is.

A cikkek általános publikációs fázisai:

preprint: a kiadóhoz megjelentetésre beküldött kézirat,

postprint: lektorálás utáni, a bírálók észrevételeinek, korrekciós kéréseinek

megfelelően kialakított verzió,

kiadói változat: korrektúrázott, tördelőszerkesztett, nyomdakész publikáció.

A megírt kéziratot a szerző először beküldi egy tudományos folyóirathoz. A tudományos

cikkek minőségét a bírálók ítélik meg. A tudományos folyóiratnál szakmai bírálatnak vetik alá

a beérkezett cikkeket, erről készül el a szakmai bírálat (review). A kéziratot elismert kutatók

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

2

bírálata alapján ítélhetnek publikálásra érdemesnek. Majd ha az elbírálás pozitív kimenetelű

volt, a cikket továbbküldik nyelvi lektorálásra. Ezután következik a nyomdai szerkesztés,

amely során nyomdakész állapotba kerül a cikk, készen a megjelentetésre. Végül bekerül a

folyóirat következő kiadványába és annak kiadásakor fog megjelenni.

A kéziratkezelő rendszer (manuscript handler system) egy szoftver, amelynek célja a

tudományos cikkek publikálási folyamatának megvalósítása és leegyszerűsítése. Magasszintű

környezetet és kezelőfelületet biztosít a felhasználók számára. Legfontosabb feladata a

különböző szerepkörök elkülönítése, ezek általában a következők: szerző, szerkesztő,

főszerkesztő, bíráló. A rendszer felel az ezekhez tartozó különböző funkciók és szolgáltatások

biztosításáért és a szerepkörök együttműködésének megvalósításáért a publikációs folyamat

során. Ezenkívül fontos még a könnyű adattárolás és adatelérés biztosítása és a hozzáférések

szerepkör szerinti szabályozása. Egyéb funkciókat is nyújthat a rendszer, például kimutatások

összeállítása, automatikus e-mail üzenetek küldése, események naplózása, stb.

A rendszer alapvetően a Miskolci Egyetem PSAIE tudományos folyóiratához készült, de

általános alkalmazást fejlesztettünk (ún. white-labeled product), ami azt jelenti, hogy bármely

hasonló folyóirat működtetéséhez fel lehet használni. A rendszer moduláris felépítése lehetővé

teszi, hogy a struktúra megváltozása nélkül le lehessen cserélni az egyes implementációkat,

ezáltal testreszabni az alkalmazást. Ezeket a pontokat a rendszerben testreszabási pontoknak

nevezik (customization point).

A szakdolgozatban először a feladat megoldása során felhasznált technológiákat ismertetem és

részletezem. Ezután a specifikáció értelmezését követő tervezési folyamatról és magáról a

specifikációról írok hosszabban. Ezt követően az implementációs folyamat részletezése

következik. Végül a szakdolgozatot egy magyar, valamint egy angol nyelvű összegzés zárja.

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

3

2. Felhasznált technológiák

A feladat elkészítésénél használt különböző kész komponensek és technológiák felsorolása

következik:

A rendszert az Eclipse nevű nyílt forráskódú, platformfüggetlen szoftverkeretrendszer

segítségével fejlesztettük, Java programozási nyelven.

A projektet az Apache Maven [3] plugin segítségével hoztuk létre különböző

modulokká felosztva, és a Maven segítségével épül fel az alkalmazás.

A webalkalmazást a Spring Web MVC (model-view-controller) [1] keretrendszer

használatával fejlesztettük.

Adattárolásra MySQL relációs adatbázist használtam.

Az adatbázis-kezelést a MyBatis [4] ORM keretrendszer használatával valósítottam

meg.

A webalkalmazást Apache Tomcat 8.0 szerveren fejlesztettük, teszteltük.

A webes felület a Bootstrap front-end keretrendszer és az Angular JS Javascript

keretrendszer segítségével készült el.

A teszteket a JUnit keretrendszer használatával írtam meg.

A közös munka során az SVN [2] verziókövető rendszert használtuk.

2.1 Spring és Spring MVC

A Spring MVC [1] a Spring keretrendszer része. Ez egy nyílt forráskódú alkalmazás-

keretrendszer és az IOC (Inversion of Control, fordított vezérlés) tervezési mintát valósítja

meg Java platformon. A rendszer alapvető funkcióit bármely Java alkalmazás felhasználhatja,

azonban készültek különböző modulok és bővítmények, amelyek webalkalmazások

fejlesztésében segítenek Java EE platformon. A Spring tulajdonképpen egy IOC konténer, az

IOC tervezési mintát a Dependency Injection (függőség injektálás) segítségével valósítja meg.

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

4

Szoftverfejlesztés során az egyes elemek működése gyakran függ más elemek által nyújtott

szolgáltatásoktól. Általában tudniuk kell, hogy mely komponensekkel kommunikáljanak, hogy

azok hol találhatóak, és hogy miként kommunikáljanak velük. Ha egy ilyen szolgáltatás

valamilyen módon megváltozik, akkor azt valószínűleg elég sok helyen át kell írni.

A hagyományos módszer a kód struktúrálására az, hogy a szolgáltatások elérésének módját az

alapvető logika részeként implementáljuk. Egy másik módszer, hogy elkerüljük az előzővel

járó nehézségeket, hogy csak függőségeket deklarálunk a szükséges szolgáltatásokhoz, és

valamilyen módon egy külső kódrészlet felel majd ezek megtalálásáért és inicializálásáért. Ez

lehetővé teszi, hogy a szolgáltatások megváltozása esetén az ezeket használó kódrészleteket ne

kelljen megváltoztatni. Ezt a fajta módszert hívjuk Dependency Injection-nek és a kódrészlet,

ami a függőségek feloldásáért felel, általában egy, a módszert megvalósító keretrendszer,

esetünkben a Spring.

A Spring MVC kérés (request) alapú keretrendszer és szorosan kapcsolódik a Servlet API-hoz.

A különböző HTTP kérések először egy diszpécser szervlethez érkeznek be

(DispatcherServlet), ami front controller-ként működik. Ez azt jelenti, hogy ennek az

osztálynak a felelőssége, hogy a kéréseket a megfelelő interfészekhez delegálja. Ezek közül a

legfontosabbak:

Controller: Az adattárolási modell (Model) és a felület (View) közötti réteg az MVC

struktúrában, feladata a bejövő kérések kezelése és a megfelelő válaszok

visszaküldése.

HandlerInterceptor: Opcionális elem, a bejövő kéréseken hajthatunk végre egyéb

műveleteket. Működése hasonló a szervlet filter működéséhez.

HandlerMapping: Kiválasztja a megfelelő objektumokat a kérések lekezelésére

valamilyen paraméter, vagy feltétel alapján.

LocaleResolver: Visszaadja az egyedi felhasználóhoz tartozó lokalizációs adatokat.

MultipartResolver: Fájlfeltöltést segítő funkciót ellátó interfész.

View: A kliensnek küldött válasz általában. Ez egy felület a Model rétegből lekérdezett

megfelelő adatokkal kitöltve.

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

5

ViewResolver: Visszaadja a felületet a neve alapján, amit aztán vissza lehet küldeni a

kliensnek válaszként.

Az 1. ábra jól mutatja a kérés kiszolgálásának folyamatát.

1. ábra: Kérés kiszolgálása Spring keretrendszerben [1]

A kéréseket lekezelő kontrollereket a @Controller annotációval kell ellátni. A kezelő

metódusokat pedig hozzárendelhetjük URL címekhez a @RequestMapping annotáció

segítségével. A Spring 3.0 verziótól kezdve a kontrollerekkel RESTful webalkalmazásokat is

készíthetünk. Mi is ezt az elvet követtük az alkalmazás fejlesztésekor, ennek jelentése az, hogy

a kliens és a szerver elkülönül egymástól, egyiket se érdekli a másik implementációja, a

kommunikáció az interfészeken keresztül zajlik, valamint hogy állapotmentes a

kommunikáció, tehát nem tárolhatunk semmilyen információt a klienstől a kérések között, a

kéréseknek minden szükséges adatot tartalmaznia kell. Ennek megvalósítására használható

például a @PathVariable annotáció, amellyel a kérés URL címének paramétereiből nyerhetjük

ki az adatokat, vagy a @RequestBody és @ResponseBody annotációk a JSON-alapú

kommunikációhoz. Mindkét módszert alkalmazzuk a rendszerünkben.

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

6

2.2 Maven

Az Apache Maven egy automatizált projekt buildelő eszköz Java projektekhez. A Maven

egyrészt leírja, hogy hogyan épül fel a projekt, másrészt meghatározza a projekt függőségeit

más moduloktól, vagy külső függvénykönyvtáraktól, amely csomagokat a build folyamat

során automatikusan le is tölt. Ezen információk egy xml fájlban vannak eltárolva, melynek

neve pom.xml. A Maven a külső csomagokat dinamikusan tölti le egy, vagy több repository-

ból, ez általában a központi Maven repository. A letöltött csomagokat a Maven helyi

gyorsítótárban tárolja.

A korábban említett pom.xml fájl (pom = Project Object Model) minden olyan információt

tartalmaz, ami szükséges egy projekt buildeléséhez. Ez általában magában foglalja a projekt

nevét, tulajdonosát és a függőségek listáját. A nagyobb projekteket általában szétszedik

különálló modulokká, ahol minden modulhoz külön tartozik egy pom fájl. Ekkor annak a

projektnek a pom fájlja, ami összefogja a modulokat, lesz a gyökere az alkalmazásnak, ennek

segítségével egyszerűen lehet buildelni az összes modult. Mi is ezt a moduláris felosztást

használtuk.

2.3 MySQL

A MySQL egy nyílt-forráskódú relációs adatbázis-kezelő rendszer (RDBMS). A relációs

adatbázis az adatokat táblákba szervezi, amelyek felépítése a következőképp néz ki: az adatok

azonos felépítésű sorokként kerülnek be egy táblába, ez a rekord. A felépítést, azaz a tárolandó

adatokat az oszlopok határozzák meg, ez pedig a mező. A tábla így egy egyedtípust

reprezentál. Ha egy mezőt elsődleges kulcsnak jelölünk ki, akkor annak értéke egyértelműen

meghatározza a rekordot, nem ismétlődhet. Ezt kihasználva megadhatjuk ezt a mezőt egy

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

7

másik táblában idegen kulcsnak jelölve, majd lekérdezéseknél egyesíthetjük a táblákat a

kulcsértékek alapján.

Minden relációs adatbázis-kezelő rendszer, így a MySQL is az SQL (Structured Query

Language, azaz struktúrált lekérdező nyelv) nyelvet használja az adatbázis létrehozására,

módosítására és az adatok lekérdezésére.

A MySQL nem biztosít grafikus felületet az adatbázisok kezelésére, kivéve a Windows

rendszereket. Helyette a parancssoros eszközöket használhatjuk, vagy egy külön program, a

MySQL Workbench letöltésével érhetjük ezt el. Én a munkám során parancssort és a

phpMyAdmin-t használtam, ami egy MySQL adatbázisok kezelésére PHP nyelven írt grafikus

felületet biztosító eszköz.

2.4 ORM rendszerek és a MyBatis

Az ORM (Object-Relational Mapping) keretrendszerek célja az adatbázisban tárolt adatok

átalakítása objektum-orientált programozási nyelvek által feldolgozható objektumokká.

Számos ingyenes és fizetős ORM rendszer áll a fejlesztők rendelkezésére, egyik

legnépszerűbb a MyBatis [4] (korábban iBatis). Munkám során ezt a keretrendszert használtam

az adatbázis kezelésére és az adatok lekérdezésére.

Az adatok a relációs adatbázisban táblákba vannak szervezve, ebben a tárolandó adatokat a

mezők határozzák meg, a komplex adatokat pedig külön táblában kell tárolni, idegen kulccsal

hivatkozva a fő táblára. Objektum-orientált nyelveknél az adatok objektumokban tárolódnak,

amelyek összetett adatokat reprezentálnak és a különböző adattagoknak megfelelő értékek

különböző táblákban helyezkedhetnek el. Ennek feloldását oldja meg az ORM keretrendszer.

Az objektumokat egyszerű skaláris adatok csoportjaira bontja fel az adatbázis számára.

Ugyanígy lekérdezéseknél a bejövő adatokat objektumokká szervezi. A nehézség az

objektumok logikai szerkezetének adatbázisban tárolható formára alakításának automatizálása,

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

8

megtartva az objektum tulajdonságait és ezek kapcsolatait, hogy igény szerinti vissza lehessen

az adatokat alakítani. Ha implementáltuk a letárolási és lekérdezési funkcionalitást, akkor az

objektumaink perzisztensek lesznek.

A hagyományos adathozzáférési technikákhoz viszonyítva (pl. JDBC) az ORM rendszerek

jelentősen lecsökkentik a szükséges kód mennyiségét.

Az ORM keretrendszerek hátránya abban nyilvánul meg, hogy magas absztrakciós szintű

eszközök, ezáltal nehézkesebben lehet az általánostól eltérő, összetett funkciókat

megvalósítani, mint például a JDBC technológiát alkalmazva. Ezenkívül az ORM szoftverre

való támaszkodás gyakran vezet gyenge tervezésű adatbázisok létrehozásához.

A MyBatis egy Java alapú ORM keretrendszer, ami az objektumokat tárolt eljárásokkal köti

össze vagy annotációk használatával, vagy külön XML dokumentumok segítségével (mapper).

Ez egy ingyenes szoftver, ami az Apache szoftvercsaládhoz tartozik. Eredetileg iBatis néven

indult, majd az iBatis 3.0-tól kezdődött a MyBatis, amelyet részben az iBatis eredeti alkotói

üzemeltetnek. A legtöbb ORM rendszerrel ellentétben a MyBatis nem az objektumokat képezi

le az adatbázis tábláira, hanem metódusokat képez le SQL utasításokra.

A MyBatis segítségével az adatbázis-kezelő rendszerek teljes funkcionalitása elérhető,

bonyolult lekérdezések, tárolt eljárások, nézetek (view). A JDBC-hez képest jelentősen

leegyszerűsíti a kódot, az SQL utasítások egy metódushívással végrehajthatóak. A MyBatis

képes egy lekérdezés eredményéül kapott rekordhalmazt automatikusan a hozzákötött

objektumot tároló kollekcióvá alakítani, ami lehet bármilyen Collection interfészt megvalósító

gyűjtemény osztály.

A MyBatis könnyen beépül a Spring keretrendszerbe. Ezt kihasználva felépíthetjük úgy a

kódunkat, hogy az üzleti logika megváltoztatása nélkül lecserélhetünk egyes lekérdezéseket,

vagy más SQL utasításokat. Ezenkívül a MyBatis támogatja a gyorsítótárazás használatát is.

Egy gyakran használt lekérdezést megjelölhetünk, hogy az adatok adatbázisból való kinyerése

után egy gyorsítótárba tárolja azokat, így legközelebb az utasítás már onnan fogja kiolvasni az

adatokat, ezáltal felgyorsítva a működést.

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

9

A MyBatis használatához létre kell hoznunk egy, vagy több interfészt (mapper-ek), ezek

metódusait meghívva hajtódnak majd végre az SQL utasítások. Ezt két módon érhetjük el, az

egyik az annotációk használata:

public interface carMapper {

@Select("select * from cars where id = #{id}")

Car selectCar(int id);

}

Ezután már csak meg kell hívnunk a metódust abból az osztályból, amelyik az adathozzáférést

valósítja meg. Másik lehetőség külön XML fájlokba szervezni az SQL utasításokat:

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="hu.iit.uni.miskolc.Example.CarMapper">

<select id="selectCar" parameterType="int"

resultType="hu.iit.uni.miskolc.Example.Car">

select * from cars where id = #{id}

</select>

</mapper>

Ilyenkor a mapper tag namespace tulajdonságának a mapper interfészt kell megadni. A

parameterType adja meg, hogy milyen típusú paramétert vár az utasítás, ezután a parancsban

bárhol a #{} szintaktikával hivatkozhatunk rá, mindegy, hogy mit írunk bele a MyBatis tudni

fogja, hogy az a paraméter. A resultType pedig megadja a visszatérési érték típusát. A

konverzió automatikusan végbemegy, ha lehetséges, de összetettebb struktúráknál resultMap-

et kell megadnunk, ami egy másik tag-re hivatkozik, ahol beállíthatjuk, hogy miként menjen

végbe az objektummá leképezés.

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

10

A mappereket a programból egy sqlSession objektumtól kérhetjük el, ami egy dataSource

objektumhoz kapcsolódik. Ez utóbbi kapcsolódik az adatbázishoz, be kell állítani az ehhez

szükséges tulajdonságait.

2.5 JUnit

A JUnit egy tesztelést segítő keretrendszer Java platformra. A teszt-vezérelt fejlesztés (TDD,

Test-Driven Development) alapvető eleme és az xUnit egységteszt-keretrendszer család tagja.

Egy külső függvénykönyvtár, ami a projektekben az egyik leggyakrabban használt

komponens.

Ahhoz, hogy egységteszteket írjunk, külön teszt-osztályokat kell létrehoznunk. Ebben a

metódusokat szerepük szerinti annotációkkal kell megjelölni. A @BeforeClass

annotációval megjelölt metódus egyszer fut le az osztályban létrehozott teszt-esetek előtt.

Hasonló a @Before, ami viszont minden teszt-metódus előtt lefut. Ennek mintájára

készíthetünk @AfterClass és @After metódusokat, amelyek utólag futnak le. Az

egységteszteket végző metódusokat pedig a @Test annotációval kell ellátni.

2.6 SVN

Az SVN [2] (Subversion) egy nyílt-forráskódú verziókövető rendszer (version control system,

VCS). A verziókövető rendszerek kezelik a fájlokat és mappákat, valamint számon tartják a

rajtuk elvégzett változtatásokat. Ez nagyban elősegíti a csapatban végzett fejlesztési munkákat,

hiszen nyomon követhetjük a saját és mások által végzett változtatásokat, nagy hiba esetén

bármikor visszatölthetjük a rendszer egy korábbi állapotát.

Bármilyen hálózaton üzemeltethetünk SVN szervert, ezáltal egymástól távol is eredményesen

dolgozhatunk. Az, hogy különböző fejlesztők egymástól távol képesek ugyanazt az

adathalmazt kezelni és módosítani, jelentősen megkönnyíti az együttműködést. Mivel a munka

verziókezelt (minden feltöltés egy verziószámmal van ellátva), nem kell attól félnünk, hogy

valami súlyos hibát, vagy minőségromlást okoz változtatásunk a rendszerben, ez esetben

csupán vissza kell töltenünk egy régebbi verziót.

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

11

Bizonyos verziókövető rendszerek egyben szoftver konfigurációs rendszerek is (software

configuration management system, SCM). Ezeket arra tervezték, hogy tudják kezelni a

forráskódot is és erre sok funkciót biztosítanak. Ilyen például, hogy felismerik és képesek

kezelni a különböző programnyelveket, valamint rendelkeznek szoftver fejlesztést segítő

beépített eszközökkel is. Az SVN azonban nem tartozik ezek közé, hanem egy általános

verziókövető rendszer, amellyel bármilyen adathalmazt kezelhetünk. Ez lehet egy szoftver

forráskódja, de lehet akár egy bevásárló lista, vagy teljesen más adatkollekció is.

A verziókövető rendszer központja az ún. repository, ami a központilag tárolt adathalmazt

jelenti. Ez általában fájlrendszer formájában tárolja az adatokat, faszerkezetbe van rendezve a

fájlok és mappák hierarchiája. Bármennyi kliens csatlakozhat a repository-hoz, olvashatja és

írhatja a fájlokat. Ez eddig nem sokban tér el egy fájlszervertől, amiben különbözik az az,

hogy a repository nyilvántartja az összes változtatást, emlékszik a fájlok minden verziójára.

A verziókezelő rendszerek másik alapvető eleme a munkapéldány (working copy). Ez a

verziókezelt fájlok lokális másolata az egyes kliensek gépén. A munkapéldányt a kliens

először letölti a repository-ból, majd azon végzi el a változtatásait, fejlesztéseit, ezután

visszatölti azt a repository-ba, amennyiben nem történt olyan változás, ami ütközik egy másik

kliens változtatásával. Ez utóbbi esetben először fel kell oldani a konfliktusokat, majd ezután

válik lehetővé a feltöltés. Ennek megoldásában is segítenek az SVN eszközök.

Szoftverfejlesztésnél általában van egy törzs (trunk), ami a szoftver fő verzióit tartalmazza.

Emellett vannak a különböző ágak (branch), amelyeken fejlesztik a változtatásokat, új

funkciókat hoznak létre és csak utána vezetik ezeket át a fő vonalra.

Az SVN legfontosabb műveletei a következők:

- checkout: saját munkapéldány létrehozása az adatok repository-ból való

letöltésével,

- commit: a munkapéldányon végrehajtott változtatások visszatöltése a repository-

ba,

- update: a munkapéldány frissítése a repository-ból, a végrehajtott változtatások

megtartásával,

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

12

- revert: a munkapéldány állapotának visszaállítása a repository egy verziójának

mintájára,

- merge: változtatások összefésülése különböző ágak között.

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

13

3. Specifikáció

3.1 Általános követelmények

A projekt célja egy elektronikus kéziratfeltöltő rendszer megtervezése és implementálása volt,

amelyen hárman vettünk részt Fogt Tamással, valamint Károlyi Mátéval. A rendszer a

Miskolci Egyetemhez tartozó PSAIE tudományos folyóirat számára készült. Az általam

elvállalt része a projektnek az adattárolási modell kidolgozása, valamint az adathozzáférési

réteg megtervezése és implementálása volt. Ennek értelmében meg kellett terveznem és

valósítanom a specifikációban megadott tárolandó adatok alapján az adattárolási modellt,

ennek alapján a rendszerben használt osztályokat, valamint a relációs adatbázis

táblaszerkezeteit. A táblákat kezdeti adatokkal is fel kellett tölteni, mely nagy segítséget

nyújtott a fejlesztés során. Ezt követően a feladatom az adatok elérésének a biztosítása volt.

Létre kellett hoznom az adathozzáférési interfészeket, valamint implementálnom kellett az

ezeket megvalósító osztályokat.

3.2 Részletes specifikáció

A cikkek elbírálási folyamata során a rendszerben a vele kapcsolatba kerülő felhasználók

különböző szerepkörökben különböző feladatokat látnak el. Ezek a szerepkörök határozzák

meg az alkalmazás funkcionalitását. Most az egyes szerepkörök részletezése következik a

tanszéktől kapott specifikáció és a menetközben megbeszélt módosítások alapján:

1. Szerző (Author) – Alapértelmezetten minden új felhasználónak ez lesz a szerepköre.

Regisztráció után cikkeket tölthet fel, melyeket kategorizálnia kell az ACM

kategórialista szerint, valamint megadhatja az esetleges társszerzőket is a már

regisztrált felhasználók közül. A cikkeinek állapotát a publikációs folyamat során

könnyen nyomon követheti. Látja továbbá a cikkek bírálatát, valamint saját adatait

módosíthatja.

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

14

2. Bíráló (Reviewer) – A szerzőn kívül minden szerepkör beállítása az admin felhasználó

által történik. A bírálónak meg kell adnia az ACM kategórialista szerint azokat a

tématerületeket, melyeknek szakértője. Ha elfogad egy bírálati felkérést, akkor

letöltheti a hozzá rendelt cikket, és kap egy határidőt, ameddig a bírálatnak el kell

készülnie. Ennek lejárta előtt kap egy automatikus figyelmeztető e-mailt. A bírálandó

cikk tanulmányozása után kitöltheti az egységes bírálati űrlapot. Szöveges értékelést ad

és kiválasztja a bírálata eredményét négy megadott értékből, aszerint, hogy elfogadja,

elutasítja, kis javításra, vagy nagymértékű javításra ítéli a cikket.

3. Főszerkesztő (Editor-in-Chief) – Látja a beérkezett cikkek listáját, állapotát, szerzőit és

rövid leírásukat. Ezenkívül látja a szerkesztők és a bírálók listáját. A feladata az, hogy

a cikkeket továbbítsa a szerkesztőkhöz a tématerület szerint. A bírálat eredményéről

értesíti a szerzőt, majd amennyiben elfogadott cikkről van szó, továbbítja azt nyelvi

lektorálásra, majd nyomdai szerkesztésre. Ő a kapcsolattartó a szerzők, szerkesztők és

bírálók között.

4. Szerkesztő (Editor) – Látja a főszerkesztő által neki küldött cikkek listáját, állapotát,

rövid leírását. Látja a tématerület szerint lehetséges bírálók listáját és a cikkekhez

beérkezett bírálatokat. Feladata a beérkezett cikkek gyors átnézése (szoftveres plágium

ellenőrzés, formai követelmény ellenőrzés). Majd a cikkeket bírálókhoz kell

hozzárendelnie szabvány szövegű email segítségével, amelyben a bírálati határidő is

megjelölésre kerül. Legalább két bíráló véleményére van szükség, ellentmondás esetén

többet is be lehet vonni. Értékeli a bírálatokat, majd dönt a cikk megjelentetéséről,

elutasításáról vagy újra bírálásáról. Ezután értesíti a főszerkesztőt a döntésről.

5. Nyelvi lektor (Proofreader) – Látja a főszerkesztőtől kapott, elfogadott cikkek listáját.

Feladata a cikkek nyelvi lektorálása. Ha végzett, visszajelez a főszerkesztőnek és

visszaküldi a javított cikket, vagy túl sok hiba esetén az eredeti cikket jelezve, hogy

szerzői javításra van szükség.

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

15

6. Nyomdai szerkesztő (Technical Editor) – Látja a főszerkesztőtől kapott elfogadott és

nyelvi lektorált cikkek listáját. Feladata a cikkek nyomdai előkészítése, a formátum

véglegesítése. Ha elkészült, visszajelez a főszerkesztőnek.

7. Admin – Kitüntetett felhasználó, feladata a regisztrált felhasználók felügyelete,

támogatása és a felhasználói adatbázis karbantartása. Ő osztja ki a különböző

szerepköröket is. A rendszerünk alapvetően tartalmaz egy admin jogosultságú

felhasználót.

Egy cikk (Submission) lehetséges állapotai a következők:

received: A szerző feltöltötte a cikket, a főszerkesztőre vár, hogy szerkesztőhöz

rendelje.

assigned: A főszerkesztő hozzárendelte a cikket egy szerkesztőhöz, a szerkesztőre vár,

hogy ellenőrizze, majd pedig elküldje elbírálásra.

referring: A szerkesztő hozzárendelte a cikket bírálókhoz, várakozás a bírálatok

elkészülésére.

reviewed: Elkészült legalább egy bírálat, várakozás a többi bírálat beérkezésére, vagy a

szerkesztő végső ítéletére.

rejected: A cikk el lett utasítva a szerkesztő által, vagy a gyors ellenőrzés, vagy a

bírálatok alapján.

accepted: A cikket elfogadta a szerkesztő, publikálható. Várakozás a főszerkesztőre,

hogy felvegye a nyelvi lektorral a kapcsolatot.

major: A szerkesztő a bírálatok alapján nagymértékű javításra ítélte a cikket.

Várakozás a szerzőre, hogy elvégezze a javításokat.

minor: A szerkesztő a bírálók véleménye alapján kismértékű javítást rendel el.

Várakozás a szerzőre, hogy elvégezze a javításokat.

proofread: A nyelvi lektorálás elkészült, várakozás a főszerkesztőre, hogy felvegye a

nyomdai szerkesztővel a kapcsolatot és a nyomdai szerkesztőre, hogy elvégezze a

végső formázást.

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

16

edited: Elkészült a formai szerkesztés, várakozás a cikk kiadványhoz rendelésére és a

kiadvány megjelentetésére.

published: A folyamat vége, a cikk sikeresen publikálva.

A 2. ábra végigvezet az elbírálási és publikálási folyamaton a cikk lehetséges állapotain

keresztül, segítségével könnyebben megérthető a procedúra.

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

17

2. ábra: A publikálási folyamat

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

18

3.3 Rendszerkövetelmények

A rendszert modern Java-s keretrendszerben kellett létrehozni, amelyre mi a Spring Web MVC

keretrendszert választottuk.

A programnak egy alkalmazásszerveren kell futnia, mi a fejlesztés során az Apache Tomcat

8.0 szervert használtuk.

Adattárolásra MySQL relációs adatbázis kellett használnom. Emellett a Java-ban kódolt

adatbázis-kezelő metódusokat a MyBatis ORM keretrendszer segítségével kellett leképeznem

SQL utasításokra.

A csapatmunkához egy számunkra létrehozott SVN szervert kellett használnunk, melynek

segítségével akár a témavezető tanár, akár a szakmai konzulensek nyomon tudták követni a

munkánk előrehaladását.

Fejlesztésre az Eclipse fejlesztőkörnyezetet kellett használnunk, amely a többi általunk

használt eszközt is támogatja.

A build folyamatok kezelésére a Maven eszközt kellet használni.

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

19

4. Tervezés

4.1 Modulok

Mint azt korábban említettem, az alkalmazást Maven modulokba szerveztük. A projekt

moduláris felosztása a következő:

model: Ez a modul tartalmazza a pojo-kat (plain old java object), vagyis az alap java

osztályokat, amelyek a tárolandó adatszerkezeteket reprezentálják a rendszerben.

Ezeket az osztályokat bean-ként kell létrehozni, annak érdekében, hogy könnyen

együttműködjenek a többi komponenssel.

dao: Ez a modul (Data Access Object) tartalmazza azokat az interfészeket, amelyek az

adatok általános (adatbázistól független) elérését szolgáló viselkedést írják le. Az

ehhez tartozó implementáció bármikor lecserélhető a modul megváltoztatása nélkül. Ez

a modul tartalmazza továbbá az általam definiált általános kivétel osztályt is.

dao-mysql: Ebben a modulban implementálom a dao interfészeit, MySQL specifikus

megoldásokkal. Itt kezelem le a különböző MySQL és egyéb kivételeket is,

becsomagolva őket a dao modul általános kivételébe, így a többi modul

megvalósítástól függetlenül kaphatja el azokat.

service: Ez a modul tartalmazza azokat az interfészeket, amelyek a controller felé

nyújtandó szolgáltatásokat írják le.

service-impl: Itt történik a service modul interfészeinek a megvalósítása. Hozzáfér a

dao modulhoz, hívhatja az interfészek metódusait az adateléréshez. Lényegében itt

található az üzleti logika, valamint az egyéb funkciók (pl. email küldés, kitömörítés,

stb.) is.

controller: Ez a modul a kapcsolattartó a webes felület (front-end) és a háttérrendszer

(back-end) között. Spring controller szervleteket tartalmaz, ezek elkapják a http

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

20

kéréseket, amelyek a klienstől érkeznek és meghatározzák, hogy a különböző url-ek

esetében milyen szolgáltatásokat kell végrehajtani és visszaadja a megfelelő

megjelenítési felületet a megfelelő adatokkal kitöltve. Hozzáfér a service modulhoz, a

service interfészek által nyújtott szolgáltatásokat hívja.

web: Itt található minden, ami a webes felülethez szükséges. Legfőképp a bootstrap

front-end keretrendszerhez tartozó javascript, css és jsp fájlokat tartalmazza. Ezenkívül

ez a modul fogja össze az egész rendszert, itt történik a Spring konfigurálása is, a

web.xml fájlban meg van adva, hogy a http hívásokat a dispatcher-servlet.xml

diszpécser fogadja, és a controllerben keresse meg a hozzá tartozó funkciót. Az

application-context.xml fálj pedig az alkalmazás kontextus bean-jeit definiálja.

util: Ez a modul tartalmazza azokat az egyéb funkciókat, amelyek nem tartoznak a

többi modulhoz. Ilyen például a rendszer naplózási funkciója (logger).

Az én részem a projektben a model, a dao és a dao-mysql modulok fejlesztése, tehát az

adattárolást és az adatelérést megvalósító funkcióké. A modulok közti függőségeket a 3. és 4.

ábra szemlélteti, sötétebb színnel jelölve az általam fejlesztett részt.

3. ábra: Moduláris felépítés

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

21

4. ábra: Függőségi fa (Dependency Tree)

4.2 Adatbázis tervezés

A tervezés során az én első feladatom az adattárolási modell kidolgozása volt, majd az

elképzelésből létrehozni egy egyedkapcsolati modellt (ER modell). Ebben a tanszék által

megadott specifikáció volt a segítségemre. El kellett különíteni a fő egyedeket, meghatározni

ezek tulajdonságait és kidolgozni az egyedek közötti számos kapcsolatot. Ez a modell a

fejlesztés során több alkalommal is megváltoztatásra került, ezáltal jelentős átdolgozási

munkálatokat okozva.

Az adattárolási szerkezet végleges ER modelljét szemlélteti az 5. ábra.

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

22

5. ábra: ER modell

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

23

4.2.1 Felhasználó

Látható, hogy az adattárolás két fő egyede a felhasználó (User) és a cikk (Submission). A

felhasználó egyed kulcsmezeje a felhasználónév (username), ezért annak egyedinek kell lennie

a rendszerben, valamint ehhez tartozik egy jelszó, amelyet titkosítva tárol el az adatbázis

(password). Ezenkívül tartalmazza az alapvető adatokat, mint név lebontva titulusra,

családnévre, keresztnévre és esetlegesen második keresztnévre (title, first_name,

middle_name, last_name); cím lebontva országra, megyére, városra, irányítószámra, utcára és

házszámra (country, state, city, postal_code, street, home_address); az elérhetőségek, mint

telefonszám, e-mail cím és fax (phone, e-mail, fax); valamint a szervezet, amihez a

felhasználó tartozik (organization).

Van két többértékű tulajdonsága is, az egyik a szerkesztők és bírálók esetében tárolja le azokat

a tématerületeket, amelyekhez értenek az ACM kategórialista alapján (ACM_area). Míg a

másik a szerepköröket megvalósító többértékű tulajdonság, ami a felhasználóhoz tartozó

jogkört, vagy jogköröket tárolja (role). Tárolunk továbbá egy bináris információt is, ami

aszerint módosul, hogy a felhasználó hozzáférhet-e a rendszerhez, értéke alapértelmezetten ’1’

(enabled). Ennek az az oka, hogy egy felhasználó törlésekor nem távolítjuk el fizikailag az

adatait, csak kitiltjuk az alkalmazásból azáltal, hogy ’0’-ra állítjuk ezt a tulajdonságát.

4.2.2 Cikk

A cikk egyednek egy egyedi azonosító lesz a kulcs tulajdonsága (id). Tárolásra kerül továbbá

a címe (title), a cikkhez tartozó, feltöltésnél megadott kulcsszavak többértékű tulajdonságként

(keywords), egy rövid összefoglaló a cikk tartalmából (abstract), a cikket tartalmazó szerverre

feltöltött zip formátumban tömörített fájl fájlfeltöltésnél generált elérési útvonala (file_path),

valamint a feltöltés dátuma (upload_date). A cikk mindenkori állapota is itt kerül tárolásra

(state), amely a specifikációban részletezett értékeket veheti fel. Ezenkívül azt, hogy a cikk

mely tudományterülethez tartozik a kategórialista alapján, itt is ugyanazzal a névvel ellátott

tulajdonság tárolja (ACM_area).

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

24

4.2.3 További egyedek

A naplózási funkció által keletkezett naplóbejegyzések külön egyedként vannak eltárolva

(History). Ennek tulajdonságai a keletkezési dátum (date) és a bejegyzés szöveges formában

(history_message). A History egyed valósítja meg többek között a cikk állapotváltozásainak a

naplózását, ezért egy-több kapcsolat van közte és a cikk egyed között.

Van még egy segédtábla is, ami később került be az ER modellbe egyedként, mivel a

fájlfeltöltési funkció kidolgozásánál derült ki az igénye (Upload Config). Erre azért volt

szükség, mert a feltöltött fájlok elérési útvonala eltérő szintaktikájú lehet attól függően, hogy a

szerver milyen operációs rendszeren üzemel. Tulajdonságként van eltárolva a feltöltési

(upload_path), valamint a kitömörítési útvonal (unzip_path) OS specifikus kezdete.

4.2.4 Felhasználó és cikk közötti kapcsolatok

A leggyakoribb összeköttetés a két fő egyed között a szerzői kapcsolat, ami fájlfeltöltésnél

kerül be az adatbázisba (corresponding_author). Ez egy-több kapcsolat, tehát egy felhasználó

bármennyi cikknek lehet a szerzője, de egy cikknek csak egy szerzője lehet, a társszerzők

máshol vannak tárolva. A társszerzői kapcsolat több-több típusú, ennélfogva külön tábla

tárolja a kapcsolatot (co_author). Egy-több kapcsolatként van még létrehozva a bírálati

folyamat során a cikkhez rendelt szerkesztő (assigned_editor), nyelvi lektor

(assigned_proofreader) és nyomdai szerkesztő (assigned_technical_editor).

Mivel bírálóból több is lehet, ezért ez több-több típusú kapcsolat (review), ahol

tulajdonságként vannak felvéve az elkészült bírálat adatai. A bíráló kijelölésekor bekerül egy

rekord az ezt megvalósító táblába, ami párosítja a cikket a bírálóval. A bírálat elkészülte után

ez a rekord kiegészül a megfelelő adatokkal, ezek a következők: az összefoglaló értékelés

(message), a részletes szöveges vélemények, meglátások (details), a szerkesztőnek szánt,

szerző által a bírálatban nem látható üzenet (secret_message), az elkészülés dátuma (date),

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

25

valamint a bírálat végeredménye (verdict), ami előre meghatározott négy értéket vehet fel,

amelyek: -elfogadva (accepted), -elutasítva (rejected), -minor (kis javítás szükséges), -major

(nagymértékű javítás szükséges).

4.3 Java osztályok tervezése

A 6. ábra szemlélteti a model modul csomaghierarchiáját, valamint a pojo osztályokat.

6. ábra: Model modul szerkezete

(A hu.uni.miskolc.iit.manuscript minden csomagnév eleje, a model pedig a modulban lévő

minden csomagé, ezért a továbbiakban csak az ezt követő résszel hivatkozok a csomagokra.)

A config csomag tartalmazza az UploadConfig osztályt, ami a fájlfeltöltési információkat

reprezentálja. A user csomagban vannak a felhasználókhoz köthető elemek, így magát a

felhasználót megvalósító User osztály, valamint a különböző szerepköröknek megfelelő

értékeket tároló Role enumeráció. A User osztály adattagként tartalmazza az ER modellben

ábrázolt összes tulajdonságot, valamint a lehetséges szerepköröket egy Role enumeráció típusú

halmaz (Set<Role>) kollekcióban és a felhasználó által megadott ACM tudományterületeket

szintén halmazban tárolva.

Itt történik a szerver oldali validáció megvalósítása is, validáló annotációk segítségével.

Például a jelszó adattag felett a @Length(min=8, max=12) annotáció a jelszó lehetséges

hosszát határozza meg. Ez a validáció a controller modulban valósul meg, a @Validated

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

26

annotáció megadásával, ami a Spring keretrendszer része. Így amikor a beérkező JSON

formátumú http kérésből objektumot generálna a controller, először leellenőrzi, hogy az

általam a model-ben megadott feltételek teljesülnek-e.

A submission csomag a cikkekhez tartozó osztályokat tartalmazza. A Submission osztály

jelképezi a cikket, annak korábban részletezett minden tulajdonságával együtt. A cikk

mindenkori állapotát egy State típusú adattag tárolja, amely típus a submission csomagban

szereplő enumeráció. A kulcsszavakat halmaz típusú kollekcióban tárolja, míg a társszerzőket,

valamint a hozzárendelt bírálókat User típusú listákban (List<User>). Itt található továbbá a

cikkhez elkészült bírálatok listája is, mely listának típusa a submission csomag Review

osztálya. A User osztálynál említett validációs technikát itt is használtam. A Review osztály a

bírálat minden tulajdonságát hivatott tárolni, köztük a User típusú bírálóval.

Itt található továbbá a History osztály, amely egy naplózandó eseményt valósít meg. Ebben

adattagként van jelen a Submission objektum, ami a bejegyzés tárgya. Ez a kapcsolat

megvalósítható lett volna úgy is, hogy a History az ER modellben nem egyedként, hanem a

Submission egyed többértékű, összetett tulajdonságaként jelenik meg és a model-ben a

Submission objektum adattagjaként kollekcióban. Azért döntöttem mégis ilyen megoldás

mellett, mert az előző esetben nem tudtam volna a naplózásért felelős funkciókat külön

adathozzáférési osztályba szervezni, ami viszont mind a kód átláthatósága, mind a különböző

funkcionalitás egymástól való elkülönítése miatt fontos volt. A 7. ábra egy osztálydiagram,

ami részletesen szemlélteti az egyes osztályokat és adattagjaikat.

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

27

7. ábra: POJO osztálydiagram

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

28

4.4 Adathozzáférési interfészek

Az interfészek megtervezése során az egyedek alapján választottam szét a funkciókat. Ennek

értelmében négy interfészt hoztam létre a dao modul interfaces csomagjába, ezek: a

fájlfeltöltési adatok elérését szolgáló ConfigDAO, a felhasználók adatainak kezelését végző

UserDAO, a cikkekkel kapcsolatos adatmozgatási funkciókat leíró SubmissionDAO és a

naplózást végző HistoryDAO.

A saját általános (implementációtól független) kivételeimet is itt hoztam létre az exceptions

csomag alatt. Ezek a következők: InsertException az adatbázisba való beszúráshoz,

UpdateException a módosítási műveletekhez, DeleteException a törlésekhez és

QueryException az adatok lekérdezéséhez. A cél beszédes nevű kivételek létrehozása volt,

amelyek utalnak rá, hogy mi volt a hiba oka, milyen művelet közben keletkezett. Ezek mind

egy közös ősosztályból származnak, ez pedig az általam létrehozott DataAccessException. A

metódusok definíció szerint ezt az ősosztályt dobják (throws DataAccessException;), a

service-impl modulban elegendő ezt elkapni. A 8. ábra ábrázolja a modul felépítését.

8. ábra: DAO modul szerkezete

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

29

4.4.1 ConfigDAO

A ConfigDAO interfész a fájlfeltöltéshez szükséges információk adatbázisból való

lekérdezéséért felelős, más funkciót nem lát el. Ezen információt a rendszer szerverre való

telepítése során kell manuálisan feltölteni az operációs rendszer függvényében. Egyetlen

metódusa van, ami egy feltöltött UploadConfig objektummal tér vissza:

public UploadConfig getUploadConfig() throws

DataAccessException;

4.4.2 UserDAO

A UserDAO interfész a felhasználók adatainak kezeléséért felelős funkciókat tartalmazza.

Rendelkezik az alapvető CRUD (Create, Read, Update, Delete) műveletekkel, valamint még

egyéb lekérdezésekkel is. Metódusai a következők:

public void reg(User user) throws DataAccessException;

Regisztráció során a megkapott User objektum adatait tölti fel az adatbázisba.

public void edit(User user) throws DataAccessException;

Módosítja egy felhasználó adatait az adatbázisban. A paraméterként kapott objektum

tartalmazza az új adatokat és hogy melyik felhasználót kell módosítani.

public void delete(String username) throws DataAccessException;

Felhasználó kizárása a rendszerből, enabled bináris tulajdonság 0-ra állítása.

public User getUser(String username) throws

DataAccessException;

Visszaadja egy felhasználó összes adatát. A paraméterben megadott felhasználónév alapján

kikeresi az adatbázisból a rekordot és visszaadja a feltöltött User objektumot.

public List<User> getAllUsers() throws DataAccessException;

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

30

Egy listában visszaadja az összes felhasználót minden adatukkal együtt.

public Set<Role> getAllRoles();

Visszaadja a Role enumeráció összes elemét egy halmazban a felületen való megjelenítéshez.

public Set<String> getAllACM_Areas() throws

DataAccessException;

Lekérdezi az összes ACM kategóriát az adatbázisból és visszaadja egy halmazban.

public List<User> getEditorsByAcm(String acm) throws

DataAccessException;

Egy paraméterként megkapott ACM kategória alapján visszaadja egy listában az összes

felhasználót, aki szakértője a témának és szerkesztő jogosultsággal rendelkezik.

public List<User> getReviewersByAcm(String acm) throws

DataAccessException;

Egy paraméterként megkapott ACM kategória alapján visszaadja egy listában az összes

bírálót, aki szakértője a témának.

public List<User> getEditors() throws DataAccessException;

Visszaadja az összes szerkesztői jogkörrel rendelkező felhasználót.

4.4.3 SubmissionDAO

A SubmissionDAO interfész a cikkekhez tartozó adatokat kezeli az alap CRUD műveletek

segítségével, valamint még számos lekérdezést is tartalmaz. Metódusai a következők:

public void add(Submission submission) throws

DataAccessException;

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

31

Cikk feltöltésekor a Submission objektum összes adata alapján beilleszt egy rekordot az

adatbázisba.

public void addReview(Submission submission) throws

DataAccessException;

Egy bírálat elkészülte után megkeresi a paraméter alapján a bíráló-cikk kapcsolatot és feltölti a

már létező rekordot a bírálat adataival.

public void edit(Submission submission) throws

DataAccessException;

Módosítja egy cikk adatait az adatbázisban.

public void setState(Submission submission) throws

DataAccessException;

Módosítja egy cikk állapotát a paraméter alapján.

public void delete(int id) throws DataAccessException;

Kitöröl egy cikket az adatbázisból, az összes rá mutató referenciával együtt (pl.: bírálatok).

public Submission getSubmission(int id) throws

DataAccessException;

A paraméterben megkapott azonosítóval rendelkező cikket adja vissza az adatbázisból.

public List<Submission> getSubmissionsByArea(String area)

throws DataAccessException;

A paraméterként megadott ACM tudományterülethez tartozó összes cikket visszaadja egy

listában.

public List<Submission> getSubmissionsByState(State state)

throws DataAccessException;

Visszaadja a bizonyos állapotú cikkek listáját a State típusú paraméter alapján.

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

32

public List<Submission> getSubmissions4Editor(String username)

throws DataAccessException;

Visszaad egy listát az összes cikkel, amely a paraméterként megkapott felhasználónevű

szerkesztőhöz van rendelve.

public List<Submission> getSubmissions4Reviewer(String

username) throws DataAccessException;

Visszaadja az egy bírálóhoz rendelt összes cikket a paraméter alapján egy listában.

public List<Submission> getSubmissions4Author(String username)

throws DataAccessException;

Visszaadja a paraméterként megkapott felhasználónév alapján az összes cikket, amit a

felhasználó töltött fel.

public Set<State> getAllStates() throws DataAccessException;

A felületen való megjelenítés céljából visszaadja a cikkállapotokat tároló enumeráció összes

elemét egy halmazban.

public void assignSubmission2Editor(Submission submission)

throws DataAccessException;

A paraméter objektum adatai alapján hozzárendel egy szerkesztőt egy cikkhez az

adatbázisban.

public void assignSubmission2Reviewers(Submission submission)

throws DataAccessException;

A Submission típusú paraméter reviewers adattagja alapján, ami egy Review típusú lista,

létrehozza az adatbázisban a megfelelő cikk-bíráló kapcsolatot jelölő rekordokat.

public void assignSubmission2Proofreader(Submission submission)

throws DataAccessException;

Hozzárendel egy nyelvi lektort a paraméterként megkapott cikkhez az adatbázisban.

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

33

public void assignSubmission2TecnicalEditor(Submission

submission) throws DataAccessException;

A paraméterként kapott cikkhez rendel hozzá egy nyomdai szerkesztőt az adatbázisban.

4.4.4 HistoryDAO

A HistoryDAO interfész a rendszer naplózási funkcióival kapcsolatos adathozzáférési

metódusokat tartalmazza. Ezek a következők:

public void add(History history) throws DataAccessException;

Hozzáad egy naplóbejegyzést az adatbázishoz.

public void deleteHistoryOfSubmission(int id) throws

DataAccessException;

Kitörli a paraméterként megkapott azonosítóval rendelkező cikkhez tartozó összes

naplóbejegyzést.

public List<History> getHistoryOfSubmission(int id) throws

DataAccessException;

Visszaadja a paraméterben megkapott azonosítóval jelölt cikkhez tartozó összes

naplóbejegyzést egy listában.

public List<History> getHistoryPeriod(Date startDate, Date

endDate) throws DataAccessException;

A két paraméter (kezdő dátum és befejező dátum) által meghatározott időintervallumban

keletkezett összes naplóbejegyzést adja vissza egy listában.

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

34

5. Implementáció

A tervezési folyamatok befejeztével és az adattárolási modell elkészültével megkezdődhetett

az implementáció. Először a létrehozott adatbázisról írok bemutatva a táblaszerkezeteket.

Majd részletezem, hogy miként valósítottam meg a megtervezett adathozzáférési interfészeket

a MyBatis használatával.

5.1 Az adatbázis

A 9. ábra szemlélteti az elkészült adatbázis tábláinak szerkezetét és azok kapcsolatát.

9. ábra: Adatbázis szerkezet

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

35

Látható, hogy az ER modellben ábrázolt többértékű tulajdonságokat külön táblákként kell

megvalósítani. Ezenkívül a bírálatokat jelző több-több kapcsolatot, mely saját

tulajdonságokkal is rendelkezik, ugyancsak külön táblában kell elhelyezni, ennek neve

kapcsolótábla. Ez tartalmazza az általa összekötött két egyedre mutató idegen kulcsot,

valamint az ide tartozó tulajdonságokat.

A cikkeket tároló tábla (submissions) elsődleges kulcsa az azonosító (id), ami a rekordok

adatbázisba való beszúrásánál generálódik:

id INT NOT NULL AUTO_INCREMENT,

Ekkor az első beszúrt rekordhoz tartozó azonosító értéke ’1’ lesz, a következőé ’2’ és így

tovább, automatikusan inkrementálódik.

Az egyes táblák alján lévő, mappa ikonnal ellátott rész az egyedi kulcsokat jelöli. Ezek olyan

értékek az adatbázisban, melyeknek párban kell egyedinek lenniük. Ilyen például a

felhasználók szakterületeit tároló tábla (user_areas):

CREATE TABLE user_areas (

username VARCHAR(100) NOT NULL,

area VARCHAR(50) NOT NULL,

UNIQUE KEY `user_area` (`username`,`area`),

FOREIGN KEY (username) REFERENCES users (username));

A táblában lehet több azonos felhasználónév is, mivel több területet is kapcsolhatunk egyhez.

Ugyanígy több azonos szakterület is lehet, mert más felhasználónak is lehet ugyanaz a

szakterülete. Mégis biztosítani kell, hogy ne kerülhessen be egy felhasználó szakterülete

kétszer is a táblába. Erre szolgál az egyedi kulcs (UNIQUE KEY), amely biztosítja, hogy egy

felhasználónév-szakterület kombinációt csak egyszer vehessünk fel a táblába. Ugyanezen

okok miatt hasonlóan épül fel a szerepköröket (user_roles), társszerzőket

(submission_co_authors) és a kulcsszavakat (submission_keywords) tároló tábla.

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

36

5.2 Az adathozzáférési osztályok

5.2.1 Modul felépítése

A dao-mysql modul tartalmazza a dao interfészeinek implementáló osztályait, a MyBatis

használatához szükséges mapper interfészeket és XML fájlokat, valamint az adatbázist és a

táblákat létrehozó SQL szkripteket. Ezt reprezentálja a 10. ábra.

10. ábra: DAO-MySQL modul szerkezete

A create_database szkript létrehozza az adatbázist, a create_tables elkészíti az összes táblát,

az insert_admin_data beszúrja az admin jogosultságú felhasználót, valamint egyet-egyet a

különböző szerepkörű felhasználók közül, a fájlfeltöltési adatokat és az ACM kategórialista

elemeit. A test mappában található többi szkript a teszteléshez szükséges adatbázis

műveleteket végzik el.

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

37

5.2.2 MyBatis konfiguráció

A MyBatis konfigurálásához a Spring keretrendszerben létre kell hoznunk a szükséges bean-

eket az alkalmazás kontextusban. Ez azt jelenti, hogy a Spring konténer képes lesz megfelelő

időben a megfelelő helyen használni ezeket az objektumokat. Ennek a megoldása

többféleképpen is lehetséges. Én a lehető legtöbb objektumot bean-ként hoztam létre a Spring

kontextusát leíró XML fájlban és csak magát a mapper-t hozom létre a DAO implementációs

osztályokban, amit a Spring fog beinjektálni.

Először is egy DataSource objektumot kell létrehozni, amely az adatbázis elérésehez

szükséges információkat tartalmazza:

<bean id="dataSource"

class="org.apache.commons.dbcp.BasicDataSource">

<property name="driverClassName"

value="com.mysql.jdbc.Driver" />

<property name="url"

value="jdbc:mysql://localhost:3306/dbtest" />

<property name="username" value="root" />

<property name="password" value="" />

</bean>

Ezt követően egy SqlSessionFactory objektum létrehozása következik, amely SqlSession

objektumokat biztosít vagy közvetlenül az implementáció osztálynak, vagy ahogy én

csináltam, a mapper objektumoknak. Az SqlSession biztosítja az adatbázis kapcsolódást

(Connection) és akár közvetlenül is végrehajthatunk SQL utasításokat általa:

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

<property name="dataSource" ref="dataSource" />

</bean>

Át kell adni neki a DataSource objektumot az adatbázishoz való kapcsolódáshoz.

Ezután létrehoztam a mappereket, mint bean-eket, átadva nekik az SqlSessionFactory

objektumot:

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

38

<bean id="userMapper"

class="org.mybatis.spring.mapper.MapperFactoryBean">

<property name="mapperInterface"

value="hu.uni.miskolc.iit.manuscript.dao.mysql.mappers.UserMapp

er" />

<property name="sqlSessionFactory" ref="sqlSessionFactory"

/>

</bean>

Ennek mintájára készítettem el a négy DAO osztályhoz tartozó négy mappert. Itt meg kell

adni tulajdonságként (mapperInterface) annak az interfésznek a teljes elérési nevét, amelyik

megvalósítja majd.

5.2.3 MyBatis implementáció

A mapper interfészek tartalmazzák azokat a metódusokat, amelyeket a DAO implementációs

osztályokból hívhatunk és egy-egy SQL utasítást reprezentálnak. Az XML fájlokban

találhatóak maguk az SQL utasítások. Ahhoz, hogy ez a két komponens megtalálja egymást,

azonos mappában kell elhelyezni őket, valamint az XML fájlok névterének a hozzájuk tartozó

interfészeket kell megadnunk a teljes elérési nevükkel. Ezenkívül fontos, hogy a nevüknek is

meg kell egyezniük. A továbbiakban bemutatok egy-egy példát minden utasítástípusból.

A felhasználók beszúrásakor használt metódus a következőképpen épül fel:

public void reg(User user) throws DataAccessException {

try {

userMapper.insertUser(user);

userMapper.insertUserRoles(user);

userMapper.insertUserAreas(user);

} catch (PersistenceException e) {

throw new InsertException("MyBatis Error occured

while performing an insert method: " + e.getMessage(), e);

} catch (Exception e) {

throw new InsertException("Other error occured while

performing an insert method: " + e.getMessage(), e);

}

}

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

39

Először magát a felhasználót szúrom be az idegen kulcsok miatt, majd a szerepköreit, végül a

szakterületeit a megfelelő táblákba. A mapper műveleteknél keletkező kivételek szinte mindig

a MyBatis kivételbe csomagolódnak be (PersistenceException). Ezt, valamint minden más

kivételt is elkap a metódus, majd ezeket becsomagolja a saját beszúrási kivételembe

(InsertException). A mapper XML fájlban ennek egy részlete így néz ki:

<insert id="insertUser"

parameterType="hu.uni.miskolc.iit.manuscript.model.user.User">

INSERT INTO users(username, password, firstname,

middlename, lastname, title, home_address, street, city,

postal_code, country, state, organization, phone, fax, email)

VALUES(#{userName}, #{password}, #{firstName},

#{middleName}, #{lastName}, #{title}, #{homeAddress},

#{street}, #{city}, #{postalCode}, #{country}, #{state},

#{organization}, #{phone}, #{fax}, #{email})

</insert>

<insert id="insertUserRoles"

parameterType="hu.uni.miskolc.iit.manuscript.model.user.User">

INSERT INTO user_roles(username, ROLE) VALUES

<foreach item="role" collection="roles" index="index"

open="(" separator="),(" close=")">

#{userName}, #{role}

</foreach>

</insert>

Látható, hogy a #{} szintaktikával lehet a paraméterként megkapott objektum adattagjaira

hivatkozni. A típuskonverzió, ha lehetséges, automatikusan végbemegy. Egyfajta típusú

paramétert adhatunk csak meg a parameterType tulajdonság segítségével. Ilyenkor, ha több

azonos típusú paramétert adunk át, akkor a #{} közötti megfelelő nevekkel hivatkozhatunk

rájuk. Erre a későbbiekben mutatok példát.

A szerepkör beillesztésnél is egy User objektumot adunk át, azon belül viszont általában több

szerep is található a kollekcióban. Itt lehet használni a foreach tag-et, ami a kollekció összes

elemére végrehajtja az SQL utasítást.

A következő bemutatott metódus a felhasználók módosítása lesz:

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

40

public void edit(User user) throws DataAccessException {

try {

userMapper.updateUser(user);

userMapper.deleteUserRoles(user.getUserName());

userMapper.deleteUserAreas(user.getUserName());

if (user.getRoles() != null) {

userMapper.insertUserRoles(user);

}

if (user.getAcmAreas() != null) {

userMapper.insertUserAreas(user);

}

} catch (PersistenceException e) {

throw new UpdateException("MyBatis Error occured

while performing an update method: " + e.getMessage(), e);

} catch (Exception e) {

throw new UpdateException("Other error occured while

performing an update method: " + e.getMessage(), e);

}

}

Mivel a többértékű tulajdonságokat tároló táblák a rendszerünkben csak néhány bejegyzést

tartalmaznak egy egyedre nézve, ezért a módosítás legegyszerűbb módja, ha a módosítási

műveletnél kitörlünk minden hozzá tartozó bejegyzést a melléktáblából, majd hozzáadjuk a

paraméterben találhatókat. Itt is hasonló a kivételkezelés, azzal a különbséggel, hogy az itt

keletkező kivételek a saját módosítási kivételembe fognak becsomagolódni

(UpdateException). Az XML fájl hozzátartozó része:

<update id="updateUser"

parameterType="hu.uni.miskolc.iit.manuscript.model.user.User">

UPDATE users SET password = #{password}, firstname =

#{firstName}, middlename = #{middleName}, lastname =

#{lastName}, title = #{title}, home_address = #{homeAddress},

street = #{street}, city = #{city}, postal_code =

#{postalCode}, country = #{country}, state = #{state},

organization = #{organization}, phone = #{phone}, fax = #{fax},

email = #{email} WHERE username = #{userName}

</update>

A törlési művelet esetében a cikk törlését mutatom be:

public void delete(int id) throws DataAccessException {

try {

submissionMapper.deleteSubmissionKeywords(id);

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

41

submissionMapper.deleteSubmissionCoAuthors(id);

submissionMapper.deleteSubmissionReviews(id);

submissionMapper.deleteSubmission(id);

} catch (PersistenceException e) {

throw new DeleteException("MyBatis Error occured

while performing a delete method: " + e.getMessage(), e);

} catch (Exception e) {

throw new DeleteException("Other error occured while

performing a delete method: " + e.getMessage(), e);

}

}

Itt fontos, hogy a törléseket hivatkozási sorrendben kell elvégezni, ugyanis egy rekord addig

nem törölhető, amíg egy másik rekord idegen kulcsa az elsődleges kulcsára mutat.

Paraméterként itt már elég csak az azonosítót megkapnunk. Az itt keletkező kivételeket a saját

törlési kivételembe csomagolom (DeleteException). Az XML fájl ide vonatkozó része:

<delete id="deleteSubmission" parameterType="int">

DELETE FROM submissions WHERE id = #{id}

</delete>

Egyszerű paramétertípusnál mindegy, hogy milyen szöveget adunk meg a #{} rész között,

amennyiben csak egy paramétert adunk át, a MyBatis tudni fogja, hogy azt kell oda beszúrnia.

Lekérdezési műveletekből kettőt mutatok be. Az első a cikk lekérdezése állapot alapján:

public List<Submission> getSubmissionsByState(State state)

throws DataAccessException {

List<Submission> result = new ArrayList<Submission>();

try {

result =

submissionMapper.getSubmissionsByState(state);

} catch (PersistenceException e) {

throw new QueryException("MyBatis Error occured while

performing a query method: " + e.getMessage(), e);

} catch (Exception e) {

throw new QueryException("Other error occured while

performing a query method: " + e.getMessage(), e);

}

return result;

}

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

42

Itt minden kivételt a saját lekérdezési kivételembe csomagolok be (QueryException). Az XML

fájl megfelelő része:

<select id="getSubmissionsByState" parameterType="String"

resultMap="SubmissionResultMap">

SELECT id, title, abstract, submission_area, state,

corresponding_author, co_author, assigned_editor, file_path,

uploadDate, reviewer, verdict, message, details,

secret_message, review_date

FROM submissions

LEFT OUTER JOIN submission_reviews ON id =

submission_reviews.submission_id

LEFT OUTER JOIN submission_co_authors ON id =

submission_co_authors.submission_id

WHERE state = #{state}

</select>

A cikket tároló táblát a melléktáblákkal a LEFT OUTER JOIN SQL művelettel kapcsoltam

össze. Ez azt jelenti, hogy az első táblából minden feltételnek megfelelő rekord szerepel majd

az eredményhalmazban, de a másodikból csak azok, amelyek egyeznek egy rekorddal az első

táblából a kapcsolódási feltétel alapján. Itt már a visszatérési érték típusát is meg kell adni,

hogy a MyBatis le tudja képezni a visszakapott adatokat a megfelelő típusokká. Itt nem kell

kollekciót megadni, elég az alaptípust, a MyBatis a rekordhalmazt automatikusan leképzi a

kívánt kollekcióvá. Ezt a resultType tulajdonsággal tehetjük meg, vagy mint a példában is,

összetett típusoknál a resultMap tulajdonságot kell használnunk. Ekkor meg kell adnunk a

leképezés módját resultMap tag-ek között:

<resultMap

type="hu.uni.miskolc.iit.manuscript.model.submission.Submission

" id="SubmissionResultMap">

<result property="id" column="id" />

<result property="title" column="title" />

<result property="abstractOfSubmission" column="abstract"

/>

<result property="acmArea" column="submission_area" />

<result property="state" column="state" />

<result property="correspondingAuthor.userName"

column="corresponding_author" />

<result property="assignedEditor.userName"

column="assigned_editor" />

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

43

<result property="assignedProofreader.userName"

column="assigned_proofreader" />

<result property="assignedTechnicalEditor.userName"

column="assigned_technical_editor" />

<result property="filePath" column="file_path" />

<result property="date" column="uploadDate" />

<collection property="assignedReviewers"

ofType="hu.uni.miskolc.iit.manuscript.model.user.User">

<result property="userName" column="reviewer" />

</collection>

<collection property="reviews"

ofType="hu.uni.miskolc.iit.manuscript.model.submission.Rev

iew">

<result property="reviewer.userName"

column="reviewer" />

<result property="verdict" column="verdict" />

<result property="message" column="message" />

<result property="details" column="details" />

<result property="secretMessage"

column="secret_message" />

<result property="date" column="review_date" />

</collection>

<collection property="coAuthors" ofType="String">

<result column="co_author" />

</collection>

</resultMap>

A type tulajdonság adja meg, hogy milyen összetett típussá akarjuk leképezni a rekordokat. A

result tag-ekkel megadhatjuk, hogy az egyes mezők mely adattagnak felelnek meg az

osztályban. Ez különösen fontos, ha a mező és az adattag neve eltér, egyébként a MyBatis

automatikusan megtalálja. A collection tag segítségével bonyolultabb lekérdezéseket is végre

lehet hajtani, itt beállíthatjuk, hogy a visszakapott adatok miképp szerveződjenek egy

kollekció típusú adattagon belül.

Az utolsó művelet, amit bemutatok, az a naplóbejegyzések időintervallum alapján történő

lekérdezése:

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

44

<select id="getHistoriesByPeriod" parameterType="java.sql.Date"

resultMap="historyResultMap">

SELECT * FROM histories WHERE history_date BETWEEN

#{start} and #{end}

ORDER BY history_date ASC

</select>

Itt a két megadott dátum paramétert a #{} közötti név alapján találja meg a MyBatis, majd

dátum alapján növekvő sorrendbe rendezi a rekordokat.

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

45

6. Tesztelés

Az alkalmazás tesztelése több tekintetben is rendkívül fontos lépés. Így tudjuk a

legegyszerűbben ellenőrizni azt, hogy a funkciók végrehajtják-e az elvárt működést. Ezenkívül

ha már készen vannak a tesztek és módosítunk valamit a tesztelt kódban, rögtön

ellenőrizhetjük, hogy a változtatásunk megzavarta-e a funkció működését.

A dao-mysql modul felépítését a tesztek szempontjából a 11. ábra mutatja be:

11. ábra: DAO-MySQL modul szerkezete (tesztelés)

A tesztosztályok mind egy közös ősből származnak (InitTest), ami a tesztek lefutása előtt és

után végrehajtandó műveleteket tartalmazza. Ezek a műveletek az adatbázist hozzák létre és

semmisítik meg úgy, hogy a MyBatis-hoz tartozó szkript futtató osztály (ScriptRunner)

segítségével futtatják az SQL szkripteket. Ezenkívül minden egyes teszt metódus előtt feltöltik

a teszt adatokkal az adatbázist, amelyeket utána ki is törölnek:

@BeforeClass

public static void setUpDatabase() {

runScript(CREATE_TABLES_SQL);

}

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

46

@AfterClass

public static void deleteDatabase() {

runScript(DROP_TABLES_SQL);

}

@Before

public void insertTestData() {

runScript(INSERT_TEST_DATA);

}

@After

public void deleteTestData() {

runScript(DELETE_TEST_DATA);

}

Minden teszt osztály tartalmaz még egy @Before annotációval ellátott metódust, melynek

feladata az adott osztályhoz tartozó DAO inicializálása. Mivel itt nem használható a Spring,

hogy biztosítsa a megfelelő mapper-t, ezért van szükség a 11. ábrán látható dao-config.xml

konfigurációs fájlra. Ugyancsak tartalmaznak egy @After jelölésű metódust, mely az

SqlSession osztály által reprezentált adatbázis-kezelő munkamenetet zárja le minden

tesztfüggvény után. Erre azért van szükség, mert a szkript futtató osztály és a DAO más

munkamenetet használ, és egyébként kizárnák egymást az adatbázisból.

Példaként bemutatom az egyik, felhasználókhoz kötődő lekérdezés tesztesetét:

@Test

public void TestGetEditorsByAcm() {

List<User> userQuery = new ArrayList<User>();

List<User> userFalseQuery = new ArrayList<User>();

try {

userQuery =

userDAO.getEditorsByAcm("INFORMATION_SYSTEMS");

userFalseQuery = userDAO.getEditorsByAcm("HARDWARE");

} catch (DataAccessException e) {

Assume.assumeNoException(e);

}

Assert.assertTrue(userQuery.size() == 1);

Assert.assertTrue(userFalseQuery.isEmpty());

}

A kód lefedettség (code coverage) azt jelenti, hogy a tesztek futása során a tesztelt kód hány

százaléka hívódik meg. A lefedettséget az Emma Code Coverage plugin segítségével

vizsgáltam, és a 12. ábra mutatja, hogy milyen eredményt értem el:

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

47

12. ábra: Kód lefedettség

60 tesztesetet hoztam létre és mindegyik sikeresen lefut. A tesztek létrehozásakor sok,

korábban nem látott hiba kiderült, amiket aztán ki tudtam javítani.

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

48

7. Összegzés

A szakdolgozatom témáját képző, általam elvállalt projektfeladat célja az volt, hogy tervezzem

meg és hozzam létre az adattárolási modellt, valamint az adathozzáférési réteget egy

elektronikus kézirat feltöltő rendszerhez. Véleményem szerint ezt sikerült teljesíteni,

elkészültek a szükséges elemek, s mivel ez egy általános alkalmazás, ezért számos

testreszabási és kibővítési pontot tartalmaz, ami a jövőre nézve is kínál lehetőségeket. A

csoportmunkában elkészült alkalmazást fel lehet használni a Miskolci Egyetem PSAIE

tudományos folyóiratához, vagy akár más intézményeknek is lehet továbbítani hasonló

célokra.

A szakdolgozat készítése során kipróbálhattam magam egy komolyabb projektmunkában,

kiderült, hogy mennyire sikerül alkalmaznom az egyetemen megszerzett tudást, valamint hogy

el tudok-e sajátítani nem oktatott technológiákat is. Úgy gondolom, hogy ezt is teljes

mértékben megvalósítottam, képes voltam hasznosítani az egyetemi tananyagot elsősorban az

’Objektum orientált programozás’, a ’WEB-es alkalmazások’, az ’Adatbázis rendszerek’, a

’Szoftvertechnológia’ és a ’Szoftver projektek és tesztelés’ tantárgyakból. Emellett sikerült

elsajátítanom az általam korábban nem ismert MyBatis technológiát is, és hasznos

tapasztalatokkal gazdagodtam a csoportmunkában történő szoftverfejlesztés kapcsán.

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

49

8. Summary

The aim of the project, which was documented in my thesis, was to develop and implement

the data structure and the data access layer of a manuscript handler system. In my opinion, I

managed to achieve this, the needed components were completed. Furthermore, because it is a

white-labeled product, the system contains many customization and extension points, thus

providing future possibilities. The application, which was developed in teamwork, can be

utilized for the PSAIE journal of the University of Miskolc, or it can be forwarded to other

institutes for similar purposes.

During the creation of my thesis I could try myself out in a major project work and find out

how much I can use the knowledge gained in the university, and if I can manage to learn new

technologies not taught in the university. I think that I have entirely accomplished this as well,

since I was able to utilize the curriculum of many subjects taught in the university. These

subjects are ’Object Oriented Programming’, ’WEB Based Applications’, ’Database Systems’,

’Software Technology’, and ’Software Projects and Testing’. In addition, I managed to learn

and use the MyBatis technology, which was completely new for me and I also gained useful

experiences regarding software development in teamwork.

Az adattárolási modell és a modell osztályok kidolgozása elektronikus kézirat feltöltő rendszerhez

________________________________________

50

9. Irodalomjegyzék

- [1] http://docs.spring.io/spring-framework/docs/current/spring-framework-

reference/html/mvc.html

- [2] Ben Collins-Sussman, Brian W. Fitzpatrick, C. Michael Pilato: Version Control

with Subversion, For Subversion 1.7

- [3] https://maven.apache.org/index.html

- [4] https://mybatis.github.io/mybatis-3/

Linkek utoljára ellenőrizve: 2015-11-20