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.