Підключення до бази даних SQLite

В Android є вбудована підтримка однієї з поширених систем керування базами даних - SQLite. Для цього в пакеті android.database.sqlite визначено набір класів, які дозволяють працювати з базами даних SQLite. І кожен додаток може створити свою базу даних.
Щоб використовувати SQLite в Android, потрібно створити базу даних за допомогою виразу на мові SQL. Після цього база даних буде зберігатися в каталозі додатка за шляхом:
DATA/data/[Назва_додатка]/databases/[Назва_файла_бази_даних]
ОС Android за замовчуванням вже містить ряд вбудованих баз даних SQLite, які використовуються стандартними програмами - для списку контактів, для зберігання фотографій з камери, музичних альбомів тощо.
Основну функціональність по роботі з базами даних надає пакет android.database. Функціональність безпосередньо для роботи з SQLite знаходиться в пакеті android.database.sqlite.
База даних в SQLite представлена класом android.database.sqlite.SQLiteDatabase. Він дозволяє виконувати запити до бази даних, виконувати з нею різні маніпуляції.
Клас android.database.sqlite.SQLiteCursor надає запит і дозволяє повертати набір рядків, які відповідають цьому запиту.
Клас android.database.sqlite.SQLiteQueryBuilder дозволяє створювати SQL-запити.
Самі SQL-вирази представлені класом android.database.sqlite.SQLiteStatement, які дозволяють з допомогою плейсхолдерів вставляти в вирази динамічні дані.
Клас android.database.sqlite.SQLiteOpenHelper дозволяє створити базу даних з усіма таблицями, якщо їх ще не існує.
В SQLite застосовується наступна система типів даних:
INTEGER: представляє ціле число, аналог типуintв JavaREAL: представляє число з плаваючою точкою, аналогfloatтаdoubleв JavaTEXT: представляє набір символів, аналогStringтаcharв JavaBLOB: представляє масив бінарних даних, наприклад, зображення, аналог типуintв Java
Збережені дані повинні відповідати відповідним типам у Java.
Створення та відкриття бази даних
Для створення або відкриття нової бази даних з коду Activity в Android ми можемо викликати метод openOrCreateDatabase(). Цей метод може приймати три параметри:
- назва для бази даних
- числове значення, яке визначає режим роботи (як правило, у вигляді константи
MODE_PRIVATE) - необов'язковий параметр у вигляді об'єкта
SQLiteDatabase.CursorFactory, який представляє фабрику створення курсора для роботи з базою даних
Наприклад, створення бази даних app.db:
SQLiteDatabase db = getBaseContext().openOrCreateDatabase("app.db", MODE_PRIVATE, null);
Для виконання запиту до бази даних можна використовувати метод execSQL класу SQLiteDatabase. В цей метод передається SQL-вираз. Наприклад, створення в базі даних таблиці users:
SQLiteDatabase db = getBaseContext().openOrCreateDatabase("app.db", MODE_PRIVATE, null);
db.execSQL("CREATE TABLE IF NOT EXISTS users (name TEXT, age INTEGER)");
Якщо нам треба не просто виконати вираз, а й отримати з бази даних якісь дані, то використовується метод rawQuery(). Цей метод як параметр приймає SQL-вираз, а також набір значень для виразу SQL. Наприклад, отримання всіх об'єктів з бази даних:
SQLiteDatabase db = getBaseContext().openOrCreateDatabase("app.db", MODE_PRIVATE, null);
db.execSQL("CREATE TABLE IF NOT EXISTS users (name TEXT, age INTEGER)");
Cursor query = db.rawQuery("SELECT * FROM users;", null);
if(query.moveToFirst()){
String name = query.getString(0);
int age = query.getInt(1);
}
Метод db.rawQuery() повертає об'єкт Cursor, за допомогою якого ми можемо витягнути отримані дані.
Можлива ситуація, коли в базі даних не буде об'єктів, і для цього методом query.moveToFirst() намагаємося переміститися до першого об'єкта, отриманого з бази даних. Якщо цей метод поверне значення false, це означає, що запит не отримав жодних даних з бази даних.
Тепер для роботи з базою даних створимо найпростіший додаток. Для цього створимо новий проект.
У файлі activity_main.xml визначимо найпростіший графічний інтерфейс:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp" >
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click"
android:onClick="onClick"
app:layout_constraintBottom_toTopOf="@id/textView"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="22sp"
app:layout_constraintTop_toBottomOf="@id/button"
app:layout_constraintLeft_toLeftOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
А в класі MainActivity визначимо взаємодію з базою даних:
package com.example.sqliteapp;
import androidx.appcompat.app.AppCompatActivity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onClick(View view){
SQLiteDatabase db = getBaseContext().openOrCreateDatabase("app.db", MODE_PRIVATE, null);
db.execSQL("CREATE TABLE IF NOT EXISTS users (name TEXT, age INTEGER, UNIQUE(name))");
db.execSQL("INSERT OR IGNORE INTO users VALUES ('Tom Smith', 23), ('John Dow', 31);");
Cursor query = db.rawQuery("SELECT * FROM users;", null);
TextView textView = findViewById(R.id.textView);
textView.setText("");
while(query.moveToNext()){
String name = query.getString(0);
int age = query.getInt(1);
textView.append("Name: " + name + " Age: " + age + "\n");
}
query.close();
db.close();
}
}
По натисканню на кнопку тут спочатку створюється в базі даних app.db нова таблиця users, а потім в неї додаються два об'єкти в базу даних за допомогою SQL-виразу INSERT.
Далі з допомогою виразу SELECT отримуємо всіх доданих користувачів з бази даних у вигляді курсора Cursor.
Викликом query.moveToNext() переміщаємося в циклі while послідовно по всіх об'єктах.
Для отримання даних з курсора застосовуються методи query.getString(0) та query.getInt(1). У дужках в методи передається номер стовпця, з якого ми отримуємо дані. Наприклад, вище ми додали спочатку ім'я користувача у вигляді рядка, а потім вік у вигляді числа. Тому нульовим стовпцем буде рядкове значення, яке отримуємо за допомогою методу getString(), а наступним - першим стовпцем буде числове значення, для якого застосовується метод getInt().
Після завершення роботи з курсором і базою даних ми закриваємо всі пов'язані об'єкти:
query.close();
db.close();
Якщо ми не закриємо курсор, то можемо зіткнутися з проблемою витоку пам'яті.
І якщо ми звернемося до додатка, то після натискання на кнопку в текстове поле буде виведено додані дані:
