Implementando persistência/banco de dados a um aplicativo react-native
Lucas Cruz
Posted on March 4, 2024
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
Pode-se importar da seguinte forma:
import * as SQLite from 'expo-sqlite'
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")
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
}
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)
}
}
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')
}
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)
ou
SQLiteDatabase.transaction(callback: SQLite.SQLTransactionCallback, errorCallback?: SQLite.SQLTransactionErrorCallback | undefined, successCallback?: (() => void) | undefined)
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")})
...
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 )
ou
SQLTransaction.executeSql(sqlStatement: string, args?: SQLite.SQLStatementArg[] | undefined, callback?: SQLite.SQLStatementCallback | undefined, errorCallback?: SQLite.SQLStatementErrorCallback | undefined): void
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);
}
);
aqui a lista
Referências
MissCoding - Local SQLite Database for Expo React Native App
Posted on March 4, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.