SQLite no Ionic com ngCordova Artigo

Conheça os cursos gratuitos do WebDevBr! - Inscreva-se!


Este artigo foi publicado a 1 ano, 7 meses, 1 semana atrás.

SQLite é um banco de dados leve, simples e muito usado no mundo backend e também pode ser usado no Ionic.

A grande questão é que o Ionic já nos da acesso a LocalStorage que é muitas vezes mais simples de usar do que SQL, além de não precisar configurar nada. Mas ele tem um limite de 5mb de espaço, confesso que não é fácil escrever 5mb de texto e em muitos casos isso vai ser suficiente, porém apenas em aplicações que não precisarem guardar muitos dados no celular.

Trocando em miúdos, LocalStorage tem (obviamente) um melhor desempenho e vai funcionar melhor para situações simples, enquanto para estruturas de dados mais complicadas o SQLite vai te ajudar muito mais, com certeza.

Gostou deste artigo?

Receba atualizações semanais com novos artigos do WebDevBr e outras dicas!

Existem outros pontos (a incapacidade de backup do LocalStorage, por exemplo), mas vou acabar fugindo da ideia de um artigo prático. Teste você mesmo.

Pra começar vamos criar um novo aplicativo Ionic, vou usar o tabs.

    ionic start sqlite tabs
    cd sqlite
    ionic platform add android

Instalando o plugin de SQLite do Cordova

Como disse antes, vou usar um plugin do Cordova, vamos precisar de duas coisas:

  1. O plugin
  2. O ngCordova

O ngCordova é um modulo para o AngularJs que empacota os recursos do Cordova para o Ionic.

    ionic plugin  add https://github.com/brodysoft/Cordova-SQLitePlugin.git
    bower install ngCordova --save

Pronto, o primeiro comando instala o plugin e o segundo baixa o ngCordova para dentro do diretório www/lib/ngCordova/.

Para finalizar apenas carregue o ngCordova no index.html:

    <script src="lib/ionic/js/ionic.bundle.js"></script>
<script src="lib/ngCordova/dist/ng-cordova.js"></script> <!-- aqui o ngCordova -->

<!-- cordova script (this will be a 404 during development) -->
<script src="cordova.js"></script>

<!-- your app's js -->
<script src="js/sqlite.js"></script> <!-- aproveite e crie este arquivi -->
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="js/services.js"></script>

Quero que você note duas coisas, eu inclui o ngCordova (<script src="lib/ngCordova/dist/ng-cordova.js"></script>) e também um js/sqlite, este último será aonde vou fazer nossa mágica.

Criando o banco de dados

Criar um banco de dados é uma tarefa simples, tudo o que você precisa é de uma instancia do $cordovaSQLite e duas linhas:

db = $cordovaSQLite.openDB("my.db");
$cordovaSQLite.execute(db, "CREATE TABLE IF NOT EXISTS chats (id integer primary key, firstname varchar(10), lastname varchar(10), avatar text, message text)");

O $cordovaSQLite.execute() aceita três parâmetros, o primeiro é o banco de dados que vamos usar, o segundo é a query a ser executada (no exemplo eu criei uma tabela), o terceiro (e opcional) é um array com as informações a serem injetadas (para evitar sql injection). Ainda vamos ver isso mais explicito.

Neste exemplo, vou abrir o arquivo js/sqlite.js e incluir o seguinte código:

var db = null;
var sqlite = angular.module('sqlite', ['ionic', 'ngCordova']);

sqlite.run(function($ionicPlatform, $cordovaSQLite) {
  $ionicPlatform.ready(function() {
    db = $cordovaSQLite.openDB("my.db");
    $cordovaSQLite.execute(db, "CREATE TABLE IF NOT EXISTS chats (id integer primary key, firstname varchar(10), lastname varchar(10), avatar text, message text)");
  });
});

O imporante aqui é que eu iniciei a variável db fora do módulo, assim eu tenho acesso em outros lugares, também verifique se o Ionic está pronto antes de criar o banco de dados, isso evita erros, note que na criação do módulo eu injetei o ngCordova e na abertura do run o $cordovaSQLite.

Simples, né.

Se for criar muitos módulos e muitas tabelas, concidere fazer isso dentro do run do app.js.

Executando queries do SQLite no ngCordova

Pra começar vou criar um factory com a estrutura que preciso, mas vazio:

sqlite.factory('chatsFactory', function($cordovaSQLite) {
  return {
    insert : function(){},
    select : function(){}
  }
});

Olha o $cordovaSQLite ali de novo.

