Dazu werden wir Veränderungen an drei Klassen unseres SQLite Projekts vornehmen. Doch bevor wir mit dem Programmieren beginnen, werden wir uns damit beschäftigen, wie man eine Tabelle in die Android SQLite Datenbank einfügt.
Dabei betrachten wir auch, was sich hinter den Kulissen abspielt. Also welche Schritte im Android System beim Erstellen der Tabelle im Hintergrund ablaufen.
Anschließend werden wir in der Klasse ShoppingMemoDbHelper die Eigenschaften unserer SQLite Datenbank und der zu erstellenden Tabelle definieren.
Danach stellen wir in der ShoppingMemoDataSource-Klasse eine Verbindung zu unserer SQLite Datenbank her. Dabei wird automatisch vom Android System die Tabelle nach unseren Vorgaben erstellt.
In dieser Lektion lernt ihr:
- Wie man eine Tabelle in einer Android SQLite Datenbank erstellt
- Definieren der Eigenschaften unserer Datenbank in der DbHelper-Klasse
- Herstellen der Verbindung zur SQLite Datenbank mit der DataSource-Klasse
- Öffnen der Datenquelle in der MainActivity-Klasse
- Starten und Testen unserer App
Das Android SQLite Tutorial:
- Teil 1: Android SQLite Projekt anlegen
- Teil 2: SQLite Datenbank integrieren
- Teil 3: Tabelle in Datenbank erstellen
- Teil 4: Daten in Datenbank schreiben
- Teil 5: Auf Eingaben reagieren
- Teil 6: Daten aus Datenbank löschen
- Teil 7: Daten in Datenbank ändern
- Teil 8: SQLite Datenbank Upgrade
Um die Änderungen an dem Quellcode zu testen, werden wir von der MainActivity-Klasse aus auf die DataSource zugreifen. Dazu fügen wir den notwendigen Testcode in die Klasse MainActivity ein.
Somit werden wir folgende Arbeitsschritte in dieser Lektion des SQLite Tutorials ausführen:
- Definieren der Eigenschaften unserer Datenbank in der ShoppingMemoDbHelper-Klasse.
- Herstellen der Verbindung zur SQLite Datenbank in der ShoppingMemoDataSource-Klasse.
- Öffnen der Datenquelle und Zugriff auf die Datenbank in der MainActivity-Klasse
Nun wünschen wir euch viel Spaß bei Teil 3 unseres Android SQLite Datenbank Tutorials. Los geht’s!
1. Wie man eine Tabelle in einer Android SQLite Datenbank erstellt
Natürlich gibt es viele verschiedene Wege eine Tabelle in einer Android SQLite Datenbank zu erstellen. Der hier gezeigte Weg, ist nur einer von vielen.
Wir haben ihn gewählt, da er oft verwendet wird und zudem leicht verständlich ist.
Um ihn umzusetzen, benötigen wir als Hilfsmittel die Klasse SQLiteOpenHelper aus dem Package android.database.sqlite
. Wir verwenden diese Klasse zum Anlegen und Öffnen einer SQLite Datenbank in unserer Android Anwendung.
Doch bevor wir sie verwenden können, müssen wir eine eigene Klasse von ihr ableiten und in dieser unsere Datenbank-Operationen vorgeben.
Den ersten Schritt dazu haben wir bereits in der vorherigen Lektion ausgeführt und unsere Klasse ShoppingMemoDbHelper von der SQLiteOpenHelper-Klasse abgeleitet. Doch bisher geben wir in der abgeleiteten Klasse noch keine auszuführenden Datenbankanweisungen vor.
Dies werden wir in dieser Lektion nachholen. Doch vorher betrachten wir noch kurz was beim Anlegen der SQLite Datenbank im Hintergrund abläuft, um besser verstehen zu können, an welcher Stelle im Code es sinnvoll ist die Anweisung für das Erzeugen einer Tabelle einzufügen.
1.1 Was passiert wenn eine Datenbank angefragt bzw. erzeugt wird?
Um eine SQLite Datenbank anzufragen bzw. zu erzeugen, müssen wir den Konstruktor der Super-Klasse SQLiteOpenHelper aufrufen. Der Konstruktor benötigt Informationen über die Datenbank (Datenbankname) und die Umgebung (meist die Activity), in der die SQLite Datenbank ausgeführt wird.
Nachdem der Konstruktor der Super-Klasse ausgeführt wurde, können wir SQL-Befehle mit der Methode execSQL() auf der Datenbank ausführen lassen. Dazu benötigen wir aber noch eine Referenz auf die angelegte Datenbank.
Mit den beiden geerbten Methoden getWritableDatabase() und getReadableDatabase() können wir diese Datenbank-Referenz anfragen. Da wir nicht nur lesend sondern auch schreibend auf unsere SQLite Datenbank zugreifen möchten, lassen wir uns mit der Methode getWritableDatabase() die Referenz auf das Datenbankobjekt liefern. Das Objekt ist vom Datentyp SQLiteDatabase.
Nun geschieht das Wichtige. Beim Aufruf der getWritableDatabase()-Methode wird vom Android System geprüft, ob die Datenbank bereits existiert. Falls die im Konstruktor angegebene Datenbank schon vorhanden ist, wird diese geöffnet und die zugehörige Referenz zurückgegeben.
Falls die Datenbank noch nicht existiert, wird diese jetzt neu angelegt und dazu die Methode onCreate() unserer Hilfsklasse ShoppingMemoDbHelper ausgeführt. Sie ist eine der beiden geerbten Methoden, die wir in der vorherigen Lektion überschreiben mussten. Die andere Methode ist onUpgrade().
Da eine Datenbank ohne Tabelle keinen Sinn ergibt, ist die onCreate()-Methode unserer abgeleiteten Hilfsklasse ShoppingMemoDbHelper genau die Stelle in unserem Quellcode, an der wir unsere Tabelle erzeugen lassen.
Dies erfolgt durch einen SQL-String, der vorgibt, welchen Namen die Tabelle trägt und welche Spalten (mit Angabe des SQL-Datentyps) sie besitzt.
1.2 Erstellen einer Tabelle in die SQLite Datenbank
Auf die Datenbanksprache SQL werden wir in diesem Tutorial nicht eingehen. Wir werden aber die verwendeten SQL-Kommandos zum besseren Verständnis erklären. Wenn ihr mehr über SQL erfahren möchten, könnt ihr hier nachschauen: https://sqlzoo.net/.
Nun zurück zur Tabelle.
Die Tabelle werden wir mit dem folgenden SQL-String in die SQLite Datenbank einfügen:
public static final String SQL_CREATE = "CREATE TABLE " + TABLE_SHOPPING_LIST + "(" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + COLUMN_PRODUCT + " TEXT NOT NULL, " + COLUMN_QUANTITY + " INTEGER NOT NULL);";
Der obere SQL-Code bedeutet für das SQLite Datenbanksystem Folgendes:
- Eine Tabelle mit dem in der Konstante TABLE_SHOPPING_LIST gespeicherten Namen soll angelegt werden.
- Die Tabelle soll aus drei Spalten bestehen.
- Spalte 1 wird als Namen den Wert der Konstante COLUMN_ID tragen und als Primärschlüssel fungieren. Mit AUTOINCREMENT geben wir vor, dass die nächste ID automatisch um 1 erhöht wird. INTEGER gibt den SQL-Datentyp vor, also wird die ID als ganzzahliger Wert gespeichert.
- Spalte 2 wird als Namen den Wert der Konstante COLUMN_PRODUCT tragen und den eingegebenen Produktnamen als eine Zeichenkette speichern. Mit NOT NULL legen wir fest, dass in jedem Datensatz hier ein Wert eingetragen sein muss.
- Spalte 3 wird als Namen den Wert der Konstante COLUMN_QUANTITY tragen und die zu kaufende Menge als ganzzahligen Wert speichern. Auch diese Zelle muss immer befüllt werden.
Den eben beschriebenen SQL-String übergeben wir später der Methode execSQL(), die wir auf dem Datenbankobjekt aufrufen können, und lassen dadurch die Tabelle erstellen.
Der Aufruf würde dann bspw. auf diese Art erfolgen:
myDatabase.execSQL(SQL_CREATE);
Da wir nun wissen, wo wir das Erstellen der Tabelle vornehmen (in der onCreate() Methode) und auch den SQL-String zum Erzeugen der Tabelle kennen, werden wir unsere neu erlangten Kenntnisse in der Praxis anwenden und im nächsten Abschnitt unsere Tabelle in die SQLite Datenbank einfügen.
2. Definieren der Eigenschaften unserer SQLite Datenbank und Tabelle in der ShoppingMemoDbHelper-Klasse
Das Erstellen der Tabelle kann mit einer einzigen Anweisung erfolgen. Dies ist aber nicht empfehlenswert, da die Arbeit mit der Tabelle und der SQLite Datenbank dann sehr fehleranfällig wird.
Um sauber mit der Tabelle und der SQLite Datenbank arbeiten zu können, werden wir einige String-Konstanten in der Klasse ShoppingMemoDbHelper definieren.
In den Konstanten sind wichtige Eigenschaften der Datenbank und Tabelle gespeichert. Da die Konstanten als public deklariert werden, können wir so auch von anderen Klassen auf die Eigenschaften der Datenbank und Tabelle zugreifen.
Dieser Weg wirkt zu Beginn etwas umständlich und aufgeblasen, bei der späteren Arbeit mit der Datenbank möchte man die Datenbank-Konstanten aber nicht mehr missen. Sie erleichtern den Zugriff und stellen das akkurate Arbeiten mit der SQLite Datenbank sicher.
Das Erzeugen der Tabelle wird durch die folgenden drei Arbeitsschritte realisiert:
- String-Konstanten anlegen – sie enthalten die wichtigen Eigenschaften der Tabelle und Datenbank.
- Aufruf des Super-Konstruktors anpassen – wir ersetzen den bisherigen Beispielaufruf durch einen Aufruf mit echten Werten durch Zuhilfenahme der String-Konstanten.
- Tabelle in onCreate() Methode erzeugen – wir implementieren die onCreate() Methode und lassen den SQL-String mit execSQL() darin ausführen.
Wir werden jetzt die Arbeitsschritte der Reihe nach ausführen. Sollte etwas unklar sein, könnt ihr am Ende dieses Abschnitts den gesamten Quellcode der Klasse ShoppingMemoDbHelper in Ruhe analysieren.
2.1 Definieren der String-Konstanten unserer SQLite Datenbank
Als Erstes öffnen wir die Klasse ShoppingMemoDbHelper in dem Editor von Android Studio. Die Klassendatei befindet sich im Package-Ordner de.codeyourapp.shoppinglist unseres Projekts. Das Gerüst der Klasse haben wir bereits in der vorherigen Lektion des SQLite Tutorials angelegt.
Wir werden nun die Datenbank-Konstanten definieren. Dazu fügen wir den folgenden Quellcode direkt nach der Definition der bereits vorhandenen Konstante LOG_TAG in die ShoppingMemoDbHelper.java
Klasse ein:
ShoppingMemoDbHelper.java
public static final String DB_NAME = "shopping_list.db"; public static final int DB_VERSION = 1; public static final String TABLE_SHOPPING_LIST = "shopping_list"; public static final String COLUMN_ID = "_id"; public static final String COLUMN_PRODUCT = "product"; public static final String COLUMN_QUANTITY = "quantity"; public static final String SQL_CREATE = "CREATE TABLE " + TABLE_SHOPPING_LIST + "(" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + COLUMN_PRODUCT + " TEXT NOT NULL, " + COLUMN_QUANTITY + " INTEGER NOT NULL);";
In den ersten beiden Zeilen legen wir den Namen der Datenbankdatei und die Versionsnummer der Datenbank fest. In Zeile 4 geben wir den Namen der zu erzeugenden Tabelle vor.
Die Namen der drei Tabellenspalten legen wir in den Zeilen 6 bis 8 fest. Die ID-Spalte wird als Primärschlüssel genutzt werden und trägt den Namen _id
. Es ist sehr ratsam diese Bezeichnung zu wählen, da einige Klassen aus der Android-API, bspw. die Klasse SimpleCursorAdapter, diese Bezeichnung zwingend erwarten.
In unserem Android SQLite Tutorial könnten wir auch einen anderen Namen wählen, bleiben aber bei dieser weit verbreiteten Standardbezeichnung.
In den Zeilen 10 bis 14 definieren wir den SQL-String, mit dem wir die Tabelle in unserer SQLite Datenbank erstellen werden. Unsere Tabelle wird drei Spalten besitzen und darin die Daten der Einkaufsliste verwalten. Die Definition der Tabelle erfolgt mit den vorher angelegten String-Konstanten.
Dies ist später bei Datenbankanfragen sehr hilfreich, da wir mit Hilfe dieser Spalten-Konstanten unsere SQL-Anfrage erstellen werden.
Da wir nun alle Datenbankeigenschaften in den String-Konstanten festgehalten haben, können wir die Datenbank im nächsten Schritt mit Hilfe des Super-Konstruktors erzeugen lassen.
2.2 Aufruf des Super-Konstruktors anpassen
Zu Testzwecken haben wir bereits einen Beispielaufruf des Super-Konstruktors in dem Konstruktor der Klasse ShoppingMemoDbHelper angegeben. Dieser hat nun ausgedient und wird durch den unten markierten Aufruf ersetzt.
Dazu überarbeiten wir den Konstruktor ShoppingMemoDbHelper der ShoppingMemoDbHelper.java
Klasse:
ShoppingMemoDbHelper.java
public ShoppingMemoDbHelper(Context context) { //super(context, "PLATZHALTER_DATENBANKNAME", null, 1); super(context, DB_NAME, null, DB_VERSION); Log.d(LOG_TAG, "DbHelper hat die Datenbank: " + getDatabaseName() + " erzeugt."); }
Mit der markierten Codezeile (Zeile 3) rufen wir den Konstruktor der ShoppingMemoDbHelper-Elternklasse auf, diese ist die SQLiteOpenHelper-Klasse.
Dabei übergeben wir das context
-Objekt und die String-Konstanten DB_NAME
und DB_VERSION
. In den beiden String-Konstanten haben wir den Namen der Datenbank („shopping_list.db“) und die Versionsnummer (1) gespeichert. Das dritte Argument ist null
, hier könnte man ein CursorFactory-Objekt übergeben, welches wir in unserem Tutorial aber nicht benötigen.
Durch den Aufruf des Super-Konstruktors wird somit eine Datenbank erzeugt, die ihre Daten in der Datei „shopping_list.db“ speichert und die Versionsnummer 1 trägt. Die Versionsnummer ist für spätere Upgrades der SQLite Datenbank wichtig, wenn bspw. eine weitere Spalte der Tabelle hinzugefügt werden soll.
Da nun das Erzeugen der SQLite Datenbank sichergestellt ist, können wir im nächsten Arbeitsschritt das Erstellen der Tabelle umsetzen.
2.3 Erstellen der Tabelle in der onCreate() Methode vorbereiten
Wie wir in Abschnitt 1 erfahren haben, wird die onCreate() Methode automatisch aufgerufen, wenn die SQLite Datenbank neu angelegt wird. Ist die Datenbank erst einmal angelegt, wird die onCreate() Methode nicht mehr aufgerufen.
Diesen Zusammenhang dürfen wir nicht vergessen, wenn wir bspw. zu Testzwecken eine Datenbank bereits angelegt haben und im Anschluss daran eine Tabelle einfügen wollen. In einem solchen Fall muss die zugehörige Datenbankdatei erst gelöscht werden.
Dies geschieht automatisch, wenn ihr die App von eurem Android Gerät oder dem Android Emulator deinstalliert. Da wir aber bisher noch keine Datenbank mit dem Namen „shopping_list.db“ erzeugt haben, müssen wir unsere SQLite-App vorher nicht deinstallieren.
Um die Tabelle in der SQLite Datenbank anzulegen, fügen wir den folgenden Quellcode in die onCreate() Methode der ShoppingMemoDbHelper.java
Klasse ein:
ShoppingMemoDbHelper.java
// Die onCreate-Methode wird nur aufgerufen, falls die Datenbank noch nicht existiert @Override public void onCreate(SQLiteDatabase db) { try { Log.d(LOG_TAG, "Die Tabelle wird mit SQL-Befehl: " + SQL_CREATE + " angelegt."); db.execSQL(SQL_CREATE); } catch (Exception ex) { Log.e(LOG_TAG, "Fehler beim Anlegen der Tabelle: " + ex.getMessage()); } }
Dies ist auch schon alles. Die Tabelle wird mit der Anweisung in Zeile 6 erstellt und in die SQLite Datenbank eingefügt. Dazu übergeben wir mittels execSQL() dem SQLiteDatabase-Objekt das SQL-Kommando zur Ausführung.
Sollte ein Fehler beim Erstellen der Tabelle aufgetreten sein, fangen wir diesen mit dem try-catch Block ab und geben die Meldung über den eingetretenen Fehler auf der Konsole aus.
2.4 Der komplette Quellcode der ShoppingMemoDbHelper-Klasse
Nun haben wir alle Veränderungen an der ShoppingMemoDbHelper-Klasse vorgenommen und das Erstellen der Tabelle in die Android SQLite Datenbank vorbereitet.
In dem unten angegebenen Quellcode ist die gesamte ShoppingMemoDbHelper-Klasse nochmals zur Kontrolle aufgeführt. Die neu eingefügten Zeilen sind markiert worden.
Der vollständige Quelltext der Klasse ShoppingMemoDbHelper.java
:
ShoppingMemoDbHelper.java
package de.codeyourapp.shoppinglist; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; public class ShoppingMemoDbHelper extends SQLiteOpenHelper{ private static final String LOG_TAG = ShoppingMemoDbHelper.class.getSimpleName(); public static final String DB_NAME = "shopping_list.db"; public static final int DB_VERSION = 1; public static final String TABLE_SHOPPING_LIST = "shopping_list"; public static final String COLUMN_ID = "_id"; public static final String COLUMN_PRODUCT = "product"; public static final String COLUMN_QUANTITY = "quantity"; public static final String SQL_CREATE = "CREATE TABLE " + TABLE_SHOPPING_LIST + "(" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + COLUMN_PRODUCT + " TEXT NOT NULL, " + COLUMN_QUANTITY + " INTEGER NOT NULL);"; public ShoppingMemoDbHelper(Context context) { //super(context, "PLATZHALTER_DATENBANKNAME", null, 1); super(context, DB_NAME, null, DB_VERSION); Log.d(LOG_TAG, "DbHelper hat die Datenbank: " + getDatabaseName() + " erzeugt."); } // Die onCreate-Methode wird nur aufgerufen, falls die Datenbank noch nicht existiert @Override public void onCreate(SQLiteDatabase db) { try { Log.d(LOG_TAG, "Die Tabelle wird mit SQL-Befehl: " + SQL_CREATE + " angelegt."); db.execSQL(SQL_CREATE); } catch (Exception ex) { Log.e(LOG_TAG, "Fehler beim Anlegen der Tabelle: " + ex.getMessage()); } } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }
Vergleicht bitte ganz genau den oberen Quellcode mit eurem eigenen Quellcode in Android Studio. Es ist wichtig, dass ihr die markierten Änderungen an exakt den gleichen Stellen im Quelltext der ShoppingMemoDbHelper-Klasse durchgeführt habt.
In Android Studio sollte die ShoppingMemoDbHelper.java
Klassendatei nun wie folgt aussehen:
In der oberen Abbildung sind die in den drei Arbeitsschritten vorgenommenen Änderungen mit blauen Rahmen markiert:
- A – Anlegen der Datenbank- und Tabellen-Konstanten für das sichere Arbeiten mit der Datenbank.
- B – Überarbeiten des Konstruktors, so dass nun die korrekte Datenbank angelegt wird.
- C – Überarbeiten der onCreate() Methode, so dass per SQL-Befehl eine Tabelle in unserer SQLite Datenbank angelegt wird.
Somit sind die Vorbereitungen in der ShoppingMemoDbHelper-Klasse abgeschlossen. Wir können sie nun in der ShoppingMemoDataSource-Klasse zum Erstellen der Datenbank und Tabelle verwenden.
3. Herstellen der Verbindung zur SQLite Datenbank mit der ShoppingMemoDataSource-Klasse
Bisher haben wir das Erstellen der Tabelle in die Datenbank nur vorbereitet.
Der Quellcode, den wir in die onCreate() Methode der ShoppingMemoDbHelper-Klasse eingefügt haben, wird noch nicht ausgeführt und somit wird auch keine Tabelle angelegt.
Erst wenn wir die geerbte Methode getWritableDatabase() der ShoppingMemoDbHelper-Klasse aufrufen, wird der Erstellungsprozess der Datenbank vom Android System gestartet.
Hierbei wird entweder eine Referenz auf die bereits vorhandene SQLite Datenbank zurückgeliefert oder, wenn noch keine Datenbank vorhanden ist, eine neue SQLite Datenbank angelegt.
Da in unserer Klasse ShoppingMemoDataSource eine Instanz der Klasse ShoppingMemoDbHelper vorhanden ist, können wir auf dieser Instanz die getWritableDatabase() Methode aufrufen und dadurch den Erstellungsprozess der SQLite Datenbank und der Tabelle auslösen.
Wenn die SQLite Datenbank erfolgreich angelegt wurde, erhalten wir als Rückgabewert eine Referenz auf das Datenbankobjekt. Wir stellen also mit dem Aufruf der getWritableDatabase() Methode auch immer eine Verbindung zu dem SQLite Datenbankobjekt her.
Wir werden nun eine solche Verbindung zur SQLite Datenbank von unserer ShoppingMemoDataSource-Klasse herstellen lassen. Dazu implementieren wir zwei neue Methoden in der Klasse, die open() Methode, deren Aufgabe der Aufbau der Datenbankverbindung ist, und die close() Methode, die für das Schließen der Verbindung zuständig sein wird.
Wir öffnen nun die ShoppingMemoDataSource.java
Klasse im Editor von Android Studio und fügen den markierten Code-Block in den Quelltext ein. Die Klassendatei befindet sich im Package-Ordner de.codeyourapp.shoppinglist unseres Projekts.
An dieser Stelle endet der freie Inhalt dieser Lektion. Wir hoffen, sie hat dir bis hierher gefallen! Du kannst sie im geschützten Bereich von ProgrammierenLernenHQ fortsetzen, in welchem sich alle Lektionen unserer Android Online-Kurse befinden.
Unsere Android Kurse bestehen aus insgesamt 43 großen Lektionen und sind unterteilt in 13 frei zugängliche und 30 Premium-Lektionen. Die Premium-Lektionen befinden sich in dem geschützten Bereich und sind nur für Käufer unseres Android Online-Kurs Gesamtpaket zugänglich.
In unserem Android Online-Kurs Gesamtpaket befinden sich 43 große Lektionen, in denen wir dir schrittweise zeigen, wie voll funktionstüchtige Android Apps programmiert werden.
Diese Lektion ist Teil unseres Android Gesamtpakets. Insgesamt sind unsere Online-Kurse unterteilt in 13 frei zugängliche und 30 Premium-Lektionen.
Die Premium-Lektionen befinden sich in dem geschützten Bereich und sind nur für Käufer des Android Online-Kurs Gesamtpakets zugänglich.
Welche Inhalte befinden sich im Android Online-Kurs Gesamtpaket?
Wir hoffen, Dich bald als neuen Kursteilnehmer unserer Android Online-Kurse begrüßen zu dürfen!
Einmal kaufen und dadurch zeitlich unbegrenzten Zugriff auf alle Inhalte unseres Android Online-Kurs Gesamtpakets erhalten.
Hinweis: Der untere Quellcode ist Teil des geschützten Bereichs von ProgrammierenLernenHQ. Durch Freischalten unserer Android Online-Kurse erhältst du Zugriff auf alle geschützten Inhalte.
Erfahre mehr über unsere Android Online-Kurse.
ShoppingMemoDataSource.java
Für das Öffnen und Schließen der SQLite Datenbankverbindung nutzen wir die beiden Methoden getWritableDatabase() und close() der Klasse SQLiteOpenHelper, die wir über das ShoppingMemoDbHelper-Objekt dbHelper aufrufen.
Mit dem Aufruf in Zeile 22 in der open() Methode stellen wir die Verbindung zu unserer SQLite Datenbank her. Beim ersten Start unserer App, wenn also noch keine Datenbankdatei vorhanden ist, wird durch den Aufruf auch der Erstellungsprozess der Datenbank gestartet.
Dabei wird die onCreate() Methode unserer ShoppingMemoDbHelper-Klasse einmalig ausgeführt und dadurch auch die Tabelle mit db.execSQL(SQL_CREATE); erstellt.
In Zeile 27 der close() Methode schließen wir die Verbindung zur Datenbank wieder. Dies erfolgt durch den Aufruf der gleichnamigen close() Methode auf dem dbHelper Objekt, welches die Methode von seiner Superklasse ShoppingMemoDbHelper geerbt hat.
Mit den beiden neuen Methoden open() und close() können wir nun sehr einfach eine Verbindung zu unserer SQLite Datenbank herstellen und wieder schließen. Um Details müssen wir uns dabei nicht kümmern, das übernimmt für uns die extra dafür angelegte Hilfsklasse ShoppingMemoDbHelper.
Diese Kapselung wird uns bei der Arbeit mit der Datenbank später eine große Hilfe sein und sorgt für verständlicheren und übersichtlicheren Quellcode.
In Android Studio sollte die ShoppingMemoDataSource.java
Klassendatei nun wie folgt aussehen:
In der oberen Abbildung ist die bereits überarbeitete ShoppingMemoDataSource.java
Klassendatei dargestellt. Der Quellcode wurde an einer Stellen (Markierung A) überarbeitet. Und zwar wurden die beiden Methoden open() und close() eingefügt, die für das Öffnen und Schließen der Datenbankverbindung verantwortlich sind.
Im nächsten Abschnitt werden wir von der MainActivity-Klasse aus eine Verbindung zur Datenbank herstellen lassen. Dabei nutzen wir unsere Datenquelle (ShoppingMemoDataSource), die das Öffnen und Schließen der Datenbankverbindung übernehmen wird. Dabei überprüfen wir auch gleichzeitig, ob unsere SQLite-App nach den vorgenommenen Änderungen noch korrekt funktioniert.
4. Öffnen der Datenquelle und Zugriff auf die Datenbank in der MainActivity-Klasse
Wir haben in der Datenbank-Hilfsklasse ShoppingMemoDbHelper den Code für das Anlegen der SQLite Datenbank und Erstellen einer Tabelle hinterlegt. Die Klasse ShoppingMemoDataSource haben wir als Datenquelle erstellt, von der aus wir eine Verbindung zur Datenbank aufbauen und später die Manipulationen an der Datenbank vornehmen werden.
Somit sind die Grundlagen für die Arbeit mit einer SQLite Datenbank gelegt. Jetzt müssen wir noch die Datenquelle öffnen und erhalten so Zugriff auf die Datenbank.
Dies werden wir in der MainActivity-Klasse vornehmen und von dort die Zugriffe auf die SQLite Datenbank über die Datenquelle (DataSource) steuern. Für das Öffnen und Schließen der Datenquelle benötigen wir jeweils nur eine Anweisung.
Wir öffnen nun die Klassendatei MainActivity.java
im Editor von Android Studio, indem wir doppelt auf ihren Dateinamen im Project Tool Window klicken. Die Klassendatei befindet sich im Package-Ordner de.codeyourapp.shoppinglist unseres Projekts.
Ihren bisherigen Quellcode lassen wir zu großen Teilen bestehen und fügen diesem nur vier neue Zeilen hinzu. Der bereits überarbeitet Quellcode der MainActivity.java
ist unten aufgeführt:
Hinweis: Der untere Quellcode ist Teil des geschützten Bereichs von ProgrammierenLernenHQ. Durch Freischalten unserer Android Online-Kurse erhältst du Zugriff auf alle geschützten Inhalte.
Erfahre mehr über unsere Android Online-Kurse.
MainActivity.java
Die beiden Anweisungen sind selbsterklärend, nicht aber was sich im Hintergrund abspielt. Beim Öffnen der Datenquelle mit der Anweisung in Zeile 24 wird mit Hilfe des dataSource
Objekts vom Typ ShoppingMemoDataSource eine Verbindung zur SQLite Datenbank angefragt.
Falls keine Datenbank vorhanden ist, wird nun mit Hilfe der ShoppingMemoDbHelper-Klasse eine SQLite Datenbank angelegt und dabei auch die von uns in dieser Lektion definierte Tabelle.
Mit der Anweisung in Zeile 27 wird die Datenquelle wieder geschlossen. Dabei wird auch die Verbindung zur Datenbank getrennt.
Die MainActivity.java
Datei sollte in Android Studio nun wie folgt aussehen:
Damit haben wir alle notwendigen Änderungen an den Projektdateien vorgenommen.
Im nächsten Abschnitt werden wir unsere Android App ausführen und die Log-Meldungen analysieren. Dadurch können wir die Funktion unserer SQLite-App überprüfen und gleichzeitig besser verstehen, was beim Öffnen der Datenquelle passiert und in welcher zeitlichen Abfolge dies stattfindet.
5. Starten und Testen unserer SQLite-App
Wir werden nun unserer Android App auf einem Android Virtual Device im Emulator ausführen lassen und die Log-Meldungen unserer Anwendung im Logcat Tool Window überprüfen. Auf diese Weise können wir das Verhalten unserer App direkt in Android Studio analysieren und überprüfen, ob unsere Tabelle korrekt in der SQLite Datenbank angelegt wird.
Hinweis: Wenn ihr Probleme beim Ausführen der App im Android Emulator oder auf einem Android Gerät haben solltet, könnt ihr unseren großen Android Apps Programmieren Kurs als Hilfe nutzen. Darin zeigen wir, wie eine Android App im Emulator oder auf einem physikalischen Android Gerät ausgeführt wird.
Unsere App starten wir dazu wie gewohnt über den Run > Run 'app' Menüeintrag, den wir über die obere Menüleiste erreichen.
Unsere SQLite App sollte jetzt auf dem Android Gerät gestartet worden sein. Die grafische Benutzeroberfläche der Anwendung hat sich auch diesmal nicht geändert, daher sieht auf dem Gerät alles genau so aus wie in der vorherigen Lektion.
Hinweis: Das Emulator-Fenster mit dem darin laufenden Android Virtual Device muss für die nächsten Arbeitsschritte geöffnet bleiben. Zudem muss in dem AVD unsere eigene App ausgeführt werden. Sollte dies nicht der Fall sein, muss die App erneut im Emulator gestartet werden.
Um die Log-Meldungen zu überprüfen, öffnen wir in Android Studio das Logcat Tool Window während unsere App auf dem AVD im Emulator ausgeführt wird.
Dazu führen wir die folgenden Schritte aus:
- Wir öffnen das Logcat Tool Window mit einem Klick auf den Logcat-Tab am unteren Bildschirmrand.
- Anschließend wählen wir Emulator Nexus_9 als AVD in der Drop-Down Liste aus.
- Nun wählen wir unsere App de.codeyourapp.shoppinglist in der Liste rechts daneben aus.
- Danach stellen wir die Prioritätsstufe auf Verbose ein.
- Und geben in das anschließende Suchfeld MainActivity|ShoppingMemo als Suchbegriff ein.
- Zuletzt wählen wir den Eintrag Show only selected application in Liste ganz rechts aus.
Uns werden die folgenden Log-Meldungen ausgegeben:
1: MainActivity﹕ Inhalt der Testmemo: 5 x Birnen
2: ShoppingMemoDataSource﹕ Unsere DataSource erzeugt jetzt den dbHelper.
3: ShoppingMemoDbHelper﹕ DbHelper hat die Datenbank: shopping_list.db erzeugt.
4: MainActivity﹕ Die Datenquelle wird geöffnet.
5: ShoppingMemoDataSource﹕ Eine Referenz auf die Datenbank wird jetzt angefragt.
6: ShoppingMemoDbHelper﹕ Die Tabelle wird mit SQL-Befehl: CREATE TABLE shopping_list(_id INTEGER PRIMARY KEY AUTOINCREMENT, product TEXT NOT NULL, quantity INTEGER NOT NULL); angelegt.
7: ShoppingMemoDataSource﹕ Datenbank-Referenz erhalten. Pfad zur Datenbank: /data/user/0/de.codeyourapp.shoppinglist/databases/shopping_list.db
8: MainActivity﹕ Die Datenquelle wird geschlossen.
9: ShoppingMemoDataSource﹕ Datenbank mit Hilfe des DbHelpers geschlossen.
Die drei ersten Log-Meldungen haben wir bereits in der vorherigen Lektion überprüft. Neu hinzugekommen sind die Meldungen 4 bis 9.
Vor dem Öffnen der Datenquelle wird die Log-Meldung „Die Datenquelle wird geöffnet.“ von der MainActivity aus ausgegeben. Anschließend wird die Datenquelle geöffnet und dadurch eine Referenz auf die Datenbank in der ShoppingMemoDataSource-Klasse angefragt.
Da noch keine Datenbank mit dem Namen shopping_list.db
auf dem Android Gerät vorhanden ist, wird sie angelegt und dabei die onCreate() Methode der ShoppingMemoDbHelper-Klasse ausgeführt. Dies wird uns mit der 6. Log-Meldung quittiert. Mit dieser Meldung können wir auch den SQL-String, den wir für das Erstellen der Tabelle verwenden, überprüfen.
Die Datenquelle besitzt jetzt eine Referenz auf die Datenbank und gibt uns den Pfad zur SQLite Datenbank als Meldung aus. Die letzten beiden Meldungen informieren uns über das Schließen der Datenquelle und Datenbank.
Hinweis: Sollte bei euch die Tabelle nicht angelegt worden sein (Log-Meldung 6), müsst ihr die App von eurem Android Gerät deinstallieren und dann erneut aufspielen. Dadurch wird die alte Datenbankdatei gelöscht und eine neue wieder angelegt.
Wir starten nun unsere App erneut über Android Studio. Die dadurch zurück erhaltenen Log-Meldungen sind mit den vorherigen fast identisch. Es besteht aber ein kleiner Unterschied zwischen den Log-Meldungen, auf den wir gleich eingehen werden.
Die folgende Abbildung enthält die resultierenden Log-Meldungen, wenn die App das erste Mal und danach ein zweites Mal gestartet wird.
Die beim erstmaligen Start ausgegebenen Log-Meldungen sind von einem blauen Rahmen umschlossen (Markierung 1). Darin ist mit einer grünen Linie die Log-Meldung unterstrichen, die bei dem Erstellen der Tabelle ausgegeben wird (Markierung A).
Die Log-Meldungen, welche beim zweiten Start ausgegeben werden, sind darunter mit einem gelben Rahmen umschlossen (Markierung 2). Bei ihnen fehlt die sechste Meldung, da die Tabelle nicht erneut in der Datenbank erstellt wurde.
Hinweis: Möchten wir die Tabelle erneut erstellen, müssen wir die App vom Android Gerät deinstallieren und anschließend neu starten.
Wenn bei euch die gleichen Log-Meldungen ausgegeben werden, habt ihr alle Arbeitsschritte korrekt umgesetzt und eure App verfügt nun über eine SQLite Datenbank mit einer Tabelle. In der nächsten Lektion des Android SQLite Tutorials können wir nun diese Tabelle mit Datensätzen füllen.
Zusammenfassung
In dieser Lektion unseres Android SQLite Tutorials haben wir eine Tabelle in die Datenbank eingefügt. Dazu mussten wir Änderungen an den folgenden drei Klassen vornehmen.
- ShoppingMemoDbHelper – Diese Klasse ist unsere Hilfsklasse. Hier haben wir die Eigenschaften der Datenbank und Tabelle definiert und die Tabelle mit einem SQL-Kommando erstellt.
- ShoppingMemoDataSource – Diese Klasse ist unsere Datenquelle und hält die Verbindung zur Datenbank aufrecht. Hier haben wir eine Referenz zu dem Datenbankobjekt angefragt und damit den Erstellungsprozess der Tabelle gestartet.
- MainActivity – Mit unserer Hauptklasse steuern wir die Datenbankzugriffe. In ihr haben wir unsere Datenquelle geöffnet und wieder geschlossen.
Durch das Testen unserer Android SQLite-App im letzten Abschnitt haben wir abschließend überprüft, ob die Tabelle ordnungsgemäß angelegt wurde.
Somit sind jetzt alle Bedingungen für das Arbeiten mit der Datenbank und ihrer Tabelle erfüllt. In der nächsten Lektion des Tutorials werden wir erstmals Datensätze in die Tabelle einfügen und wieder auslesen.
Comments 19
Hallo Chris,
erstmal vielen Dank für das ausführliche Tutorial! Auch wenn es schon etwas älter ist, hilft es noch sehr gut beim Einstieg.
Ich habe versucht dein ShoppingMemo Beispiel auf ein eigenes Problem anzuwenden und habe dabei eigentlich alles übernommen nur die Namen geändert. Jedoch fehlt bei mir die Log-Meldung, dass die Tabelle erstellt wurde. Dadurch komme ich dann auch beim nächsten Teils des Tutorials auf Fehlermeldungen. Anbei mal die Erstellung der Tabelle, vielleicht kannst du mir ja weiterhelfen. In der oncreate-Methode ist aktuell noch eine zweite Tabelle auskommentiert, die ich gerne später zusätzlich erzeugen würde.
Viele Grüße und besten Dank,
Fabian
Author
Hallo Fabian,
vielen Dank für dein Lob!
Ich denke, dass einige Leerzeichen in deinen Quellcode eingefügt werden müssen, damit die Tabelle erstellt werden kann. Denn es scheint so, als würde der SQL-Create Befehl nicht korrekt zusammengesetzt.
In deinem Quellcode:
sollten folgende Änderungen vorgenommen werden:
Viele Grüße, Chris
in 4. Öffnen der Datenquelle und Zugriff auf die Datenbank in der MainActivity-Klasse ist ein kleiner Fehler.
In Android Studio sollte die Klasse ShoppingMemoDataSource nun wie folgt aussehen:
müsste eigentlich
In Android Studio sollte die Klasse MainActivity nun wie folgt aussehen:
Author
Hallo Pascal,
danke für deinen Hinweis! Ich habe den Fehler korrigiert.
Viele Grüße, Chris
Hi Chris,
lange habe ich nach sowas gesucht – ein echt geniales Tutorial, das mir den Einstieg möglich gemacht hat. Alles ist bestens erklärt und dokumentiert und die Beispiele funktionieren. Genial!
Vielen herzlichen Dank und mehr davon!
Andreas!
Author
Hallo Andreas,
vielen Dank für dein Lob!
Viele Grüße, Chris
Hi,
ich habe folgendes Problem:
Bei mir wird keine datenbank erzeugt.
Mir fehlt auch die LOG Ausgabe:
Die Tabelle wird mit SQL-Befehl: CREATE TABLE shopping_list(_id INTEGER PRIMARY KEY AUTOINCREMENT, product TEXT NOT NULL, quantity INTEGER NOT NULL); angelegt.
Hier ist meine DbHelper Klasse mit der die Tabelle iegentlich angelegt werden soll:
Vielen Dank schonmal im Vorraus fürs drüberschauen.
!!!!
lg
ich korrigiere die Datenbank wird erzeugt .
Es wird aber leider keine Tabelle erzeugt…
Author
Hallo littlefutt,
anstelle von
muss in deinen Quellcode:
In Zeile 6 muss ein Semikolon nach der geschlossenen Klammer eingefügt werden.
Viele Grüße, Chris
Hallo,
unter 4. sollte es bei „In Android Studio sollte die Klasse ShoppingMemoDataSource nun wie folgt aussehen:“ statt „Klasse ShoppingMemoDataSource“ -> „Klasse MainActivity“ heißen, oder?
Ansonsten ein sehr gelungenes Tutorial!
Viele Grüße
Author
Hallo Dennis,
danke für den Hinweis. Ich habe die betreffende Stelle nun korrigiert.
Viele Grüße, Chris
Hi,
das Tutorial ist echt super, hat bisher auch super bei mir funktioniert, jetzt bin ich aber auf ein Problem gestoßen, bei dem ich nicht weiterkomme. Im Javafile der dbHelper Klasse bekomme ich bei dem Stück des Aufrufs des Superkonstruktors eine Error Meldung. Genauer gesagt schon beim vorigen Aufruf des Konstruktors der dbHelper Klasse.
Der Compiler sagt: „invalid method declaration; return type required.“
Dabei handelt es sich doch nicht um eine Methodendeklaration oder? Ich hab alles etliche male durchgeschaut, verglichen etc. und komme nicht darauf wo der Fehler liegt…
Danke, und viele Grüße,
Kim
Author
Hallo Kim,
ohne Quellcode ist der Fehler schwer zu finden. Wenn du möchtest, kannst Du mir die Quelldatei der dbHelper Klasse per E-Mail zusenden. Die E-Mail Adresse kannst Du im Impressum finden. Ich schaue dann mal, ob ich etwas herausfinden kann.
Viele Grüße, Chris
Pingback: Android SQLite Tutorial - Teil 1: SQLite Projekt anlegen
Hallo Chris,
großes Lob für die beiden Android-Tutorials. Du hast Dir sehr viel Mühe gegeben. Mir gelang damit der Einstieg in die Android-Programmierung sehr gut.
Ich freue mich schon auf die Fortsetzung mit dem 4. Teil am Ende dieser Woche.
Viele Grüße
Uwe
Author
Hallo Uwe,
danke für das Lob! Ja, Ende der Woche kommt Teil 4 raus.
Viele Grüße, Chris
Zwei echt gute Tutorials für den Einstieg in Android.
Setzt du das „Android SQLite Datenbank Tutorial “ irgendwann mit Teil 4 fort?
Gruß
Author
Hallo Stefan,
danke für das Lob! Der vierte Teil ist in Arbeit und erscheint Ende nächster Woche.
Viele Grüße, Chris
Pingback: Android SQLite Tutorial - Teil 2: SQLite Datenbank integrieren