Поделиться через


Использование SQLite.NET с Android

Библиотека SQLite.NET, которую рекомендует Xamarin, является очень простой ORM, которая позволяет легко хранить и извлекать объекты в локальной базе данных SQLite на устройстве Android. ORM означает сопоставление реляционных объектов — API, который позволяет сохранять и извлекать "объекты" из базы данных без написания инструкций SQL.

Чтобы включить библиотеку SQLite.NET в приложение Xamarin, добавьте следующий пакет NuGet в проект:

SQLite.NET NuGet package

Доступно несколько разных пакетов SQLite— обязательно выберите правильный (это может быть не лучший результат поиска).

Внимание

SQLite.NET — это сторонняя библиотека, поддерживаемая репозиторием praeclarum/sqlite-net.

Получив доступ к библиотеке SQLite.NET, выполните следующие три действия, чтобы использовать ее для доступа к базе данных:

  1. Добавьте инструкцию using. Добавьте следующую инструкцию в файлы C#, где требуется доступ к данным:

    using SQLite;
    
  2. Создание пустой базы данных — ссылка на базу данных может быть создана путем передачи пути к файлу конструктора класса SQLite Подключение ion. Если файл уже существует, вам не нужно проверка — он будет автоматически создан при необходимости, в противном случае будет открыт существующий файл базы данных. Переменная dbPath должна быть определена в соответствии с правилами, описанными ранее в этом документе:

    var db = new SQLiteConnection (dbPath);
    
  3. Сохранение данных— после создания объекта SQLite Подключение ion команды базы данных выполняются путем вызова методов, таких как CreateTable и Insert, как показано ниже:

    db.CreateTable<Stock> ();
    db.Insert (newStock); // after creating the newStock object
    
  4. Получение данных — чтобы получить объект (или список объектов), используйте следующий синтаксис:

    var stock = db.Get<Stock>(5); // primary key id of 5
    var stockList = db.Table<Stock>();
    

Пример "Базовый доступ к данным"

Пример кода DataAccess_Basic для этого документа выглядит следующим образом при запуске в Android. В коде показано, как выполнять простые SQLite.NET операции и отображать результаты в виде текста в главном окне приложения.

Android

Android SQLite.NET sample

В следующем примере кода показано все взаимодействие с базой данных с помощью библиотеки SQLite.NET для инкапсулировать доступ к базовой базе данных. В нем показано:

  1. Создание файла базы данных

  2. Вставка некоторых данных путем создания объектов и их сохранения

  3. Запрос данных

Вам потребуется включить эти пространства имен:

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, необходимо использовать следующее решение:

  1. Ссылка на собственную библиотеку 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();
    
  2. В самом начале OnCreate метода добавьте этот код для завершения работы SQLite, настройте его для сериализованного режима и повторно инициализируйте SQLite:

    using using Mono.Data.Sqlite;
    ...
    sqlite3_shutdown();
    SqliteConnection.SetConfig(SQLiteConfig.Serialized);
    sqlite3_initialize();
    

Это решение также работает для библиотеки Mono.Data.Sqlite . Дополнительные сведения о SQLite и нескольких потоках см. в разделе SQLite и нескольких потоков.