DEV Community

Lucas Cruz
Lucas Cruz

Posted on • Updated on

Implementando persistência/banco de dados a um aplicativo react-native

Neste artigo eu compartilho como implementar persistência local com react-native com expo, usando sqlite que é o banco de dados nativo para android.

Requisitos

  • React-native
  • expo
  • expo-sqlite

Instalando e importando

Primeiramente vamos usar a lib 'expo-sqlite'. O comando usado para instalar é:

npx expo install expo-sqlite
Enter fullscreen mode Exit fullscreen mode

Pode-se importar da seguinte forma:

import * as SQLite from 'expo-sqlite'
Enter fullscreen mode Exit fullscreen mode

Criando e Conectando com Banco de dados

Para abrir um banco de dados ou criar, caso o banco não exista se usa a função OpenDatabase.

db = SQLite.openDatabase("myDatabase.db")
Enter fullscreen mode Exit fullscreen mode

Para facilitar a forma como se obtém a a conexão e não ter que ficar repetindo o nome do banco em todos os lugares que tiver que fazer essa conexão, pode-se encapsular em uma função da seguinte forma:

export function getDBConnection() {
    let db = null
    try{ 
        db = SQLite.openDatabase("myDatabase.db")
    }
    catch(error){
        console.log("error openDatabase:", error)
    }
    return db
}
Enter fullscreen mode Exit fullscreen mode

Criando tabelas

Assim que se cria o banco o próximo passo é criar as tabelas, abaixo temos um exemplo de código onde se cria as tabelas caso elas não existam no banco de dados. Para isso é feita a conexão com o banco primeiro e a criação das tabelas é feita na mesma transação.

export function initDB(){

    try{
        const db = getDBConnection()
        if(db){

            // Execute consultas SQL para criar tabelas
            db.transaction(tx => {

                // Cria a tabela Subject
                tx.executeSql(
                    'CREATE TABLE IF NOT EXISTS Subject (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, start_time TEXT, end_time TEXT)',[], ()=>{console.log("successful create Subject")}, ()=>{console.log("error: create Subject")})

                // Cria a tabela Student
                tx.executeSql(
                    'CREATE TABLE IF NOT EXISTS Student (id INTEGER PRIMARY KEY, name TEXT)',[], ()=>{console.log("successful create Student")}, ()=>{console.error("error: create Student")});

                // Cria a tabela Machine
                tx.executeSql(
                    'CREATE TABLE IF NOT EXISTS Machine (id INTEGER PRIMARY KEY, is_available INTEGER)',[], ()=>{console.log("successful create Machine")}, ()=>{console.error("error: create Machine")})

                // Cria a tabela Loan   
                tx.executeSql(
                    'CREATE TABLE IF NOT EXISTS Loan (id INTEGER PRIMARY KEY AUTOINCREMENT, student INTEGER, machine INTEGER, subject INTEGER, loan_time TEXT, devolution_time TEXT, FOREIGN KEY (student) REFERENCES Student(id) ON DELETE NO ACTION, FOREIGN KEY (machine) REFERENCES Machine(id) ON DELETE NO ACTION, FOREIGN KEY (subject) REFERENCES Subject(id) ON DELETE NO ACTION)',[], ()=>{console.log("successful create Loan")}, ()=>{console.error("error: create Loan")});


                tx.executeSql(
                    'CREATE TABLE IF NOT EXISTS Student_Subject (student INTEGER, subject INTEGER, PRIMARY KEY (student, subject), FOREIGN KEY (student) REFERENCES Student(id), FOREIGN KEY (subject) REFERENCES Subject(id))',[], ()=>{console.log("successful create Student_Subject")}, ()=>{console.error("error: create Student_Subject")});


                }, (error) =>{ console.error("error transition: ",error)},
                    ()=> { console.log('successful transition initDB')

                })

    }
    }catch(error){
        console.log("error openDB", error)
    }
}
Enter fullscreen mode Exit fullscreen mode

Aprofundando na criação de tabela

if(db){           
 // Execute consultas SQL para criar tabelas
 db.transaction(tx => {
 // Operações no banco 
 }, (error) =>{ console.error("error transition: ",error)},
    ()=> { console.log('successful transition initDB')
}

Enter fullscreen mode Exit fullscreen mode

Primeiramente é interessante verificar se o a conexão foi estabelecida, então eu verifico com o if(db) se for nulo e por que a conexão não foi estabelecida.

após isso uso a função transaction do db:

A função pode ser descrita com:

db.transaction(callback transaction, callback error, callback successful)
Enter fullscreen mode Exit fullscreen mode

ou

SQLiteDatabase.transaction(callback: SQLite.SQLTransactionCallback, errorCallback?: SQLite.SQLTransactionErrorCallback | undefined, successCallback?: (() => void) | undefined)
Enter fullscreen mode Exit fullscreen mode

O primeiro callback é onde ocorre as operações com o banco, após isso tem um callback de erro onde se pode tratar o erro no caso mostrado aqui foi feito apenas um log para verificar se está ocorrendo e o ultimo argumento é o callback de sucesso, quando as operações são bem sucedidas, nessa aplicação também é feito apenas um log.

Operações com o banco - SQL

db.transaction(tx => {

                // Cria a tabela Subject
                tx.executeSql(
                    'CREATE TABLE IF NOT EXISTS Subject (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, start_time TEXT, end_time TEXT)',
                    [],
                    ()=>{console.log("successful create Subject")},
                    ()=>{console.log("error: create Subject")})

...
Enter fullscreen mode Exit fullscreen mode

O callback tem um parâmetro que é um objeto de transação (SQLite.SQLTransaction) e com esse objeto você pode usar a função
executeSql que utiliza a linguagm SQL (Structured Query Language) para fazer operações com o banco. Essa função recebe três parâmetros

tx.executeSql( string SQL, list params to SLQ, callback successful, callback error )
Enter fullscreen mode Exit fullscreen mode

ou

SQLTransaction.executeSql(sqlStatement: string, args?: SQLite.SQLStatementArg[] | undefined, callback?: SQLite.SQLStatementCallback | undefined, errorCallback?: SQLite.SQLStatementErrorCallback | undefined): void
Enter fullscreen mode Exit fullscreen mode

No exemplo que estou usando a lista de argumentos para o SQL está vazio pois na criação não precisamos passar nenhum argumento, os callbacks de sucesso e de erro aqui também só estação mostrando logs.

Um exemplo de quando se passa os argumentos para a lista de argumentos pode ser visto abaixo.

tx.executeSql(
            'INSERT INTO Subject (name, start_time, end_time) VALUES (?, ?, ?)',
            [name, startTime, endTime],
            (tx, results) => {
                console.log('Item adicionado com sucesso!', results);
                if(callback){
                 callback(results)
                }
            },
            (tx, error) => {
                console.error('Erro ao adicionar o item:', error);
            }
        );
Enter fullscreen mode Exit fullscreen mode

aqui a lista

Referências

MissCoding - Local SQLite Database for Expo React Native App

Top comments (0)