Armazenar dados localmente e persistir entre inicializações de aplicativos é um dos conceitos fundamentais de qualquer processo de desenvolvimento de aplicativo móvel. Quase todos os aplicativos exigem que você lide com dados-desde o armazenamento de informações do cliente para um aplicativo de entrega de comida, até o número de pontos marcados em um jogo ou um valor simples para saber se o usuário ativou o modo escuro durante sua última visita.
O Flutter oferece muitas opções de persistência de dados locais para os desenvolvedores escolherem. shared_preferences é um bom pacote para armazenar pequenos pares de valores-chave localmente e sqflite , o pacote SQLite para Flutter, é uma boa escolha quando você está lidando com dados relacionais fortes que exigem que você lide com relacionamentos complexos no banco de dados.
Mas se você quiser um banco de dados local rápido e seguro, sem dependências nativas, que também seja executado na web Flutter (), então Hive é uma escolha muito boa.
Neste artigo, você aprenderá como começar a usar o Hive antes de construirmos um aplicativo simples usando o Flutter. Também examinaremos um conceito que permite que você lide com dados relacionais simples no Hive.
Por que o Hive?
Vamos primeiro dar uma olhada em por que você deve escolher o Hive em vez de outras soluções disponível para dados persistentes localmente no Flutter.
O Hive é uma solução de banco de dados de valor-chave leve e rápida que é multiplataforma (roda em dispositivos móveis, desktop e web) e é escrita em Dart puro. Isso dá a ele uma vantagem instantânea sobre o sqflite, que não oferece suporte ao Flutter web-o Hive não tem dependências nativas, por isso funciona perfeitamente na web.
Abaixo está um gráfico que compara o Hive com outras soluções de banco de dados semelhantes:
Este é um benchmark de 1000 operações de leitura e gravação realizadas em um dispositivo Oneplus 6T com Android Q. Você pode aprender mais sobre este benchmark em GitHub do Hive .
O Hive também permite que você armazene classes personalizadas usando TypeAdapters . Vamos olhar para isso em mais detalhes posteriormente neste artigo.
Introdução ao Hive
Vamos construir um aplicativo básico onde os detalhes de nossos usuários são armazenados e onde adicionar, ler, atualizar e excluir operações nos dados podem ser realizadas.
Crie um novo projeto Flutter usando o seguinte comando:
flutter create hive_demo
Você pode abrir o projeto usando seu IDE favorito, mas para este exemplo, estarei usando o código VS:
code hive_demo
Adicione o Hive e hive_flutter para seu arquivo pubspec.yaml:
dependencies: hive: ^ 2.0.4 hive_flutter: ^ 1.1.0
Substitua o conteúdo do seu arquivo main.dart pelo seguinte:
importar’pacote: flutter/material.dart’; main () {runApp (MyApp ()); } class MyApp extends StatelessWidget {@override Widget build (BuildContext context) {return MaterialApp (title:’Hive Demo’, theme: ThemeData (primarySwatch: Colors.purple,), debugShowCheckedModeBanner: false, home: InfoScreen (),); }}
O InfoScreen exibirá os detalhes do usuário-nós o examinaremos em um momento. Antes disso, vamos entender um conceito importante usado pelo Hive.
Compreendendo as caixas
O Hive usa o conceito de “caixas” para armazenar dados no banco de dados. Uma caixa é semelhante a uma tabela em um banco de dados SQL, exceto que as caixas não possuem uma estrutura rígida. Isso significa que as caixas são flexíveis e podem lidar apenas com relacionamentos simples entre os dados.
Cobriremos apenas a caixa Hive típica neste tutorial, mas vale a pena mencionar que você pode criar caixas preguiçosas e caixas criptografadas também.
Inicializar Hive
Antes de passar para as operações CRUD do banco de dados, você deve inicializar o Hive e abrir uma caixa que irá ser usado para armazenar os dados.
O Hive deve ser inicializado antes de carregarmos qualquer caixa, então é melhor inicializá-lo dentro da função main () do seu aplicativo Flutter para evitar erros. Observe que se você estiver usando o Hive em um aplicativo Dart puro e não Flutter, deverá usar Hive.init () para inicializar o Hive.
main () async {//Initialize hive await Hive.initFlutter (); runApp (MyApp ()); }
Torne a função principal assíncrona e use await para inicializar o Hive.
Agora, você precisa abrir uma caixa do Hive. Se você planeja usar várias caixas em seu projeto, observe que deve abrir uma caixa antes de usá-la.
Neste aplicativo, usaremos uma única caixa que abriremos logo após o Hive concluir a inicialização.
main () async {//Inicializar hive await Hive.initFlutter ();//Abra o peopleBox await Hive.openBox (‘peopleBox’); runApp (MyApp ()); }
Agora estamos prontos para executar operações CRUD no banco de dados local.
Executando operações CRUD
Definiremos as operações CRUD básicas no InfoScreen StatefulWidget. A estrutura desta classe será a seguinte:
import’package: flutter/material.dart’; import’package: hive/hive.dart’; classe InfoScreen estende StatefulWidget {@override _InfoScreenState createState ()=> _InfoScreenState (); } a classe _InfoScreenState estende o estado
Primeiro, recuperamos uma referência à caixa dentro do método initState () que abrimos anteriormente. Você deve sempre fechar as caixas abertas após terminar de usá-las e antes de fechar o aplicativo.
Como atualmente exigimos apenas a caixa dentro deste widget, podemos fechar a caixa dentro do método dispose () deste classe.
Vamos criar alguns métodos para realizar as operações CRUD.
class _InfoScreenState extends State
Agora construiremos uma IU muito básica para que possamos testar se as operações estão funcionando corretamente ou não.
class _InfoScreenState extends State
O aplicativo terá a seguinte aparência:
Armazenamento de dados
Se precisar armazenar dados, você pode usar a referência para a caixa Hive e chamar coloque () nele. Este método aceita um par de valores-chave.
//Adicionar informações à caixa de pessoas _addInfo () async {//Armazenando o par de valores-chave box.put (‘nome’,’John’); box.put (‘país’,’Itália’); imprimir (‘Informações adicionadas à caixa!’); }
Aqui, armazenamos dois pares de valores-chave, o Nome da pessoa e seu País de residência .
O Hive também oferece suporte a inteiros chaves, para que você possa usar as chaves de incremento automático. Isso pode ser útil se você estiver armazenando vários valores (meio semelhante a uma lista) e quiser recuperá-los por seus índices. Você pode armazenar assim:
box.add (‘Linda’);//índice 0, chave 0 box.add (‘Dan’);//índice 1, chave 1
Recuperando dados
Para ler dados, você pode usar o método get () no objeto box. Você só precisa fornecer a chave para recuperar seu valor.
//Ler informações da caixa de pessoas _getInfo () {var name=box.get (‘nome’); var country=box.get (‘country’); print (‘Informações obtidas na caixa: $ name ($ country)’); }
Se estiver usando valores de incremento automático, você pode ler usando o índice, como este:
box.getAt (0);//recupera o valor com índice 0 box.getAt (1);//recupera o valor com o índice 1
Atualizando dados
Para atualizar os dados de uma chave específica, você pode usar o mesmo método put () que você usou originalmente para armazenar o valor. Isso atualizará o valor presente nessa chave com o valor fornecido recentemente.
//Atualizar informações da caixa de pessoas _updateInfo () {box.put (‘nome’,’Mike’); box.put (‘país’,’Estados Unidos’); imprimir (‘Informações atualizadas na caixa!’); }
Se você estiver usando valores de incremento automático, poderá usar o método putAt () para atualizar o valor presente em um índice específico.
box.putAt (0,’Jenifer’);
Excluindo dados
Para excluir dados, você pode usar o método delete () fornecendo a chave.
//Excluir informações da caixa de pessoas _deleteInfo () {box.delete (‘nome’); box.delete (‘país’); imprimir (‘Informações excluídas da caixa!’); }
Isso excluirá os valores presentes nessas chaves específicas. Agora, se você tentar chamar o método get () usando essas chaves, ele retornará valores nulos.
Se você estiver usando valores de incremento automático, poderá usar o método deleteAt () fornecendo o índice.
box.deleteAt (0);
Usando objetos personalizados com TypeAdapter
Em geral, o Hive oferece suporte a todos os tipos primitivos, como List, Map, DateTime e Uint8List. Mas às vezes você pode precisar armazenar classes de modelo personalizadas que tornam o gerenciamento de dados mais fácil.
Para fazer isso, você pode aproveitar as vantagens de um TypeAdapter, que gera os métodos binários de e para.
TypeAdapters podem ser escritos manualmente ou gerados automaticamente. É sempre melhor usar a geração de código para gerar os métodos necessários porque ajuda a evitar quaisquer erros que possam ocorrer durante a escrita manual (e também é mais rápido).
A classe de modelo que usaremos para armazenar Os dados pessoais são os seguintes:
class Person {final String name; país final da string; Pessoa ({this.name obrigatório, this.country obrigatório,}); }
Gerando o adaptador Hive
Você precisará adicionar algumas dependências para gerar o TypeAdapter para Hive. Adicione o seguinte ao seu arquivo pubspec.yaml:
dev_dependencies: hive_generator: ^ 1.1.0 build_runner: ^ 2.0.6
Anote a classe do modelo para usar a geração de código:
import’package: hive/hive.dart’; parte’people.g.dart’; @HiveType (typeId: 1) class People {@HiveField (0) final String name; @HiveField (1) país final da string; Pessoas ({this.name obrigatório, this.country obrigatório,}); }
Você pode então acionar a geração de código usando o seguinte comando:
flutter packages pub run build_runner build
Registrando o TypeAdapter
Você deve registrar o TypeAdapter antes de abrir a caixa que está usando isso-caso contrário, ele produzirá um erro. Como estamos usando apenas uma única caixa e a abrimos dentro da função main (), temos que registrar o adaptador antes disso.
main () async {//Initialize hive await Hive.initFlutter ();//Registrando o adaptador Hive.registerAdapter (PersonAdapter ());//Abrindo a caixa await Hive.openBox (‘peopleBox’); runApp (MyApp ()); }
Agora, você pode realizar operações de banco de dados diretamente usando esta classe personalizada.
Construindo o aplicativo final
O aplicativo final consistirá principalmente em três telas:
AddScreen: para armazenar as informações do usuário no banco de dados InfoScreen: para mostrar as informações do usuário que estão presentes no banco de dados Hive, e um botão para deletar os dados do usuário UpdateScreen: para atualizar as informações do usuário no banco de dados
Não é necessário modifique o arquivo main.dart que contém o widget MyApp e a função main ().
AddScreen
A AddScreen exibirá um formulário para receber os dados do usuário como entradas. Em nosso caso, inseriremos apenas dois valores, Nome e o País de origem . Na parte inferior, haverá um botão para enviar os dados para o Hive.
O código para AddScreen é o seguinte:
class AddScreen extends StatefulWidget {@override _AddScreenState createState ()=> _AddScreenState (); } class _AddScreenState extends State
AddPersonForm é o widget principal onde a IU para o formulário é criada. Ele também contém a funcionalidade de armazenamento do Hive.
A estrutura básica do widget será semelhante a esta:
class AddPersonForm extends StatefulWidget {const AddPersonForm ({Key? Key}): super (key: key ); @override _AddPersonFormState createState ()=> _AddPersonFormState (); } classe _AddPersonFormState estende o estado
Recuperamos uma referência à caixa dentro do método initState (). Agora, temos que definir uma chave global para o formulário e adicionar alguns controladores de edição de texto.
class _AddPersonFormState extends State
Defina um método para armazenar dados no Hive e adicione um validador de campo de texto:
class _AddPersonFormState extends State
O código para a IU é o seguinte:
class _AddPersonFormState extends State
UpdateScreen
A UpdateScreen será semelhante à AddScreen, mas aqui passaremos o objeto Person para mostrar o valor atual nos campos de texto.
O código para essa tela será o seguinte:
class UpdateScreen extends StatefulWidget {final int index; pessoa final; const UpdateScreen ({required this.index, required this.person,}); @override _UpdateScreenState createState ()=> _UpdateScreenState (); } class _UpdateScreenState extends State
A única diferença no widget UpdatePersonForm é que ele conterá um método para atualizar o valor presente no banco de dados Hive.
class _UpdatePersonFormState extends State
InfoScreen
A InfoScreen será responsável por exibir os dados da Pessoa armazenados no Hive. Basicamente, a operação de leitura será realizada aqui.
O Hive fornece um widget chamado ValueListenableBuilder que só é atualizado quando algum valor dentro do banco de dados é modificado.
Esta tela conterá alguns itens adicionais funcionalidades:
Tocar no botão Excluir próximo a cada item da lista removerá os dados do usuário do banco de dados. Tocar em cada item da lista irá navegar para a tela de atualização. Tocar no botão de ação flutuante no canto inferior direito trará você para AddScreen
O código para esta tela é o seguinte:
class InfoScreen extends StatefulWidget {@override _InfoScreenState createState ()=> _InfoScreenState (); } class _InfoScreenState extends State
Parabéns , você tem concluiu seu aplicativo Flutter usando Hive como banco de dados persistente local.
Uma demonstração do aplicativo final é mostrado abaixo:
Conclusão
Este artigo cobre quase todos os conceitos básicos importantes do Hive. Existem mais algumas coisas que você pode fazer com o banco de dados Hive, incluindo o armazenamento de dados relacionais simples. Relações simples entre os dados podem ser tratadas usando HiveList , mas se você estiver armazenando qualquer dados para o Hive, então você deve verificar a caixa criptografada .
Resumindo, o Hive é uma das melhores opções que você tem para persistência de dados locais no Flutter, especialmente considerando que é extremamente rápido e suporta quase todas as plataformas .
Obrigado por ler o artigo! Se você tiver sugestões ou perguntas sobre o artigo ou exemplos, sinta-se à vontade para entrar em contato comigo no Twitter ou LinkedIn . Você também pode encontrar o repositório do aplicativo de amostra no meu GitHub .