2. diel - Databázy v Androide - Trieda SQLiteOpenHelper
V minulej lekcii, Databáza v Androide - Vytvorenie ukážkového projektu , sme vytvorili ukážkový projekt aplikácie Notepad pre ukladanie vlastných poznámok do databázy, ktorá je umiestnená v úložisku zariadenia.
V dnešnom Java tutoriále začneme pracovať na Java kóde databázy pre ukladanie poznámok nášho poznámkového bločku. Neskôr budeme pokračovať s písaním metód, ktorými budeme k dátam databázy pristupovať.
Definícia štruktúry databázy
Našu prácu si rozdelíme do dvoch častí, v rámci ktorých budeme deklarovať dve triedy:DbHelper: Trieda definujúca štruktúru databázy.DataSource: Trieda s metódami pre prístup k dátam databázy.
Pre lepšiu prehľadnosť súborov v projekte budeme súbory triediť do rôznych zložiek. V našom jednoduchom projekte by sme sa bez tohto obišli, ale pri zložitejších projektoch je to veľmi prínosné z hľadiska prehľadnosti štruktúry jednotlivých častí Java kódu.
Vytvoríme teda zložku database, do ktorej obe spomínané
triedy umiestnime. V okne so štruktúrou projektu klikneme
pravým tlačidlom myši na zložku notepad. V zobrazenom menu cez
položku New zvolíme možnosť Package:

V zobrazenom dialógu, na koniec pripraveného textového reťazca,
doplníme názov našej novej zložky database a
potvrdíme klávesom Enter:

Trieda DbHelper
Trieda DbHelper bude definovať štruktúru
databázy vrátane tabuliek. Túto triedu vytvoríme v štruktúre
projektu kliknutím pravým tlačidlom myši na našu zložku
database. V zobrazenom menu, cez položku New, zvolíme
možnosť Java Class:

V ďalšom dialógu, do prázdneho políčka, napíšeme názov našej novej
triedy DbHelper. Ďalej skontrolujeme, že je vybraná možnosť
Class. Zadanie potvrdíme stlačením klávesu Enter:

