Elemi alkalmazások fejlesztése IV.
Adatbázis-kezelés ODBC driverrel
ADATBÁZIS-KEZELÉS ODBC DRIVERREL............................................................................................................ 1 ODBC: OPEN DATABASE CONNECTIVITY (NYÍLT ADATBÁZIS KAPCSOLÁS) ................................................................... 1 AZ ODBC FELÉPÍTÉSE .................................................................................................................................................... 2 ADATBÁZIS REGISZTRÁCIÓ ............................................................................................................................................. 2 PROJEKT LÉTREHOZÁSA .................................................................................................................................................. 3 A GENERÁLT PROJEKT FELÉPÍTÉSE .................................................................................................................................. 4 REKORDOK MEGJELENÍTÉSE ........................................................................................................................................... 4 ADATCSERE A VEZÉRL K ÉS AZ ADATTAGOK KÖZÖTT .................................................................................................... 5 RENDEZÉS ÉS SZ RÉS...................................................................................................................................................... 5 REKORD MÓDOSÍTÁSA .................................................................................................................................................... 6 REKORD BESZÚRÁSA....................................................................................................................................................... 6 A CEafView osztály módosítása ................................................................................................................................ 6 İ
Ő
EafView.h ................................................................................................................................................................................ 6 EafView.cpp............................................................................................................................................................................. 7 EafView.cpp............................................................................................................................................................................. 7
REKORD TÖRLÉSE ........................................................................................................................................................... 8 EafView.cpp............................................................................................................................................................................. 8
Szabóné Nacsa Rozália Email:
[email protected] Honlap: people.inf.elte.hu/nacsa 2004. november
Adatbázis-kezelés ODBC driverrel Ebben a munkafüzetben megtanuljuk, hogyan használhatjuk Visual C++-ban megírt alkalmazásainkban a már meglév adatbázisunkat ODBC meghajtóval. ı
ODBC: Open Database Connectivity (nyílt adatbázis kapcsolás) Napjainkban számos adatbázis-kezel létezik. Az els adatbázis-kezel alkalmazások úgy készültek, hogy a forráskódba beírták az adott adatbázisra jellemz eljáráshívásokat. (Application Program Interface hívások). Ha az alkalmazást egy új környezetben, egy másik adatbázisra szerették volna használni, akkor a programozóknak közvetlenül a forráskódban kellet átírni ezeket az eljárás- (API) hívásokat, annak ellenére, hogy az adatbázisokkal kapcsolatos tennivalók nagyon hasonlóak voltak. ı
ı
ı
ı
Az adatbázis-kezel k elterjedésével felmerült az igény az adatbázis-kezel k szabványos kezelésére. Az adatbázis-kezelés els szabványosítása az SQL nyelv (Standard Query Language) volt. Ezt a nyelvet az IBM fejlesztette ki és els ként az ORACLE implementálta. Napjainkra az adatbázis-kezel rendszerek legtöbbje lehet vé teszi, hogy adatbázisát az SQL nyelven keresztül is elérhessük. ı
ı
ı
ı
ı
ı
Az ODBC egy másik adatbázis-kezel szabvány. Itt egy szabványos eljárás készletet definiáltak az adatbázis eléréséhez. Az ilyen adatbázis-kezel rendszerek esetében rendelkezünk egy olyan „meghajtó programmmal - driverrel” is, amely az adott adatbázishoz biztosítja az ODBC szabvány eljárásokat. A programozó ODBC hozzáférés esetén mindig ugyanazt az eljáráskészletet használja, így alkalmazása módosítás nélkül futtatható bármely más ODBC meghajtóval rendelkez adatbázisra is. Ilyen ODBC eljárások például a rekordok bejárását végz MoveFirst(), MoveNext() eljárások. A hordozhatóság egyetlen feltétele, hogy az adatbázis-kezel rendelkezzen ODBC meghajtóval. ı
ı
ı
ı
ı
ELTE Informatikai Kar
1. oldal
Elemi alkalmazások fejlesztése IV.
Adatbázis-kezelés ODBC driverrel
Az ODBC felépítése Az ODBC architektúrája több szint . Legfelül van a „Connection” szint. Ezen a szinten két adatot kell megadni. Az egyik adat az adatforrás neve (DSN – Data Source Name). Ennek a névnek nem kötelez megegyeznie az adatbázis tényleges, adathordozóra felírt nevével. A másik adattal azt mondjuk meg, hogy az adatbázisunkhoz melyik ODBC drivert szeretnénk használni. A futó alkalmazás az aktuális adatforrás ismeretében határozza meg, hogy melyik drivert kell betöltenie. Az ODBC eljárások mellet az alkalmazásban kiadhatunk SQL parancsokat is. ő
ı
ODBC architektúra „Access” driver
Driver (meghajtó) „MySQL” driver
Adatbá Adatbázis1
DSN (adatforrás) Elemi alkalmazások fejlesztése adatbázis
A program indításakor a driver manager beolvassa az adatforrás adatait és betölti a drivert.
driver1
Alkalmazás CDataBase példány
Függvényhívások
CRecordSet példány
driver2 Adatbá Adatbázis2
Adatbázis regisztráció Azt a tevékenységet, melynek során összekapcsoljuk az adatbázist és az ODBC drivert (meghajtót) „adatbázis regisztrációnak” nevezzük. A regisztráció lépései 1. 2. 3. 4.
Vezérl pult/Felügyeleti eszközök/ODBC adatforrások Felhasználói DSN fül / Hozzáadás gomb Driver kiválasztása (MySQL ODBC 3.51) / Befejezés gomb DSN (Data Source Name – adatforrás név) konfikuráció DSN information Data Source Name: Elemi alkalmazások fejlesztése Description: MySQL ODBC 3.51 Driver DSN MySQL connection parameters Host: localhost Database name: eaf User: nacsa Pasword: xxxx Port: 3306 OK / OK ı
ELTE Informatikai Kar
2. oldal
Elemi alkalmazások fejlesztése IV.
Adatbázis-kezelés ODBC driverrel
Projekt létrehozása File/New/ Projects
Saját jegyzeteim
MFC AppWizard.exe Project name: Eaf Next
Step1: Single Document Document/View architecture support? Next Step 2/a: What database support would you like to import? Database view without file support DataSource gomb Datasource Step 2/b: ODBC (Elemi alkalmazások fejlesztése) Recordset type Snapshot OK Select database tables: diak Step 2/c: OK Step 3: What compound document support would you like to include? none What othr support would you like to include? Automation ActiveX controls Next Step 4: What features would you like to include? Docking toolbars Initial status bar Printing and print preview 3D controls How do you want your toolbars to look? normal How many files would you like on your recent file list? 4 Next Step 5: MFC Standards Yes please As a shared DLL
style comments library Next
Step 6: CEafView Class name: Base class: Header file Implementation file: CEafSet Class name: Base class: Header file Implementation file:
CEafView CRecordView EafView.h EafView.cpp CEafSet CRecordSet EafSet.h EafSet.cpp Finish
Forditás/Futtatás A projekt lefordítása után azonnal rendelkezésünkre állnak a legalapvet bb adatbázis navigáló funkciók. ı
ELTE Informatikai Kar
3. oldal
Elemi alkalmazások fejlesztése IV.
Adatbázis-kezelés ODBC driverrel
A generált projekt felépítése
A CEafView osztály a CRecordView osztályból, a CEafSet osztály a CRecordSet osztályból származtatással jött létre. Az örökl dés szabályai szerint a származtatott osztályok megöröklik az sosztályok metódusait. A CRecordSet osztályban találhatók az ODBC-vel kapcsolatos metódusok (MoveFirst(), MoveNext(), isEOF(), Update()). Az alkalmazás-varázsló felismeri a megjelölt tábla (diak tábla) felépítését és a CEafSet osztályban deklarálja a tábla egyes oszlopainak megfelel változókat. (m_diak_id, m_azon, m_nev). A CEafView osztályban definiált CEafSet-re mutató m_pSet pointer segítségével hívhatjuk meg a CRecordSet (ODBC) eljárásait. ı
ı
ı
Rekordok megjelenítése A fejleszt környezet ResourceView fülén, a Dialógus mappából válassza ki az IDD_EAF_FORM elemet és a már ismert módon tervezze meg az rlapot. ı
ő
Control ID IDC_DIAK_ID IDC_AZON IDC_NEV
1
Style Right, number left left
Variable name m_pSet->m_diak_id1 m_pSet->m_azon m_pSet->m_azon
Type long CString CString
A változók deklarálásához a Ctrl-t lenyomva tartva kattintson duplát a megfelel vezérl re. ı
ELTE Informatikai Kar
ı
4. oldal
Elemi alkalmazások fejlesztése IV.
Adatbázis-kezelés ODBC driverrel
ı
Adatcsere a vezérl k és az adattagok között A CEafView adattagjai és az IDD_EAF_FORM vezérl i között az adatcserét az UpdateData(TRUE) és az UpdateData(FALSE) eljárások végzik. Az osztályvarázsló a vezérl k és az adattagok közötti kapcsolatot a DoDataExchange() eljárás DDX_FieldText makróiban definiálja. ı
ı
void CEafView::DoDataExchange(CDataExchange* pDX) { CRecordView::DoDataExchange(pDX); //{{AFX_DATA_MAP(CEafView) DDX_FieldText(pDX, IDC_DIAK_ID, m_pSet->m_diak_id, m_pSet); DDV_MinMaxLong(pDX, m_pSet->m_diak_id, 1, 9999); DDX_FieldText(pDX, IDC_AZON, m_pSet->m_azon, m_pSet); DDV_MaxChars(pDX, m_pSet->m_azon, 20); DDX_FieldText(pDX, IDC_NEV, m_pSet->m_nev, m_pSet); DDV_MaxChars(pDX, m_pSet->m_nev, 30); //}}AFX_DATA_MAP }
Az UpdateData(FALSE) (a DoDataExchange makró definíciói alapján) az adattagokból a vezérl kbe, az UpdateData(TRUE) pedig a vezérl kb l az adattagokba tölti át az adatokat. Az UpdateData() metódust a CRecordView osztály OnMove() metódusa hívja meg. ı
ı
ı
Ezek a metódusok automatikusan bekerültek a projektbe, így a lefordított projekt azonnal alkalmas arra, hogy a diak táblát végigböngésszük.
Rendezés és sz rés ő
Adatbázis rekordjainak rendezett megjelenítéséhez a CRecordSet osztály m_strSort és m_strFilter CString típusú adattagjait kell a megfelel értékre beállítani. Az m_strSort adattag nem más, mint az SQL parancsok ORDER BY klauzulája, míg az m_strFilter adattag tartalma a WHERE klauzula értéke. ı
Példa SQL CRecordSet Select * from diak ORDER BY azon ASC; m_strSort = „azon” Select * from diak ORDER BY diak_id DESC; m_strSort = „diak_id DESC” Select * from diak WHERE nev Like „Nagy%”; m_strFilter = „nev Like „Nagy%” Egészítsük ki az alkalmazásunkat egy új menüponttal. A menü neve: Rendezés Menüpontok: Rendezés diak_id szerint (ID_SORT_DIAK_ID) Rendezés azonosító szerint (ID_SORT_AZON) Rendezés név szerint (ID_SORT_NEV) Vegyük hozzá a projektünkhöz az alábbi eseménykezel ket: ı
void CEafView::OnSortDiakId() { m_pSet->m_strSort = "diak_id"; m_pSet->Requery(); //Nyitott record set frissítése az adatbázisból UpdateData(FALSE); //Vezérl k frissítése a record setb l } void CEafView::OnSortAzon() { m_pSet->Close(); m_pSet->m_strSort = "azon"; m_pSet->Open(); //Új record set feltöltése az adatbázisból UpdateData(FALSE); //Vezérl k frissítése a record setb l } ı
ı
ELTE Informatikai Kar
ı
ı
5. oldal
Elemi alkalmazások fejlesztése IV.
Adatbázis-kezelés ODBC driverrel
void CEafView::OnSortNev() { m_pSet->m_strSort = "nev"; m_pSet->Requery(); //Nyitott record set frissítése az adatbázisból UpdateData(FALSE); //Vezérl k frissítése a record setb l } ı
ı
Rekord módosítása Az adatbázis böngészése közben egyszer en módosíthajuk az egyes rekordok adatait. Az adatbázis módosítását a CRecordView OnMove() eljárása hajtja végre. Ez az eljárás akkor hívódik meg, amikor „lelépünk” a rekordról. A CRecordView OnMove metódusa meghívja az UpdateData(TRUE) eljárást, mely a vezérl ket átmásolja a CRecordSet megfelel adattagjaiba, majd meghívja a a CRecordSet Move() eljárását. A Move() eljárás DoFieldExchange() metódusa az adattagokat átmásolja az adatbázisba. ő
ı
ı
OnMove() { ... UpdateData(TRUE); ... }
CRecordView
CRecordSet m_strSort m_strFilter Open() MoveFirst() MoveNext() isEOF() Update() Move() 3 ...
Move() { ... DoFieldExchange //makró ... }
1
CEafView
DoFieldExchange
m_diak_id m_azon m_name
Dialógus ablak
m_pSet
CRecordSet objektumra mutató pointer
CEafSet ODBC driver
OnMove()
2
UpdateData(TRUE)
4
Ha a párbeszéd ablak valamely vezérl jét csak olvashatóra állítjuk be, de ezt a mez t új rekord beszúrásakor a felhasználónak kell kitölteni, akkor a vezérl írásvédettségének beállítása attól függ, hogy éppen milyen feladatot hajtunk végre. Beszúrásnál fel kell oldani e mez „csak olvasható” állapotát. ı
ı
ı
ı
Rekord beszúrása Vezessünk be m_AddingRecord néven egy új privát BOOL adattagot a CEafView osztályban. Ebben az adattagban jelezzük, ha a Beszúrás m veletet hajtottuk végre. Az adattag kezd értéke legyen FALSE. ő
ı
módosítása A CEafView osztály módo sítása EafView.h private: BOOL m_AddingRecord;
ELTE Informatikai Kar
6. oldal
Elemi alkalmazások fejlesztése IV.
Adatbázis-kezelés ODBC driverrel
Legyen az m_AddingRecord adattag kezdetei értéke FALSE. EafView.cpp CEafView::CEafView() : CRecordView(CEafView::IDD) { //{{AFX_DATA_INIT(CEafView) m_pSet = NULL; //}}AFX_DATA_INIT // TODO: add construction code here m_AddingRecord = FALSE; }
Egészítsük ki alkalmazásunk Rekord menüjét a Rekord beszúrása menüponttal: ID_RECORD_ADD, majd illesszük be a projektbe a menüpont eseménykezel jét. EafView.cpp ı
void CEafView::OnRecordAdd() { //Létrehoz egy üres rekordot a record set-ben m_pSet->AddNew(); //"read only" vezérl k "engedélyezése" m_AddingRecord = TRUE; CEdit* pCtrl = (CEdit*)GetDlgItem (IDC_DIAK_ID); int result = pCtrl->SetReadOnly(FALSE); ı
//Az aktuális rekord (üres) adatainak átmásolása a recordset-be. UpdateData(FALSE); }
Végül felüldefiniáljuk a CRecordView osztály OnMove() virtuális függvényét, melyben a beszúrás m veletet elhagyva visszaállítjuk a „csak olvasható” mez (k) írásvédettségét. ı
ő
View/ClassWizard Project: Eaf Class name: CEafView Object IDs: CEafView Messages: OnMove Add function/Edit Code
BOOL CEafView::OnMove(UINT nIDMoveCommand) { if (m_AddingRecord) { m_AddingRecord = FALSE; UpdateData(TRUE); if(m_pSet->CanUpdate()) m_pSet->Update(); m_pSet->Requery(); UpdateData(FALSE);
//vezérl k ı
recordset
→
//Adatbázis frissítése //adatbázis recordset //recordset vezérl k →
→
ı
//"read only" visszaállítása CEdit* pCtrl = (CEdit*)GetDlgItem(IDC_DIAK_ID); pCtrl->SetReadOnly(TRUE); return TRUE; } else { return CRecordView::OnMove(nIDMoveCommand); } }
ELTE Informatikai Kar
7. oldal
Elemi alkalmazások fejlesztése IV.
Adatbázis-kezelés ODBC driverrel
Rekord törlése Egészítsük ki alkalmazásunk Rekord menüjét a Rekord törlése menüponttal: ID_RECORD_DELETE, majd illesszük be a projektbe a menüpont eseménykezel jét. ı
EafView.cpp void CEafView::OnRecordDelete() { m_pSet->Delete(); m_pSet->MoveNext();
//Töröljük az aktuális rekordot //Ráállunk a következ rekordra, ha van ilyen ı
if (m_pSet->IsEOF()) m_pSet->MoveLast(); if (m_pSet->IsBOF()) m_pSet->SetFieldNull(NULL); UpdateData(FALSE); }
A munkafüzetben bemutatott projekt letölthet a people.inf.elte.hu/nacsa/eaf/eaf4/projects/eafadmin_odbc címr l. ı
ı
ELTE Informatikai Kar
8. oldal