Использование SQLite.NET с Android
Библиотека SQLite.NET, которую рекомендует Xamarin, является очень простой ORM, которая позволяет легко хранить и извлекать объекты в локальной базе данных SQLite на устройстве Android. ORM означает сопоставление реляционных объектов — API, который позволяет сохранять и извлекать "объекты" из базы данных без написания инструкций SQL.
Чтобы включить библиотеку SQLite.NET в приложение Xamarin, добавьте следующий пакет NuGet в проект:
- Имя пакета: sqlite-net-pcl
- Автор: Фрэнк А. Крюгер
- Идентификатор: sqlite-net-pcl
- Url: nuget.org/packages/sqlite-net-pcl
Доступно несколько разных пакетов SQLite— обязательно выберите правильный (это может быть не лучший результат поиска).
Внимание
SQLite.NET — это сторонняя библиотека, поддерживаемая репозиторием praeclarum/sqlite-net.
Получив доступ к библиотеке SQLite.NET, выполните следующие три действия, чтобы использовать ее для доступа к базе данных:
Добавьте инструкцию using. Добавьте следующую инструкцию в файлы C#, где требуется доступ к данным:
using SQLite;
Создание пустой базы данных — ссылка на базу данных может быть создана путем передачи пути к файлу конструктора класса SQLiteConnection. Вам не нужно проверять, существует ли файл, он будет автоматически создан при необходимости, в противном случае будет открыт существующий файл базы данных. Переменная
dbPath
должна быть определена в соответствии с правилами, описанными ранее в этом документе:var db = new SQLiteConnection (dbPath);
Сохранение данных — после создания объекта SQLiteConnection команды базы данных выполняются путем вызова методов, таких как CreateTable и Insert, как показано ниже.
db.CreateTable<Stock> (); db.Insert (newStock); // after creating the newStock object
Получение данных — чтобы получить объект (или список объектов), используйте следующий синтаксис:
var stock = db.Get<Stock>(5); // primary key id of 5 var stockList = db.Table<Stock>();
Пример "Базовый доступ к данным"
Пример кода DataAccess_Basic для этого документа выглядит следующим образом при запуске в Android. В коде показано, как выполнять простые SQLite.NET операции и отображать результаты в виде текста в главном окне приложения.
Android
В следующем примере кода показано все взаимодействие с базой данных с помощью библиотеки SQLite.NET для инкапсулировать доступ к базовой базе данных. В нем показано:
Создание файла базы данных
Вставка некоторых данных путем создания объектов и их сохранения
Запрос данных
Вам потребуется включить эти пространства имен:
using SQLite; // from the github SQLite.cs class
Последний требует, чтобы вы добавили SQLite в проект. Обратите внимание, что таблица базы данных SQLite определяется путем добавления атрибутов в класс ( Stock
класс), а не команды CREATE TABLE.
[Table("Items")]
public class Stock {
[PrimaryKey, AutoIncrement, Column("_id")]
public int Id { get; set; }
[MaxLength(8)]
public string Symbol { get; set; }
}
public static void DoSomeDataAccess () {
Console.WriteLine ("Creating database, if it doesn't already exist");
string dbPath = Path.Combine (
Environment.GetFolderPath (Environment.SpecialFolder.Personal),
"ormdemo.db3");
var db = new SQLiteConnection (dbPath);
db.CreateTable<Stock> ();
if (db.Table<Stock> ().Count() == 0) {
// only insert the data if it doesn't already exist
var newStock = new Stock ();
newStock.Symbol = "AAPL";
db.Insert (newStock);
newStock = new Stock ();
newStock.Symbol = "GOOG";
db.Insert (newStock);
newStock = new Stock ();
newStock.Symbol = "MSFT";
db.Insert (newStock);
}
Console.WriteLine("Reading data");
var table = db.Table<Stock> ();
foreach (var s in table) {
Console.WriteLine (s.Id + " " + s.Symbol);
}
}
[Table]
Использование атрибута без указания параметра имени таблицы приведет к тому, что базовая таблица базы данных будет иметь то же имя, что и класс (в данном случае "Stock"). Фактическое имя таблицы важно, если вы записываете SQL-запросы непосредственно в базу данных, а не используете методы доступа к данным ORM. Аналогичным образом [Column("_id")]
атрибут является необязательным, и если столбец отсутствует, он будет добавлен в таблицу с тем же именем, что и свойство в классе.
Атрибуты SQLite
Общие атрибуты, которые можно применить к классам, чтобы управлять тем, как они хранятся в базовой базе данных, включают:
[PrimaryKey] — этот атрибут можно применить к целочисленным свойству, чтобы принудительно использовать его в качестве первичного ключа базовой таблицы. Составные первичные ключи не поддерживаются.
[AutoIncrement] — этот атрибут приведет к автоматическому добавлению значения целочисленного свойства для каждого нового объекта, вставленного в базу данных.
[Столбец(имя)] — параметр
name
задает имя базового столбца базы данных.[Table(name)] — помечает класс как возможность храниться в базовой таблице SQLite с указанным именем.
[MaxLength(value)] — ограничить длину текстового свойства при попытке вставки базы данных. Использование кода должно проверить это перед вставкой объекта, так как этот атрибут проверяется только при попытке вставки или обновления базы данных.
[Игнорировать] — вызывает SQLite.NET игнорировать это свойство. Это особенно полезно для свойств, имеющих тип, который не может храниться в базе данных, или свойства, которые не могут быть разрешены автоматически с помощью SQLite.
[Уникальный] — гарантирует, что значения в базовом столбце базы данных уникальны.
Большинство этих атрибутов являются необязательными. Всегда следует указать целый первичный ключ, чтобы запросы на выбор и удаление могли эффективно выполняться в данных.
Более сложные запросы
Для выполнения других операций с данными можно использовать следующие методы SQLiteConnection
:
Вставка — добавляет новый объект в базу данных.
Получение<T> — пытается получить объект с помощью первичного ключа.
Таблица<T> — возвращает все объекты в таблице.
Delete — удаляет объект с помощью первичного ключа.
Запрос<T> . Выполнение SQL-запроса, возвращающего ряд строк (в виде объектов).
Выполнение — используйте этот метод (и не
Query
), если строки не ожидаются из SQL (например, инструкции INSERT, UPDATE и DELETE).
Получение объекта первичным ключом
SQLite.Net предоставляет метод Get для получения одного объекта на основе его первичного ключа.
var existingItem = db.Get<Stock>(3);
Выбор объекта с помощью Linq
Методы, возвращающие поддержку IEnumerable<T>
коллекций, чтобы использовать Linq для запроса или сортировки содержимого таблицы. В следующем коде показан пример с помощью Linq для фильтрации всех записей, начинающихся с буквы "A":
var apple = from s in db.Table<Stock>()
where s.Symbol.StartsWith ("A")
select s;
Console.WriteLine ("-> " + apple.FirstOrDefault ().Symbol);
Выбор объекта с помощью SQL
Несмотря на то, что SQLite.Net могут предоставлять доступ на основе объектов к данным, иногда может потребоваться выполнить более сложный запрос, чем Linq допускает (или может потребоваться более быстрая производительность). Команды SQL можно использовать с методом query, как показано ниже:
var stocksStartingWithA = db.Query<Stock>("SELECT * FROM Items WHERE Symbol = ?", "A");
foreach (var s in stocksStartingWithA) {
Console.WriteLine ("a " + s.Symbol);
}
Примечание.
При написании инструкций SQL непосредственно создается зависимость от имен таблиц и столбцов в базе данных, созданных из классов и их атрибутов. При изменении этих имен в коде необходимо не забудьте обновить все написанные вручную инструкции SQL.
Удаление объекта
Первичный ключ используется для удаления строки, как показано ниже:
var rowcount = db.Delete<Stock>(someStock.Id); // Id is the primary key
Вы можете проверить rowcount
, сколько строк было затронуты (удалено в этом случае).
Использование SQLite.NET с несколькими потоками
SQLite поддерживает три разных режима потоков: однопотоковый, многопоточный и сериализованный. Если вы хотите получить доступ к базе данных из нескольких потоков без каких-либо ограничений, можно настроить SQLite для использования режима сериализованной потоковой передачи. Важно задать этот режим в начале приложения (например, в начале OnCreate
метода).
Чтобы изменить режим потоковой передачи, вызовите SqliteConnection.SetConfig
. Например, эта строка кода настраивает SQLite для сериализованного режима:
using using Mono.Data.Sqlite;
...
SqliteConnection.SetConfig(SQLiteConfig.Serialized);
В версии Android SQLite есть ограничение, которое требует выполнения нескольких действий. Если вызов создает SqliteConnection.SetConfig
исключение SQLite, например library used incorrectly
, необходимо использовать следующее решение:
Ссылка на собственную библиотеку libsqlite.so таким образом, чтобы
sqlite3_shutdown
api иsqlite3_initialize
интерфейсы API были доступны для приложения:[DllImport("libsqlite.so")] internal static extern int sqlite3_shutdown(); [DllImport("libsqlite.so")] internal static extern int sqlite3_initialize();
В самом начале
OnCreate
метода добавьте этот код для завершения работы SQLite, настройте его для сериализованного режима и повторно инициализируйте SQLite:using using Mono.Data.Sqlite; ... sqlite3_shutdown(); SqliteConnection.SetConfig(SQLiteConfig.Serialized); sqlite3_initialize();
Это решение также работает для библиотеки Mono.Data.Sqlite
. Дополнительные сведения о SQLite и нескольких потоках см. в разделе SQLite и нескольких потоков.