Ukladanie záznamov
SQLite
Android podporuje relačnú databázu SQLite, ktorú používajú aj iné programovacie jazyky C, Java, Python, Perl, atď. Databáza SQLite nepotrebuje mať spustený server, nemusí sa inštalovať a nepotrebuje nastavovať žiadne konfiguračné súbory. Dáta sú uložené v súbore, ku ktorému pristupuje klientská aplikácia. SQLite vykonáva vždy iba jeden príkaz, pričom čítanie má väčšiu prioritu ako zapisovanie.
Databáza podporuje vytvorenie tabuliek, indexovanie, podpora trigerov, vytváranie pohľadov, transakcie ACID (Atomicity, Consistency, Isolation, Durability).
Na rozdiel od SQL neumožňuje vložiť do tabuľky cudzí klúč, používať spojenia RIGHT OUTER JOIN, FULL OUTER JOIN, obmedzený príkaz ALTER TABLE.
Vytvorenie databázy
Na vytvorenie/ aktualizovanie databázy potrebujeme triedu SQLiteOpenHelper, ktorú budeme dediť v našej triede.
Metódy triedy SQLiteOpenHelper:
- onCreate() – vytvorenie databázy a naplnenie údajmi prostredníctvom objektu SQLiteDatabase (ak objekty ešte neexistujú).
- onUpgrade() – zmena štruktúry tabuliek/ databázy. Obsahuje tri parametre – prvý je objekt SQLiteDatabase, druhý je číslo starej verzie databázy a tretí je číslo novej verzie databázy. Ak sa čísla verzí nezhodujú, vykoná sa zmena štruktúry DB – vymažp sa tabulky a následne sa znovu vytvoria.
- konštruktor – vytvorí sa databáza. Obsahuje štyri parametre:
- objekt typu Context – zvyčajne aktivita
- názov databázy
- stará verzia databázy (ak nie je použijeme null)
- nová verzia. Hodnota začína na čísle 1.
Podľa toho, či chceme čítať alebo zapisovať údaje do databázy, použijeme metódy:
- getWriteableDatabase()
- getReadableDatabase()
Obidve majú návratovú hodnotu – inštanciu triedy SQLiteDatabase, pomocou ktorej môžeme vykonávať SQL požiadavky.
Vytvorenie tabuľky
Tabuľka sa zvyčajne vytvára v metóde onCreate() zavolaním metódy execSQL() na inštancií triedy SQLLiteDatabase:
db.execSQL("CREATE TABLE " + DB_TABULKA
+ "(" + TABULKA_ID + " INTEGER PRIMARY KEY,"
+ TABULKA_KATEGORIA + " TEXT,"
+ TABULKA_ZNACKA + " TEXT,"
+ TABULKA_MODEL + " TEXT,"
+ TABULKA_STAV + " TEXT );");
Metóda execSQL() sa môže použiť iba na SQL príkazy, ktoré nevracajú žiadne údaje.
Vloženie záznamu
Vkladanie záznamu do databázy môžeme vykonať pomocou metódy execSQL() alebo insert()
| Java | Kotlin |
String insertSQL = "INSERT INTO " + DB_TABULKA + " (" +
|
val insertSQL = """ db.execSQL(insertSQL) |
alebo
ContentValues val = new ContentValues();
val.put(TABULKA_KATEGORIA, atributy.get(TABULKA_KATEGORIA));
val.put(TABULKA_ZNACKA, atributy.get(TABULKA_ZNACKA));
val.put(TABULKA_MODEL, atributy.get(TABULKA_MODEL));
val.put(TABULKA_STAV, atributy.get(TABULKA_STAV));
//metóda insert() vkladá údaje do DB, ako parametre obsahuje názov tabulky, null-sql nedovoluje vkladať prázdny riadok-null vloží NULL hodnotu, objekt ContentValues
db.insert(DB_TABULKA, null, val);
Metóda insert() obsahuje tri parametre:
- názov tabuľky
- názov stĺpca tabuľky, ktorý sa použije, ak je tretí parameter NULL
- inštanciu triedy ContentValues, ktorá obsahuje hodnoty, ktoré chceme do db vložiť
Ak je v príkaze INSERT hodnota primárneho klúča NULL, databáza inkrementovaním poslednej hodnoty vytvorí nový identifikátor.
Ďalšie metódy z triedy SQLiteDatabase
- close() – zavrie pripojenia na databázu
- rawQuery() –
- update() – aktualizuje záznam
- delete() – vymaže záznam.
Práca s kurzorom
Výsledkom každého SQL dotazu je inštancia triedy Cursor. Metódy pre prácu s triedou Cursor:
- getCount() – vráti počet riadkov
- getColumnCount() – vráti počet stĺpcov v riadku
- isFirst() – vráti true, ak kurzor ukazuje na prvý riadok
- moveToFirst() – presunie kurzor na prvý riadok
- moveToLast() – presunie kurzor na posledný riadok
- moveToNext() – presunie kurzor na ďalší záznam
V nasledujúcom kóde prechádzame záznamy z príkazu SELECT, pokiaľ neprídeme na koniec tabuľky.
| Java | Kotlin |
|
HashMap<String, String> zaznam = new HashMap<String, String>(); if (cursor.moveToFirst()) { |
//namiesto HashMap sa používa mutableMapOf ktoré má jednoduchšiu syntax val zaznam = mutableMapOf<String, String>() val selectQuery = "SELECT * FROM $DB_TABULKA WHERE _id='$id'" val db = this.writableDatabase if (cursor.moveToFirst()) { //hodnoty do mapy sa pridávajú cez [] |
Príklad
Aplikácia pozostáva z troch aktivít. Prvá aktivita obsahuje zoznam dát z tabuľky (ListView) a tlačidlo pridaj ďalší záznam (tlačidlo sa nachádza v panely nástrojov ActionBar). Druhá aktivita – pridanie záznamu, táto aktivita sa spustí po kliknutí na tlačidlo pridaj záznam. Po kliknití na tlačidlo „Uložiť“ sa záznam uloží do databázy a načíta sa hlavná aktivita – zoznam záznamov. Po kliknutí na ľubovoľný záznam sa otvorí tretia aktivita – uprav záznam. V tejto aktivite sa predvyplnia záznamy podľa identifikátora (id riadku) a používateľ môže upraviť alebo vymazať daný riadok.
![]() |
![]() |
![]() |
DataModel.java
| Java | Kotlin |
public class DataModel extends SQLiteOpenHelper {
|
class DataModel(context: Context) : SQLiteOpenHelper(context, DB_NAZOV, null, DB_VERZIA) { companion object { override fun onCreate(db: SQLiteDatabase) { override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) { // Vloží záznam do databázy // Aktualizuje záznam podľa ID // Vymaže záznam podľa ID // Vráti konkrétny záznam ako Mapu // Vráti všetky záznamy ako zoznam Map db.rawQuery(selectQuery, null).use { cursor -> return zaznamy |
MainActivity.java
| Java | Kotlin |
public class MainActivity extends AppCompatActivity |
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { // Nastavenie textu do action baru // Údaje z DB budú uložené v premennej autobazarList if (autobazarList.isNotEmpty()) { // Po kliknutí na riadok sa otvorí nová aktivita UpravZaznam // Po kliknutí otvor novú aktivitu // Nastavenie adaptéra // Vlastné metódy pre ListView - v prípade dedenia z triedy ListActivity ich nepotrebujem - mám getListView() protected fun setListAdapter(adapter: ListAdapter) { // Nastavenie menu v action bare override fun onOptionsItemSelected(item: MenuItem): Boolean { |
PridajZaznam.java
| Java | Kotlin |
public class PridajZaznam extends AppCompatActivity {
|
class PridajZaznam : AppCompatActivity() { private val dataModel = DataModel(this) override fun onCreate(savedInstanceState: Bundle?) { // Nastavenie textu do action baru edtKategoria = findViewById(R.id.edt_kategoria) // onClick metóda tlačidla pridaj záznam query[DataModel.TABULKA_KATEGORIA] = edtKategoria.text.toString() dataModel.vlozZaznam(query) // Po pridaní záznamu sa presmerujeme späť na hlavnú obrazovku |
UpravZaznam.java
| Java | Kotlin |
public class UpravZaznam extends AppCompatActivity {
|
class UpravZaznam : AppCompatActivity() { private val dataModel = DataModel(this) override fun onCreate(savedInstanceState: Bundle?) { // Nastavenie textu do action baru edtKategoria = findViewById(R.id.edt_kategoria) // Získaj parameter poslaný z predchádzajúceho okna = id val hm = dataModel.vypisZaznam(tabulkaId) // onClick metóda tlačidla uložiť záznam query[DataModel.TABULKA_ID] = tabulkaId dataModel.aktualizujZaznam(query) val intent = Intent(applicationContext, MainActivity::class.java) // onClick metóda tlačidla vymazať záznam val intent = Intent(applicationContext, MainActivity::class.java) |
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_data_model"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="p_v.databaza.MainActivity">
<TableRow
android:id="@+id/riadok2"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"></ListView>
</TableRow>
</TableLayout>
item.xml
<?xml version="1.0" encoding="utf-8"?>
<TableRow xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/tabulka_id"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:visibility="gone"
/>
<TextView
android:id="@+id/tabulka_znacka"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:textSize="20dp"
android:textStyle="bold"
/>
<TextView
android:id="@+id/tabulka_model"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:textSize="16dp"
/>
</LinearLayout>
</TableRow>
pridaj_zaznam.xml
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="5dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="5dp">
<TableRow
android:id="@+id/riadok1_kategoria"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/txt_kategoria"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:text="Kategoria:" />
<EditText
android:id="@+id/edt_kategoria"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
</TableRow>
<TableRow
android:id="@+id/riadok2_znacka"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/txt_znacka"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:text="Značka:" />
<EditText
android:id="@+id/edt_znacka"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
</TableRow>
<TableRow
android:id="@+id/riadok3_model"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/txt_model"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:text="Model:" />
<EditText
android:id="@+id/edt_model"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
</TableRow>
<TableRow
android:id="@+id/riadok4_stav"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/txt_stav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:text="Stav:" />
<EditText
android:id="@+id/edt_stav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
</TableRow>
<TableRow
android:id="@+id/riadok5_tlacidlo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center">
<Button
android:id="@+id/btn_ulozit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="pridajZaznam"
android:text="Uložiť" />
</TableRow>
</TableLayout>
uprav_zaznam.xml
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TableRow
android:id="@+id/riadok1_nadpis"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/nadpis"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="Pridaj záznam"/>
</TableRow>
<TableRow
android:id="@+id/riadok2_kategoria"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/txt_kategoria"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_weight="0.5"
android:text="Kategoria:"/>
<EditText
android:id="@+id/edt_kategoria"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_weight="1"/>
</TableRow>
<TableRow
android:id="@+id/riadok3_znacka"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/txt_znacka"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_weight="0.5"
android:text="Kategoria:"/>
<EditText
android:id="@+id/edt_znacka"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_weight="1"/>
</TableRow>
<TableRow
android:id="@+id/riadok4_model"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/txt_model"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_weight="0.5"
android:text="Model:"/>
<EditText
android:id="@+id/edt_model"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_weight="1"/>
</TableRow>
<TableRow
android:id="@+id/riadok5_stav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/txt_stav"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_weight="0.5"
android:text="Stav:"/>
<EditText
android:id="@+id/edt_stav"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_weight="1"/>
</TableRow>
<TableRow
android:id="@+id/riadok6_tlacidlo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/btn_ulozit"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_weight="0.5"
android:text="Uložiť"
android:onClick="ulozitZaznam"/>
<Button
android:id="@+id/btn_vymazat"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_weight="0.5"
android:text="Vymazať"
android:onClick="vymazatZaznam"/>
</TableRow>
</TableLayout>
menu_main.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity">
<item
android:id="@+id/action_pridat"
android:icon="@android:drawable/ic_input_add"
android:title="add"
app:showAsAction="ifRoom"
android:actionProviderClass="android.widget.ShareActionProvider"
/>
</menu>


