Adatbázis-kezelés Delphi segítségével

A Borland Delhi fejlesztőeszközzel nagyon gyorsan és hatékonyan tudunk adatbázis-kezelő alkalmazásokat fejleszteni. A Delphi kiemelkedően támogatja az adatok kezelését, és mivel RAD eszközről van szó, nagyon gyorsan fejleszthetjük ki az alkalmazás párbeszédpaneleit is.  Ebben a cikksorozatban megpróbálom bemutatni, hogy hogyan tudjuk a feladatainkat ennek a remek fejlesztőrendszernek a segítségével megoldani. Az első néhány cikk az alapokról szól majd, majd utána érdekesebb témák fel vesszük az irányt.

A cikk nyelvezeténél feltételezem, hogy a Tisztelt Olvasó már rendelkezik Delphi és adatbázis-kezelés alapismeretekkel. Ha nem így lenne, kérem, hogy a cikk elolvasása előtt tanulmányozza át a Delphi alapokról szóló cikket. A cikkben található feladatok mindegyike lokális adatbázisok kezelésére lesz alkalmas, a szerver-kliens architektúrájú adatbázis-kezelés egy másik cikksorozat témája lehet.

A Delphi az alábbi adatbázis típusokkal képes közvetlenül együttműködni a beépített, ún. natív meghajtóinak a segítségével:

·         dBase, Foxpro, amelyek az adatokat egy *.dbf kiterjesztésű állományban tárolják;

·         Paradox, amelynek állománykiterjesztése *.db;

·         Microsoft Access típusú, *.mdb kiterjesztésű adatbázisokkal;

természetesen lehetőség van adatbázis-kezelő rendszerek elérésére is, az alábbi listában láthatjuk azokat a rendszereket, amelyek adataihoz közvetlenül hozzáférhetünk Delphi alól:

·         IBM DB2 adatbázis szerver;

·         Borland InterBase szerver;

·         Microsoft SQL szerver;

·         Oracle SQL szerver;

·         SYBASE szerver;

·         Informix;

Mint minden feladathoz, a Delphiben ehhez is megfelelő komponensek állnak a rendelkezésünkre, amelyek segítségével a programfejlesztő környezet nagyon sok feladatot levesz a vállunkról. A fenti listában látható, hogy milyen sokféle típussal képes a Delphi együtt dolgozni. A munka elősegítése érdekében minden adatbázis-típushoz külön komponensekre lenne szükség, mert ezek kezelése eltérő lehet. Ennek kiküszöbölése érdekében a Borland programozói úgy gondolták, hogy elkészítenek az adatbázisok és a Delphiben készített alkalmazásaink közé egy szoftver-réteget, amelynek a feladata a különböző típusú adatbázisok kezelése oly módon, hogy az alkalmazás felé egységes felület látszódjon. Ezt a szoftver-réteget adatbázis-kezelő motornak nevezzük és a Delphivel együtt szállított BDE (Borland Database Engine, Borland adatbázis-kezelő motor) valósítja meg. A BDE minden olyan rutint tartalmaz, amelyek képesek a fizikai adatbázisok kezelésére, az alkalmazásunk a kapcsolatot a BDE-vel tartja csupán.