Triedu odvodíme od triedy SQLiteOpenHelper:
public class DbHelper extends SQLiteOpenHelper { }
Konštanty
V úvode triedyDbHelper deklarujeme tieto konštanty:
TABLE_NOTES- názov tabuľkyCOLUMN_...- názvy stĺpcov tabuľkyDATABASE_NAME- názov databázyDATABASE_VERSION- číselná hodnota verzie databázyTABLE_NOTES_CREATE- textový reťazec s SQL príkazom pre vytvorenie konkrétnej tabuľky.
Konštanty sme deklarovali takto:
public class DbHelper extends SQLiteOpenHelper { public static final String TABLE_NOTES = "table_notes"; public static final String COLUMN_ID = "id"; public static final String COLUMN_TITLE = "title"; public static final String COLUMN_CONTENT = "content"; public static final String COLUMN_DATE = "date"; public static final String COLUMN_PRIORITY = "priority"; public static final String COLUMN_IS_ACTIVE = "is_active"; private static final String DATABASE_NAME = "database_notes.db"; private static final int DATABASE_VERSION = 2; private static final String TABLE_NOTES_CREATE = "CREATE TABLE " + TABLE_NOTES + " ( " + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + COLUMN_TITLE + " VARCHAR (100), " + COLUMN_CONTENT + " VARCHAR (100), " + COLUMN_DATE + " BIGINT, " + COLUMN_PRIORITY + " TINYINT, " + COLUMN_IS_ACTIVE + " TINYINT " + ");"; }
Konštruktor
Keďže sme našu triedu odvodili z triedySQLiteOpenHelper
musíme deklarovať:
- buď jeden z troch možných konštruktorov
- alebo vlastný konštruktor, ktorý musí volať rodičovský konštruktor v jednom z troch možných variantov
V triede DbHelper deklarujeme premennú context a
pridáme konštruktor:
public class DbHelper extends SQLiteOpenHelper { ... public Context context; public DbHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); this.context = context; }
Podrobnosti nájdeme v dokumentácii.
Metódy
Najprv si napíšeme metódyonCreate(),
doesDatabaseExist() a onUpgrade(). Nakoniec si len
ukážeme metódy onDowngrade() a onOpen().
Metóda onCreate()
Teraz prepíšeme metódu onCreate() z predka
SQLiteOpenHelper. Metóda je volaná pri vytvorení
databázy a dochádza tu aj k vytvoreniu všetkých
databázových tabuliek. V metóde voláme metódu
execSQL(), prijímajúcu v parametri konštantu
TABLE_NOTES_CREATE. Konštanta TABLE_NOTES_CREATE
obsahuje textový reťazec s SQL príkazom pre vytvorenie databázovej
tabuľky s názvom table_notes:
public class DbHelper extends SQLiteOpenHelper { ... @Override public void onCreate(SQLiteDatabase database) { database.execSQL(TABLE_NOTES_CREATE); } }
Metódu execSQL() možné použiť pre jeden
príkaz SQL, ktorý NIE JE príkazom SELECT, ani žiadnym iným
príkazom SQL, ktorý by vracal dáta.
Metóda
doesDatabaseExist()
Ďalej napíšeme metódu doesDatabaseExist(). V metóde si
uložíme databázový súbor, ktorý sme získali z metódy
getDatabasePath() volanej na Context z prijatého
parametra context. Z metódy ale vrátime iba hodnotu
true, alebo false, podľa toho, či databázový
súbor existuje:
public class DbHelper extends SQLiteOpenHelper { ... public static boolean doesDatabaseExist(Context context, String dbName) { File dbFile = context.getDatabasePath(dbName); return dbFile.exists(); } }
Metóda onUpgrade()
Nakoniec prepíšeme metódu onUpgrade() z predka
SQLiteOpenHelper:
public class DbHelper extends SQLiteOpenHelper { ... @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS " + TABLE_NOTES); onCreate(db); } }
Metóda je volaná pri potrebe upgradovať databázu po zmene jej štruktúry a je tiež automaticky volaná pri prechode databázy na vyššiu verziu. Na vyššiu verziu databázy prechádzame vždy, ak akokoľvek zmeníme štruktúru databázy – napríklad pridaním stĺpca databázovej tabuľky, zmena dátového typu stĺpca atď.
Pri zmene štruktúry databázy musíme zvýšiť hodnotu
našej konštanty DATABASE_VERSION. Po každej zmene verzie
databázy budú stratené všetky
dáta, ktoré doteraz boli v databáze uložené.
Metódy onDowngrade()
a onOpen()
Metódy onDowngrade() a onOpen() implementovať
nebudeme. Len si povieme na čo slúži:
onDowngrade()- metóda je volaná pri potrebe prechodu verzie databázy na nižšiu verziuonOpen()- metóda je volaná po dokončení konfigurácie pripojenia k databáze, alebo potom, čo bola vytvorená, upgradovaná alebo downgradovaná databázová schéma
Viac tabuliek
Databáza nášho poznámkového bločku bude pracovať s jednou tabuľkou. Ak by sme chceli mať tabuliek viac, iba si ukážeme postup a nižšie uvedené kódy do našej triedyDbHelper implementovať
nebudeme.
V triede DbHelper by sme deklarovali ďalšie konštanty s SQL
príkazmi pre vytvorenie ďalších tabuliek. Telá
prepisovaných metód onCreate() a onUpgrade() by sme
doplnili o ďalšie riadky s použitím príslušných parametrov pre
jednotlivé tabuľky.
Metóda onCreate() by potom mohla napríklad vyzerať nejako
takto:
@Override public void onCreate(SQLiteDatabase database) { database.execSQL(TABLE_1_CREATE_STRING); database.execSQL(TABLE_2_CREATE_STRING); database.execSQL(TABLE_3_CREATE_STRING); }
Metóda onUpgrade() by potom mohla napríklad vyzerať nejako
takto:
@Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS " + TABLE_1_NAME); db.execSQL("DROP TABLE IF EXISTS " + TABLE_2_NAME); db.execSQL("DROP TABLE IF EXISTS " + TABLE_3_NAME); onCreate(db); }
V prípade väčšieho počtu tabuliek by bolo nutné
deklarovať premenné s textovými reťazcami s definíciou stĺpcov každej
vytváranej tabuľky podobne, ako máme definovanú konštantu
TABLE_NOTES_CREATE.
V budúcej časti, Databázy v Androide - Metódy pre prácu s databázou , vytvoríme potrebné rozhrania a triedu
DataSource s komponentmi pre prístup k dátam našej
databázy.

