Збереження даних в базі даних ідеально підходить для структурованих або повторюваних даних, наприклад, контактної інформації. Даний урок припускає, що ви знайомі з базами даних SQL в цілому і допоможе почати роботу з базами даних SQLite на Android.
API-інтерфейси, які треба буде використовувати з базами даних на Android доступні в пакеті android.database.sqlite.
Визначення Schema та Contract
Одним з основних принципів баз даних SQL є schema: офіційна заява про те, як організована база даних. Schema відображається у звітності SQL, яку ви використовуєте для створення бази даних. Ви можете знайти це корисним для створення класу компаньйона, відомого як клас contract, який явно вказує розташування вашої schema систематичним і само-документованим чином.
Клас contract служить контейнером для констант, які визначають імена для URI, таблиць і стовпців. Клас contract дозволяє використовувати одні й ті ж константи в усіх інших класах в одному пакеті. Це дозволяє змінити ім'я стовпця в одному місці і зміна пошириться по всьому вашому коду.
Хороший спосіб організувати клас contract, це зробити визначення, які є глобальними для всієї бази даних, в корені класу. Потім створити внутрішній клас для кожної таблиці, яка перераховує свої колонки.
Примітка: При реалізації інтерфейсу BaseColumns ваш внутрішній клас може успадковувати поля первинного ключа під назвою _ID, тому деякі класи Android, такі як адаптери курсору, будуть чекати, щоб його отримати. Це не обов'язково, але може допомогти вашій базі даних гармонійно працювати з фреймворком Android.
Приклад фрагменту, який визначає ім’я таблиці та імена стовпців для однієї таблиці:
public final class FeedReaderContract {
// Щоб забобігти чомусь з випадковим екземпляром класу contract,
// дамо йому порожній конструктор.
public FeedReaderContract() {}
/* Внутрішній клас, який визначає вміст таблиці */
public static abstract class FeedEntry implements BaseColumns {
public static final String TABLE_NAME = "entry";
public static final String COLUMN_NAME_ENTRY_ID = "entryid";
public static final String COLUMN_NAME_TITLE = "title";
public static final String COLUMN_NAME_SUBTITLE = "subtitle";
...
}
}
Створення бази даних з використанням SQL Helper
Після того, як визначили, як виглядає ваша база даних, необхідно реалізувати методи, які створюють і підтримують бази даних і таблиць. Ось деякі типові визначення для створення і видалення таблиці:
private static final String TEXT_TYPE = " TEXT";
private static final String COMMA_SEP = ",";
private static final String SQL_CREATE_ENTRIES =
"CREATE TABLE " + FeedEntry.TABLE_NAME + " (" +
FeedEntry._ID + " INTEGER PRIMARY KEY," +
FeedEntry.COLUMN_NAME_ENTRY_ID + TEXT_TYPE + COMMA_SEP +
FeedEntry.COLUMN_NAME_TITLE + TEXT_TYPE + COMMA_SEP +
... // будь-які інші варіанти для команди CREATE
" )";
private static final String SQL_DELETE_ENTRIES =
"DROP TABLE IF EXISTS " + FeedEntry.TABLE_NAME;
Так само, як файли, які ви зберігаєте на внутрішньому сховищі пристрою, Android зберігає бази даних на приватному дисковому просторі, який пов'язаний з додатком. Дані будуть в безпеці, тому що за замовчуванням ця ділянка не доступна для інших додатків.
Корисний набір API, доступний в класі SQLiteOpenHelper. Коли використовуєте цей клас, щоб отримати посилання на бази даних, система виконує потенційно тривалі операції створення та оновлення бази даних тільки при необхідності, а не під час запуску додатку. Все, що вам потрібно зробити, це викликати getWritableDatabase() або getReadableDatabase().
Примітка: Тому, що вони можуть бути тривалими, переконайтеся, що викликаєте getWritableDatabase() або getReadableDatabase() у фоновому потоці, наприклад, з AsyncTask або IntentService.
Щоб використовувати SQLiteOpenHelper, створіть підклас, який перекриває методи зворотного виклику onCreate(), onUpgrade() і onOpen(). Ви також можете здійснити onDowngrade(), але це не обов'язково.
Приклад реалізації SQLiteOpenHelper, який використовує деякі з команд, показаних вище:
public class FeedReaderDbHelper extends SQLiteOpenHelper {
// Якщо ви зміните schema бази даних, то треба збільшити версію бази даних.
public static final int DATABASE_VERSION = 1;
public static final String DATABASE_NAME = "FeedReader.db";
public FeedReaderDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public void onCreate(SQLiteDatabase db) {
db.execSQL(SQL_CREATE_ENTRIES);
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Дана база даних лише кешує дані інтернету, тому її оновлена політика
// є просто відкинути дані і почати
db.execSQL(SQL_DELETE_ENTRIES);
onCreate(db);
}
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
onUpgrade(db, oldVersion, newVersion);
}
}
Щоб отримати доступ до бази даних, створіть екземпляр підкласу SQLiteOpenHelper:
FeedReaderDbHelper mDbHelper = new FeedReaderDbHelper(getContext());
Розміщення інформації в базі даних
Вставка даних в базу даних здійснюється передаванням об'єкта ContentValues в метод insert():
// Отримуємо сховище даних в режимі запису
SQLiteDatabase db = mDbHelper.getWritableDatabase();
// Створюємо нову карту значень, в якій імена стовпців є ключами
ContentValues values = new ContentValues();
values.put(FeedEntry.COLUMN_NAME_ENTRY_ID, id);
values.put(FeedEntry.COLUMN_NAME_TITLE, title);
values.put(FeedEntry.COLUMN_NAME_CONTENT, content);
// Вставте новий рядок, повертаючи значення первинного ключа нового рядка
long newRowId;
newRowId = db.insert(
FeedEntry.TABLE_NAME,
FeedEntry.COLUMN_NAME_NULLABLE,
values);
Перший аргумент для insert() є просто ім'я таблиці. Другий аргумент містить ім'я стовпця, в якому фреймворк можете вставити NULL у випадку, якщо ContentValues порожнє (якщо ви вставляєте "null", то фреймворк не буде вставляти рядок, коли немає значення).
Читання інформації з бази даних
Щоб прочитати з бази даних, використайте метод query(), передавши йому свої критерії відбору та потрібні стовпці. Метод поєднує в собі елементи insert() і update(), за винятком списку стовпців, визначаючи дані, які хочете отримати, а не дані для вставки. Результати запиту повертаються в об'єкті Cursor:
SQLiteDatabase db = mDbHelper.getReadableDatabase();
// Визначте проекцію, яка задає, які стовпчики з бази даних
// ви насправді використаєте після цього запиту.
String[] projection = {
FeedEntry._ID,
FeedEntry.COLUMN_NAME_TITLE,
FeedEntry.COLUMN_NAME_UPDATED,
...
};
// Як ви хочете сортувати результати в результуючому Cursor
String sortOrder =
FeedEntry.COLUMN_NAME_UPDATED + " DESC";
Cursor c = db.query(
FeedEntry.TABLE_NAME, // Таблиця для запиту
projection, // Колонки, що повертаються
selection, // Колонки для пункту WHERE
selectionArgs, // Значення для пункту WHERE
null, // не групувати рядки
null, // не фільтрувати групи рядків
sortOrder // Сортування
);
Щоб подивитися на рядок у cursor, використовуйте один з методів кроку Cursor, який ви повинні завжди викликати, перш ніж почати читати значення. Як правило, ви повинні почати з виклику moveToFirst(), який поміщає "положення читання" на перший запис в результатах. Для кожного рядка можете прочитати значення стовпця, викликавши один з методів get Cursor, таких як getString() або getLong(). Для кожного з методів get ви повинні пройти позицію індексу стовпця, який бажаєте, яку можете отримати, викликавши getColumnIndex() або getColumnIndexOrThrow(). Наприклад:
cursor.moveToFirst();
long itemId = cursor.getLong(
cursor.getColumnIndexOrThrow(FeedEntry._ID)
);
Видалення інформації з бази даних
Для видалення рядків з таблиці необхідно надати критерії відбору, які ідентифікують рядки. API бази даних надає механізм для створення критеріїв відбору, який захищає від ін'єкції SQL. Механізм ділить специфікацію вибору на вибір пункту і вибір аргументів. Пункт визначає стовпці для перегляду, а також дозволяє об'єднати тести стовпців. Аргументи – це значення для перевірки того, з чим пов'язані в пункті. Тому, що результат не обробляється так само, як звичайне визначення SQL, це буде імунітетом до ін'єкції SQL.
// Визначити 'where' частину запиту.
String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + " LIKE ?";
// Вкажіть аргументи в порядку заповнювача.
String[] selectionArgs = { String.valueOf(rowId) };
// Випуск SQL оголошення.
db.delete(table_name, selection, selectionArgs);
Оновлення бази даних
Якщо вам необхідно змінити підмножину значень бази даних, використайте метод update().
Оновлення таблиці поєднує синтаксис значення змісту insert() з синтаксисом where delete().
SQLiteDatabase db = mDbHelper.getReadableDatabase();
// Нове значення для одного стовпця
ContentValues values = new ContentValues();
values.put(FeedEntry.COLUMN_NAME_TITLE, title);
// Який ряд оновити, базуючись на ID
String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + " LIKE ?";
String[] selectionArgs = { String.valueOf(rowId) };
int count = db.update(
FeedReaderDbHelper.FeedEntry.TABLE_NAME,
values,
selection,
selectionArgs);
(Джерело: developer.android.com)