A fenti adatbázisokon kívül lehetőség van ODBC-n keresztüli adatbázis elérésre is minden olyan típusból, amelyhez rendelkezésre áll ODBC meghajtó. Ez a Microsoft által bevezetett rutincsomag, amely egységes felületet biztosít a különböző formátumú adatbázisok kezeléséhez. Ebből a szempontból a funkciója azonos a BDE-vel, viszont míg a BDE a Delhivel van szoros integráltságban, addig az ODBC a Windows-zal. Számos ODBC meghajtó hozzáférhető az adatbázis-gyártók jóvoltából, amelyek segítségével gyakorlatilag külön rutinkönyvtár felhasználása nélkül használhatjuk az erőforrásokat, nem kell nekünk elkészíteni a meghajtókat. Amennyiben nincs a BDE-ben natív meghajtó a használni kívánt adatbázishoz, akkor szükséges az ODBC meghajtó. Így az alkalmazás a BDE-vel tartja a kapcsolatot egy szabványos felületen keresztül. A BDE kapcsolódik az ODBC meghajtóhoz, amely a beépített rutinjai segítségével megoldja a fizikai adatbázis-kezelést. Elsőre talán bonyolultnak tűnhet, de a megoldás rendkívül rugalmas. Nekünk semmi másra nincs szükségünk, mint annak a néhány komponensnek a megismerésére, amely megvalósítja a kapcsolatot a BDE-vel. Minden további feladatot levesz a fejlesztőkörnyezet a vállunkról. A megoldásnak van egy hátránya, miszerint az alkalmazásunkkal együtt az adatbázis-motort is át kell vinnünk a futtató gépre. Mivel a BDE-t telepíteni kell, ezért a legegyszerűbb módszer, ha készítünk az alkalmazásunkhoz egy telepítő készletet, amelyhez felhasználhatjuk az InstallShield Express nevű programot, amely szintén elérhető a CD-ről. Ennek használatáról is lesz szó a későbbiekben.

A Delphi adatbázis-kezelő felépítését mutatja az alábbi ábra:

Álnevek használata

Az adatbázisok kezelését rábízni egy, az alkalmazástól független motorra, láthattuk, hogy előnyös lépés. Ennek a használata viszont megköveteli, hogy a BDE tisztában legyen az adatbázisok helyével és formátumával. Az általános megoldás, hogy a programunkba belefordítjuk ezeket az információkat. Ez mindaddig működni is fog, amíg nem azt egy másik könyvtárba, vagy egy másik meghajtóra. Ezt is meg lehet oldani, mert a forráskódban kijavítjuk a hivatkozást és újra lefordítjuk a programot. Ez a megoldás két szempontból sem megfelelő. Egyrészt oda kell adnunk a programunkkal együtt a forráskódot, aminek a hátrányait, gondolom, nem kell senki számára ecsetelnem. A másik hátulütője a dolognak, hogy a fordításhoz a gépen telepített Delphinek is lennie kell, ami az esetek nagy részében nem kivitelezhető.

A probléma rugalmas megoldásának érdekében a Borland programozói felkészítették a BDE-t az álnevek (Alias) kezelésére. Az álnév tulajdonképpen egy hivatkozás a fizikai adattáblára, tartalmazza annak helyét és típusát egyaránt. Az álnevek a programtól függetlenek, az adatbázis-kezelő motorhoz tartozik és annak konfigurációs állománya tartalmazza (IDAPI32.CFG). Az alkalmazásunkban az adatbázisok elérési útvonala helyett csak az álnevet használjuk és így fordítjuk le. Amikor a programot telepítjük, akkor csak az álnevet kell beállítani a korrekt elérhetőségnek megfelelően, miután a programunk változatlanul képes lesz a működésre.

Az álnevek ettől sokkal többre alkalmasak, de ezekre ebben a cikksorozatban nem lesz szükségünk.

Az adatbázisok kezeléséhez a Delphivel együtt különböző segédeszközöket is kapunk, amelyekkel a különböző adatbázis műveleteket is elvégezhetjük. Nézzük meg röviden, hogy milyen programokat is használhatunk a fejlesztőkörnyezetünkben:

·         BDE Administrator az adatbázis-kezelő motor beállító programja. Ennek használata akár egy egész cikket is megtöltene. Segítségével beállíthatjuk az álneveket, az adatbázis meghajtókat és egyéb más rendszerparamétert, amely a BDE működéséhez szükséges.