Não temos nenhum registro ainda, então vou começar com o insert, acerte o item inserte do factory para ficar assim:

insert : function(firstname, lastname, avatar, message) {
  var query = "INSERT INTO chats (firstname, lastname, avatar, message) VALUES (?, ?, ?, ?);";
  var values = [firstname, lastname, avatar, message];

  $cordovaSQLite.execute(db, query, values).then(
    function(res) {
      console.log('INSERTED ID: '+res.insertId);
    },
    function(err) {
      console.log('ERROR: '+err);
    }
  );
}

Agora ficou claro? Da pra rodar qualquer SQL agora, né?

Note que o execute() retorna um promise e eu uso o them() para setar o que acontece em caso de sucesso ou falha.

Acredito que neste ponto você seja capaz de criar qualquer query que quiser, mas eu vou dar outro exemplo, o do select.

select : function(id) {
  var query = "SELECT * FROM chats WHERE id=?";
  var values = [id];

  $cordovaSQLite.execute(db, query, values).then(
    function(res) {
      if (res.rows.length > 0) {
        var first = res.rows.item(0);
        console.log(res.rows.length + ' records, fist: ' + first.firstname + ' ' + first.lastname + ' - ' + first.avatar);
      } else {
        console.log('No records found');
      }
    }
  );
}

Quando eu trago dados com select eles vem dentro de res.rows, você pode usar o length do javascript para verificar se realmente encontramos algum registro. Cada registro pode ser acessado usando o .item(n), onde n é a chave do item (no exemplo usei res.rows.item(0) para pegar o primeiro e único registro), você pode usar um loop para percorrer todos os registros.

O nosso sqlite.js completo ficou assim:

var db = null;
var sqlite = angular.module('sqlite', ['ionic', 'ngCordova']);

sqlite.run(function($ionicPlatform, $cordovaSQLite) {
  $ionicPlatform.ready(function() {
    db = $cordovaSQLite.openDB("my.db");
    $cordovaSQLite.execute(db, "CREATE TABLE IF NOT EXISTS chats (id integer primary key, firstname varchar(10), lastname varchar(10), avatar text, message text)");
  });
});

sqlite.factory('chatsFactory', function($cordovaSQLite) {
  return {
    insert : function(firstname, lastname, avatar, message) {
      var query = "INSERT INTO chats (firstname, lastname, avatar, message) VALUES (?, ?, ?, ?);";
      var values = [firstname, lastname, avatar, message];

      $cordovaSQLite.execute(db, query, values).then(
        function(res) {
          console.log('INSERTED ID: '+res.insertId);
        },
        function(err) {
          console.log('ERROR: '+err);
        }
      );
    },
    select : function(id) {
      var query = "SELECT * FROM chats WHERE id=?";
      var values = [id];

      $cordovaSQLite.execute(db, query, values).then(
        function(res) {
          if (res.rows.length > 0) {
            var first = res.rows.item(0);
            console.log(res.rows.length + ' records, fist: ' + first.firstname + ' ' + first.lastname + ' - ' + first.avatar);
          } else {
            console.log('No records found');
          }
        }
      );
    }
  }
});

Testando

Antes de qualquer coisa precisamos injetar nosso módulo sqlite (que criamos acima) no app.js:

    angular.module('starter', ['ionic', 'starter.controllers', 'starter.services', 'sqlite'])

Viu? O último item.

Agora abra o arquivo em www/js/controllers.js e deixe seu ChatsCtrl assim:

.controller('ChatsCtrl', function($scope, Chats, chatsFactory) {

        //cadastro dois registros
  chatsFactory.insert('Erik', 'Figueiredo', 'adam.jpg', 'Hello Brazil!');
  chatsFactory.insert('Leticia', 'Figueiredo', 'max.jpg', 'Another hello!');

        //retorno dois registros
  chatsFactory.select(1);
  chatsFactory.select(2);
  $scope.chats = Chats.all();
  $scope.remove = function(chat) {
    Chats.remove(chat);
  };
})

Uma dica importante é que isso não rola no navegador, você vai ter que testar com emulador ou no celular.

Removendo um banco de dados.

Só para completar, se quiser remover um banco de dados completamente, use:

    $cordovaSQLite.deleteDB("my.db");

Conclusão

SQLite é uma boa opção para armazenamento de dados locais (no celular) e com certeza você vai encontrar muitas utilidades para ele durante o desenvolvimento da sua aplicação.

Exemplo completo - em breve

E aqui meu curso de Ionic


Cursos relacionados


* Parcelamento apenas cartão de crédito! Pode haver uma pequena variação no parcelamento em relação a simulações apresentadas!