Compartilhar via


Como usar o SQLite.NET com o Android

A biblioteca SQLite.NET que o Xamarin recomenda é um ORM muito básico que permite armazenar e recuperar facilmente objetos no banco de dados SQLite local em um dispositivo Android. ORM significa Object Relational Mapping – uma API que permite salvar e recuperar "objetos" de um banco de dados sem escrever instruções SQL.

Para incluir a biblioteca SQLite.NET em um aplicativo Xamarin, adicione o seguinte pacote NuGet ao seu projeto:

SQLite.NET pacote NuGet

Existem vários pacotes SQLite diferentes disponíveis – certifique-se de escolher o correto (pode não ser o principal resultado na pesquisa).

Importante

O SQLite.NET é uma biblioteca de terceiros com suporte do repositório praeclarum/sqlite-net.

Depois de ter a biblioteca SQLite.NET disponível, siga estas três etapas para usá-la para acessar um banco de dados:

  1. Adicionar uma instrução using – Adicione a seguinte instrução aos arquivos C# em que o acesso a dados é necessário:

    using SQLite;
    
  2. Criar um banco de dados em branco – uma referência de banco de dados pode ser criada passando o caminho do arquivo para o construtor de classe SQLiteConnection. Você não precisa verificar se o arquivo já existe – ele será criado automaticamente, se necessário, caso contrário, o arquivo de banco de dados existente será aberto. A dbPath variável deve ser determinada de acordo com as regras discutidas anteriormente neste documento:

    var db = new SQLiteConnection (dbPath);
    
  3. Salvar dados – Depois de criar um objeto SQLiteConnection, os comandos do banco de dados são executados chamando seus métodos, como CreateTable e Insert assim:

    db.CreateTable<Stock> ();
    db.Insert (newStock); // after creating the newStock object
    
  4. Recuperar dados – Para recuperar um objeto (ou uma lista de objetos), use a seguinte sintaxe:

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

Exemplo de acesso a dados básicos

O código de exemplo DataAccess_Basic para este documento tem esta aparência quando executado no Android. O código ilustra como executar operações SQLite.NET simples e mostra os resultados como texto na janela principal do aplicativo.

Android

Exemplo de SQLite.NET Android

O exemplo de código a seguir mostra uma interação de banco de dados inteira usando a biblioteca SQLite.NET para encapsular o acesso ao banco de dados subjacente. Ele mostra:

  1. Criando o arquivo de banco de dados

  2. Inserindo alguns dados criando objetos e salvando-os

  3. Consulta dos dados

Você precisará incluir estes namespaces:

using SQLite; // from the github SQLite.cs class

O último requer que você tenha adicionado SQLite ao seu projeto. Observe que a tabela do banco de dados SQLite é definida pela adição de atributos a uma classe (a Stock classe) em vez de um comando 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);
    }
}

Usar o [Table] atributo sem especificar um parâmetro de nome de tabela fará com que a tabela de banco de dados subjacente tenha o mesmo nome que a classe (nesse caso, "Stock"). O nome real da tabela é importante se você escrever consultas SQL diretamente no banco de dados, em vez de usar os métodos de acesso a dados ORM. Da mesma forma, o [Column("_id")] atributo é opcional e, se ausente, uma coluna será adicionada à tabela com o mesmo nome da propriedade na classe.

Atributos SQLite

Os atributos comuns que você pode aplicar às suas classes para controlar como elas são armazenadas no banco de dados subjacente incluem:

  • [Chave Primária] – Este atributo pode ser aplicado a uma propriedade inteira para forçá-la a ser a chave primária da tabela subjacente. Não há suporte para chaves primárias compostas.

  • [AutoIncremento] – Este atributo fará com que o valor de uma propriedade inteira seja incrementado automaticamente para cada novo objeto inserido no banco de dados

  • [Coluna(nome)] – O name parâmetro define o nome da coluna do banco de dados subjacente.

  • [Tabela (nome)] – Marca a classe como podendo ser armazenada em uma tabela SQLite subjacente com o nome especificado.

  • [MaxLength(valor)] – Restringir o comprimento de uma propriedade de texto, quando uma inserção de banco de dados é tentada. O consumo de código deve validar isso antes de inserir o objeto, pois esse atributo só é 'verificado' quando uma operação de inserção ou atualização de banco de dados é tentada.

  • [Ignorar] – Faz com que SQLite.NET ignore essa propriedade. Isso é particularmente útil para propriedades que têm um tipo que não pode ser armazenado no banco de dados ou propriedades que modelam coleções que não podem ser resolvidas automaticamente pelo SQLite.

  • [Único] – Garante que os valores na coluna do banco de dados subjacente sejam exclusivos.