·         Borland Database Desktop nevű program a helyi adatbázisok, adattáblák kezelésére szolgál, így számunkra elsősorban ez lesz az egyik leggyakrabban használt program. Az álneveket természetesen ennek segítségével is menedzselhetjük, de ezen a funkción kívül segítségével létrehozhatunk adattáblákat, módosíthatjuk szerkezetüket, belepillanthatunk a tartalmukba, de akár módosíthatjuk is az adatokat. Ezen kívül táblák közötti műveleteket is végezhetünk, hogy az indexek kezeléséről már ne is beszéljünk.

·         Borland Database Explorer egy olyan segédprogram, amely alkalmas az álnevek kezelése mellett az adatbázisok, adattáblák szerkezetének és tartalmának megtekintésére és módosítására. Ezen kívül lehetőséget nyújt SQL lekérdezések futtatására is. 

A fenti programok a legegyszerűbb Delphi kiadásban is megtalálhatók. A Professional változattól kezdődően az adatbázis-kezeléssel kapcsolatos lehetőségek és programok is megszaporodnak, de nekünk ezekre nem lesz szükségünk.

Most, hogy már ismerjük az alapokat és megismerkedtünk azokkal a programokkal, amelyeket segítségül hívhatunk a mindennapi munkánkhoz, neki is kezdhetnénk a konkrét programozással foglalkozni. Igen ám, de milyen adatokkal fogunk dolgozni? Minden adatbázis-kezelési feladatot meg kell előzni egy tervezési fázisnak, mivel az adatszerkezeten múlik egy alkalmazás hatékonysága. Ez a feladat nem ennek a cikknek a témája, de ebben a számban a Adatbázis normalizálás elnevezésű cikkben megismerkedhetnek ezzel a komoly tudást igénylő munkával.

Annak érdekében, hogy a Delphiben történő adatbázis-kezelést megvalósító programozás elsajátítását megkönnyítsék, a Borland programozói mellékeltek mintaadatbázisokat is. A mostani cikkünkben mi is ezt fogjuk használni, de megnyugtatok mindenkit, a következő hónaptól már mi magunk fogjuk az adatbázisainkat elkészíteni.

Adatbázis-kezelés Delphiben

Már láttuk, hogy mennyire rugalmas eszköz a Delphi ennek a feladatnak az ellátására. A feladataink megoldásában előre elkészített komponensek állnak a rendelkezésünkre. Annak érdekében, hogy ténylegesen különválasszák az adatkezelést az adatmegjelenítéstől, az adatkezelő komponensek két nagy, az adatelérési- és az adatmegjelenítési csoportba sorolhatók, fizikailag is külön komponenspalettán találhatók.

Adatelérési (Data Access) komponensek

Adatelérési (Data Access) komponensek az adattáblák elérését teszik lehetővé. Tulajdonképpen a BDE megfelelő moduljaival ezek tartják a kapcsolatot. A Delphi változatástól függ, hogy itt milyen elemeket láthatunk, a Standard változatban az alábbi palettával találhatjuk szemben magunkat:

Nézzük meg, hogy mire is szolgálnak az itt látható, előre elkészített komponensek, amelyek többsége nem vizuális komponens, vagyis csak tervezési időben látszanak.

 

Az adatbázisok eléréséhez szükségünk van egy DataSource komponensre, amely erre szolgál. Fontos, hogy ez nem közvetlenül kapcsolódik a fizikai táblához, mivel ennek bemenete lehet akár egy tábla, akár egy lekérdezés eredménye, de akár tárolt eljárások is szolgáltathatják a bemenetét. Az adatmegjelenítési komponensek ettől kapják az adatokat. Ez a megoldás rendkívül rugalmas és hatékony eszközt ad a kezünkbe, mert így az adatok és a megjelenítési komponensek függetlenné válhatnak egymástól. Például amikor egy táblából lekérdezéseket kell megjeleníteni a képernyőn attól függően, hogy a felhasználó mit választ ki. Borzasztó hosszadalmas lenne minden megjelenítési komponensnek megváltoztatni az adatforrását, ehelyett inkább a DataSource komponenst irányítjuk át egy másik lekérdezésre és máris a helyes eredményt látjuk. A gyakorlatban a későbbiekben ki is fogjuk használni ezt a tulajdonságot.

A Table komponens egy relációs táblával tartja a kapcsolatot a BDE-n keresztül. A paramétereit rendszerint tervezési időben határozzuk meg, néhány tulajdonságának kivételével, de erről a későbbiekben még bővebben lesz szó.

A Query komponenssel a relációs táblákból kérdezhetünk le rekordokat az SQL nyelv használatával. Szintén tervezési időben állítjuk be a legtöbb tulajdonságát, de az SQL utasításokat az esetek döntő részében csak futási időben adjuk át.

A StoredProc szerver-kliens adatbázis-szerkezetnél használatos, amikor a kliens az adatbázis-szerveren eljárásokat szeretne tárolni, illetve azokhoz hozzáférni. Mi nem fogunk ilyen alkalmazást fejleszteni, éppen ezért nincs is erre szükségünk.

A Database komponens rendszerint szerver-kliens architektúráknál használatos, lehetővé teszi a kapcsolatok ellenőrzését, különböző biztonsági műveletek elvégzését csakúgy, mint a kapcsolat-ellenőrzést. Mivel ilyen alkalmazást ennek a cikksorozatnak a keretében nem, készítünk, így ezt a komponenst sem fogjuk használni.

A Session komponens legfontosabb tulajdonsága, hogy egy eseményt biztosít az adatbázisokban történő bejelentkezések testre szabásához. Mi nem fogjuk használni.

A BatchMove segítségével, mint ahogy a nevéből is látszik, kötegelt műveletek végrehajtásra nyílik lehetőségünk. Ilyen művelet lehet akár másolás, akár mozgatás, vagy törlés is. Szintén nem kerül majd az általunk készített alkalmazásokban felhasználásra.

Az UpdateSQL segítségével adatfrissítő műveleteket végezhetünk SQL lekérdezések segítségével egy csak olvasható Query komponensen. Rendszerint a táblák és a lekérdezések UpdateObject értékeként használjuk. A mi esetünkben nem lesz rá szükség.

Amint az a kis összefoglalóból is kiderült számunka a Table, a Query és a DataSource komponens fontos, mivel erre fog épülni minden adatbázis-kezelő alkalmazásunk.

Adatmegjelenítési komponensek

Az adatok párbeszédpanelen (FORM) megjelenítésére számos komponens áll rendelkezésünkre, amelyek rengeteg előnyös tulajdonsággal rendelkeznek. Ha ezek nem lennének megfelelő, az interneten számtalan komponenshez férhetünk hozzá, amelyek egy része ingyenes, míg másokat meg kell vásárolnunk.

Amikor megnyitjuk a Delphi Standard Data Controls (adat vezérlő) palettáját, akkor ehhez hasonló választékkal találjuk szemben magunkat:

Nézzük meg, hogy melyik mire szolgál, erről a palettáról szinte mindegyik elemet fel fogjuk a későbbiekben használni, ezért szeretném bemutatni ezeket.

A DBGrid egy táblázatot jelenít meg a panelen, amelyen a táblákból származó adatokat láthatjuk. A táblázat automatikusan annyi oszlopot tartalmaz, amennyi mezője van a relációnak, de ezt felül is bírálhatjuk. Áttekintő listák készítéséhez nagyon jól használható.

A rekordokműveleteket segíti elő a DBNavigator. Segítségével a rekordmutató léptetésén túl, felvehetünk új rekordot, törölhetjük az aktuális sort, vagy akár szerkeszthetjük is azt. A gombok tetszőlegesen ki és bekapcsolhatók, annak megfelelően, hogy melyikre van szükségünk.

Abban az esetben, ha egy statikus, vagyis a formon nem módosítható szöveget kell megjeleníteni egy relációs táblából, akkor használjuk a DBLabel komponenst. Az éppen aktuális rekord hozzárendelt mezőjének az értékét jeleníti meg.