A maioria desses atributos é opcional. Você deve sempre especificar uma chave primária inteira para que as consultas de seleção e exclusão possam ser executadas com eficiência em seus dados.

Consultas mais complexas

Os seguintes métodos podem SQLiteConnection ser usados para executar outras operações de dados:

  • Inserir – Adiciona um novo objeto ao banco de dados.

  • Get<T> – Tenta recuperar um objeto usando a chave primária.

  • Tabela<T> – Retorna todos os objetos na tabela.

  • Excluir – Exclui um objeto usando sua chave primária.

  • Consulta<T> – Execute uma consulta SQL que retorna várias linhas (como objetos).

  • Executar – Use esse método (e não Query) quando não esperar linhas de volta do SQL (como instruções INSERT, UPDATE e DELETE).

Obtendo um objeto pela chave primária

SQLite.Net fornece o método Get para recuperar um único objeto com base em sua chave primária.

var existingItem = db.Get<Stock>(3);

Selecionando um objeto usando Linq

Os métodos que retornam coleções dão suporte IEnumerable<T> para que você possa usar o Linq para consultar ou classificar o conteúdo de uma tabela. O código a seguir mostra um exemplo usando o Linq para filtrar todas as entradas que começam com a letra "A":

var apple = from s in db.Table<Stock>()
    where s.Symbol.StartsWith ("A")
    select s;
Console.WriteLine ("-> " + apple.FirstOrDefault ().Symbol);

Selecionando um objeto usando SQL

Embora SQLite.Net possa fornecer acesso baseado em objeto aos seus dados, às vezes você pode precisar fazer uma consulta mais complexa do que o Linq permite (ou pode precisar de um desempenho mais rápido). Você pode usar comandos SQL com o método Query, conforme mostrado aqui:

var stocksStartingWithA = db.Query<Stock>("SELECT * FROM Items WHERE Symbol = ?", "A");
foreach (var s in stocksStartingWithA) {
    Console.WriteLine ("a " + s.Symbol);
}

Observação

Ao escrever instruções SQL diretamente, você cria uma dependência dos nomes de tabelas e colunas em seu banco de dados, que foram gerados a partir de suas classes e seus atributos. Se você alterar esses nomes em seu código, lembre-se de atualizar todas as instruções SQL escritas manualmente.

Excluindo um objeto

A chave primária é usada para excluir a linha, conforme mostrado aqui:

var rowcount = db.Delete<Stock>(someStock.Id); // Id is the primary key

Você pode verificar o rowcount para confirmar quantas linhas foram afetadas (excluídas neste caso).

Usando SQLite.NET com vários threads

O SQLite dá suporte a três modos de threading diferentes: Single-thread, Multi-thread e Serialized. Se você quiser acessar o banco de dados de vários threads sem restrições, poderá configurar o SQLite para usar o modo de threading serializado . É importante definir esse modo no início do aplicativo (por exemplo, no início do OnCreate método).

Para alterar o modo de threading, chame SqliteConnection.SetConfig. Por exemplo, esta linha de código configura o SQLite para o modo Serializado :

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

A versão Android do SQLite tem uma limitação que requer mais algumas etapas. Se a chamada para SqliteConnection.SetConfig produzir uma exceção SQLite, como library used incorrectly, você deverá usar a seguinte solução alternativa:

  1. Link para a biblioteca nativa do libsqlite.so para que as sqlite3_shutdown APIs e sqlite3_initialize sejam disponibilizadas para o aplicativo:

    [DllImport("libsqlite.so")]
    internal static extern int sqlite3_shutdown();
    
    [DllImport("libsqlite.so")]
    internal static extern int sqlite3_initialize();
    
  2. No início do método, adicione este código para desligar o SQLite, configure-o para o modo Serializado e reinicialize o OnCreate SQLite:

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

Essa solução alternativa também funciona para a Mono.Data.Sqlite biblioteca. Para obter mais informações sobre SQLite e multithreading, consulte SQLite e vários threads.