Az egyik leggyakrabban használt vezérlőelem a beviteli mező adatbázisokhoz illesztett változata, a DBEdit. Nem csak a mező értékét képes megjeleníteni, hanem módosíthatjuk is az, emennyiben engedélyeztük ezt az adatbázis műveletet.

Számos esetben előfordulhat, hogy nem elegendő egy soros beviteli mező, ilyen esetekben használhatjuk a DBMemo komponenst, amely a DBEdit többsoros változata.

Ha képet szeretnénk megjeleníteni a párbeszédpanelünkön, akkor erre a DBImage komponenst felhasználva nagyon egyszerűen lehetőséget kapunk. A képek megjelenítésénél még azt is meghatározhatjuk, hogy a nagy (vagy éppen kicsi) képekkel mi történjen, megnyújthatjuk, kicsinyíthetjük, vagy éppen levághatjuk a kilógó részeket.

A DBListBox egy listaelem, amely az lehetséges értékeit nekünk kell feltölteni tervezési-  vagy futási időben. Ebből a listából kiválasztott elem a hozzárendelt mezőbe kerül tárolásra.

A DBListBox komponenshez nagyon hasonló vezérlőelem a DBComboBox, azonban itt a választható elemeket egy legördülő listából választhatjuk ki.

Abban az esetben, ha egy mező értéke csak igaz, vagy hamis lehet, akkor használhatjuk a DBCheckBox vezérlőelemet. A logikai érték kerül eltárolásra az adattábla megfelelő mezőjében.

Egy adatbázishoz kapcsolódó választógomb-csoportot hoz létre a DBRadioGroup komponens. A gombok egy listában tárolódnak és a kiválasztott elem sorszáma kerül be a tábla mezőjébe.

Számos esetben előfordul, hogy egy listaelem sorait egy másik táblából kellene feltölteni. Ennek biztosítására készült a DBLookupListBox komponens, amely rendkívül jól használható több táblás adatbázisok esetében.

A DBLookupListBox vezérlőelem egy speciális változata a DBLookupComboBox, amikor is az adatok egy legördülő listába kerülnek be.

A DBRichEdit komponens nagyon hasonlít a DBMemo vezérlőelemhez, mivel itt is több soros információt tárolhatunk, azonban az ebben megjelenített tartalomhoz formátumot is hozzárendelhetünk. Lehetőség van szövegek stílusát, betűtípusát, betűméretét megváltoztatni.

Most, hogy már ismerjük mind az adatelérésre-, mind az adatmegjelenítésre szolgáló komponenseket, nézzük meg, hogy mire is megyünk ezzel a tudással a gyakorlatban.

Egy kis gyakorlat…

Ennyi elmélet után lássuk a gyakorlatot. Az egyszerűség kedvéért a Delphiben elérhető mintaadatbázist fogjuk használni.

Hozzunk létre egy új projektet. Szükségünk lesz egy Table és egy DataSource komponensre, hogy létrejöjjön a kapcsolat az adatok és az alkalmazásunk között.

A Table komponensnek a DataBaseName tulajdonságát az Object Inspectorban változtassuk meg DBDEMOS-ra. Ez egy aliasnév, amely megadja, hogy a BDE hol találja a mintaadat bázisokat. Miután ezzel megvagyunk a komponensünkhöz hozzá kell rendelnünk a fizikai táblát, ami most legyen az ANIMALS.DB. Ez a tábla állatok adatait tartalmazza, többféle vezérlőelem használatát be lehet mutatni a segítségével. Ahhoz, hogy a kapcsolat ténylegesen létrejöjjön, a komponenst aktivizálni kell, amihez az Active tulajdonságát állítsuk igazra (true).

Az adatforrás (DataSource) komponensnek egy tulajdonságára van szükségünk, ez pedig a DataSet. A legördülő listából ki tudjuk választani a tábla komponensünknek a nevét. Ezzel az adatelérés beállításával meg is vagyunk.

A párbeszédpanelen el kell helyeznünk az adatok megjelenítésére szolgáló komponenseket a DataControl palettáról. Szükségünk lesz egy DBNavigatpor, egy DBGrid, négy DBEdit és egy DBImage komponensre, valamint néhány egyszerű címkére, amivel jelezhetjük, hogy melyik vezérlőelem milyen információt tartalmaz. Minden komponensnek be kell állítani, hogy honnan kapja az adatokat, amire a DataSource tulajdonság szolgál. Mivel ez mindegyik komponensnél ugyanaz, ezért egyszerre is beállíthatjuk, csak jelöljük ki a vezérlőelemeket. Ezután már egyesével meg kell adni, hogy melyik mezőhöz tartozzanak. Ezt a DataField tulajdonság beállításával tehetjük meg. Mivel itt legördülő listából kell a megfelelő mezőt kiválasztanunk, nem tévedhetünk a nevek megadásánál. Aki nem tud angolul, egy kis magyarázat a nevekkel kapcsolatban: Name (név), Size (méret), Weight (tömeg), Area (terület, élőhely), BMP (bitmap, vagyis ebben tároljuk a képet) A Form felépítése az alábbi ábrán szemügyre vehető.

Első adatbázis-kezelő programunk máris működőképes, használatba is vehetjük, csak egyszerűen futtassuk le. Mint láthatóm, mindehhez egyetlen sor kódot sem kellett írnunk. Persze van néhány szépséghibája, amelyet egyszerűen ki is javíthatunk. Az első, hogy a formhoz tartozó, a címsorban megjelenő Form1 felirat csúnya, éppen ezért a Form tulajdonságlapján állítsuk be a Caption értékét valamilyen, nekünk tetsző szövegre.

A következő, egy kicsit zavaró tényező, hogy a táblázatban a mezőnevek angolul szerepelnek. Ezt is ki tudjuk természetesen javítani, mégpedig egy másik hibával egyetemben. Ez utóbbi a BMP mezőben szereplő (BLOB) feliratokat jelenti, gondolom egyértelmű, hogy ennek megjelenítése semmilyen plusz információval nem szolgál. Éppen ezért tüntessük el ezt is az oszlopok feliratainak megváltoztatásával egyetemben.

Ha a DBGrid komponensen duplán kattintunk, akkor megnyílik a hozzá tartozó oszlopszerkesztő, amely az alábbi ábrán is szemügyre vehető.

A lista most üres, ami azt jelenti, hogy minden oszlop megjelenik, ami a táblában szerepel, mégpedig azokkal az értékekkel, ami ott szerepel. Mivel négy oszlopra van csak szükségünk, adjuk a listához hozzá négy oszlopot.

Minden oszlopot egyesével be kell állítanunk, amihez az Object Inspectort fogjuk természetesen használni. Az első oszlop tulajdonságlapja látható a fenti ábrán. Nekünk be kell állítanunk a FieldName tulajdonságot, amit a már ismert legördülő listából tehetünk meg. Mihelyt beállítjuk ez a jellemzőt, rögtön meg is jelenik az oszlop az eredeti elnevezéssel és a mezőben található tulajdonság-értékekkel. Az oszlop megnevezésének a megváltoztatásához a Title csoportban található Caption tulajdonságot is meg kell adnunk. A kibontáshoz a Title szón kattintsunk duplán. Beállíthatjuk azt is, hogy az oszlopfejléc középre legyen igazítva, amihez az ugyanebben a csoportban található Aligment tulajdonságot állítsuk be tsCenter értékre. Az eredmény az alábbi ábrán látható.

A következő cikkekben erre az ismeretre fogunk tovább építkezni és egyre több mindent meg fogunk ismerni ennek a remek programozási nyelvnek a sajátosságairól, működéséről és használatáról. Addig is az Olvasókra bízom, hogy milyen feladatokat találnak ki maguknak, a DBDEMOS álnév alatt számos más, ennél nagyobb táblával gyakorolnak.

Markó Imre