在移动应用开发中,本地数据存储是提升用户体验、实现离线功能的关键能力。
本文将手把手教你如何在uni-app跨平台应用中无缝集成轻量级嵌入式数据库SQLite,彻底摆脱网络依赖,打造高性能、高可靠性的本地数据管理方案。
首先打开manifest.json配置中SQLite的配置。

在uni项目中新建一个JS文件
sqlite.js
module.exports = {
/**
* 数据库名称
* @type {String}
*/
dbName: 'database',
/**
* 数据库地址
* @type {String} 推荐使用H5+规范的安全目录 _doc/xxx.db
* 安卓开发环境中数据库所在地址:/Android/data/io.dcloud.HBuilder/app/Hbuilder/doc/sqlite/database.db
*/
dbPath: `_doc/sqlite/database.db`, // 使用H5+规范的安全目录
/**
* 处理空值和特殊字符
* @param value 值
*/
escapeValue(value) {
if (value === 0) return 0; // 0直接返回
if (!value) return 'NULL'; // 空值转为 NULL
if (typeof value !== 'string') return value; // 其他类型直接 返回
return `'${value.replace(/'/g, "''")}'`; // 转义单引号
},
/**
* 判断数据库是否打开
* @returns {Boolean} 打开为 true,否则为 false
*/
isOpen() {
return plus.sqlite.isOpenDatabase({ name: this.dbName, path: this.dbPath })
},
/**
* 打开数据库,没有则创建
*/
openSqlite() {
return new Promise((resolve, reject) => {
plus.sqlite.openDatabase({
name: this.dbName,
path: this.dbPath,
success(e) {
resolve(e);
},
fail(e) {
reject(e);
}
})
})
},
/**
* 关闭数据库
*/
closeSqlite() {
return new Promise((resolve, reject) => {
plus.sqlite.closeDatabase({
name: this.dbName,
success(e) {
resolve(e);
},
fail(e) {
reject(e);
}
})
})
},
/**
* 创建表
* @param {Object} dbTable 表名
* @param {Object} data 表列
*/
createTable(dbTable, data) {
return new Promise((resolve, reject) => {
// executeSql: 执行增删改等操作的SQL语句
plus.sqlite.executeSql({
name: this.dbName,
sql: `CREATE TABLE IF NOT EXISTS ${dbTable}(${data})`,
success(e) {
resolve(e);
},
fail(e) {
reject(e);
}
})
})
},
/**
* 数据库删表
* @param {Object} dbTable 表名
*/
dropTable(dbTable) {
return new Promise((resolve, reject) => {
plus.sqlite.executeSql({
name: this.dbName,
sql: `DROP TABLE ${dbTable}`,
success(e) {
resolve(e);
},
fail(e) {
reject(e);
}
})
})
},
/**
* 新增数据到表里
* @param {String} dbTable 表名
* @param {String} data 列值
* @param {String} condition 表头列名
*/
insertTableData(dbTable, data, condition) {
if (dbTable !== undefined && data !== undefined) {
const bol = (JSON.stringify(data) == "{}");
if (!bol) {
if (condition == undefined) {
var sql = `INSERT INTO ${dbTable} VALUES('${data}')`;
} else {
var sql = `INSERT INTO ${dbTable} (${condition}) VALUES(${data})`;
}
// console.log(sql);
return new Promise((resolve, reject) => {
// 表格添加数据
plus.sqlite.executeSql({
name: this.dbName,
sql: sql,
success(e) {
resolve(e);
},
fail(e) {
reject(e);
}
})
})
} else {
return new Promise((resolve, reject) => {
reject("错误添加")
})
}
} else {
return new Promise((resolve, reject) => {
reject("错误添加")
})
}
},
/**
* 根据条件向表格里添加数据 有数据更新、无数据插入
* (建表时必须设置主键, 不然会保存失效) 例如 --- "id" INTEGER PRIMARY KEY
* @param {String} dbTable 表名
* @param {String} data 列值
* @param {String} condition 表头列名
*/
insertOrReplaceData(dbTable, data, condition) {
if (dbTable !== undefined && data !== undefined) {
let sql = null
if (condition == undefined) {
sql = `INSERT OR REPLACE INTO ${dbTable} VALUES('${data}')`;
} else {
sql = `INSERT OR REPLACE INTO ${dbTable} (${condition}) VALUES(${data})`;
}
return new Promise((resolve, reject) => {
plus.sqlite.executeSql({
name: this.dbName,
sql: sql,
success(e) {
resolve(e);
},
fail(e) {
reject(e);
}
})
})
} else {
return new Promise((resolve, reject) => {
reject("错误添加")
})
}
},
/**
* 查询表里的数据
* @param {String} dbTable 表名
* @param {String} [condition = ''] 查找条件
* @remark 查询获取数据库里的数据 sql例子: 'SELECT * FROM dbTable WHERE id = 1'
*/
selectTableData(dbTable, condition = '') {
if (dbTable !== undefined) {
var sql = `SELECT * FROM ${dbTable} ${condition}`;
return new Promise((resolve, reject) => {
// 表格查询数据 执行查询的SQL语句
plus.sqlite.selectSql({
name: this.dbName,
sql: sql,
success(e) {
resolve(e);
},
fail(e) {
reject(e);
}
})
})
} else {
return new Promise((resolve, reject) => {
reject("错误查询")
});
}
},
/**
* 删除表里的数据
* @param {String} dbTable 表名
* @param {String} [condition = ''] 查找条件 例如(const condition = 'WHERE id = 1')
* @remark 删除表里的数据 sql例子:'DELETE FROM dbTable WHERE id = 1'
*/
deleteTableData(dbTable, condition = '') {
if (dbTable !== undefined) {
var sql = `DELETE FROM ${dbTable} ${condition}`;
return new Promise((resolve, reject) => {
// 删除表数据
plus.sqlite.executeSql({
name: this.dbName,
sql: sql,
success(e) {
resolve(e);
},
fail(e) {
reject(e);
}
})
})
} else {
return new Promise((resolve, reject) => {
reject("错误删除")
});
}
},
/**
* 修改数据表里的数据
* @param dbTable 表名
* @param data 要修改的列名=修改后列值
* @param lname 是查询条件的列名
* @param lvalue 是查询条件的列值
*/
updateTableData(dbTable, data, lname, lvalue) {
if (lname == undefined) {
var sql = `UPDATE ${dbTable} SET ${data}`;
} else {
var sql = `UPDATE ${dbTable} SET ${data} WHERE ${lname} = '${lvalue}'`;
}
// WHERE 前面是要修改的列名、列值,后面是条件的列名、列值
return new Promise((resolve, reject) => {
// 修改表数据
plus.sqlite.executeSql({
name: this.dbName,
sql: sql,
success(e) {
resolve(e);
},
fail(e) {
reject(e);
}
})
})
},
/**
* 从指定数据库表中选择数据的方法。此功能对于实现分页加载等场景非常有用。
*
* 此方法用于执行SQL查询以从给定的数据库表(dbTable)中选择特定数量(dataNum)的数据项,
* 并跳过前面的一定数量(jumpNum)的数据项。
* @param {string} dbTable - 数据库表的名称。
* @param {number} dataNum - 要选择的数据项的数量。
* @param {number} jumpNum - 要跳过的数据项的数量。
*/
selectPullData(dbTable, dataNum ,jumpNum) {
return new Promise((resolve, reject) => {
plus.sqlite.selectSql({
name: this.dbName,
sql: `SELECT * FROM ${dbTable} LIMIT ${dataNum} OFFSET '${jumpNum}'`,
success(e) {
resolve(e);
},
fail(e) {
reject(e);
}
})
})
}
}
看懂以上代码基本就能自己开始造接口了!!!
举个🌰栗子🌰
封装一个content.js文件
import sqlite from '../sqlite'
/**
* 创建对话表
* @returns {Promise<void>}
*/
export async function createContent() {
await sqlite.createTable('content', `
id INTEGER PRIMARY KEY AUTOINCREMENT,
timeOnlyDate BOOLEAN,
content TEXT,
time TEXT,
type varchar(10)
`)
}
/**
* 查询对话表
*/
export async function selectContent(condition = '') {
return await sqlite.selectTableData('content', condition)
}
/**
* 新增或修改对话表
*/
export async function insertOrReplaceContent(data) {
// 构造插入或更新的值
const values = [
sqlite.escapeValue(data.id),
sqlite.escapeValue(data.timeOnlyDate),
sqlite.escapeValue(data.content),
sqlite.escapeValue(data.time),
sqlite.escapeValue(data.type)
].join(', ');
try {
await sqlite.insertOrReplaceData('content', values, 'id,timeOnlyDate,content,time,type');
return true
} catch (err) {
// 错误处理
console.error('添加或修改失败:', err)
return false
}
}
/**
* 删除数据
*/
export async function deleteContent(id) {
if (id) {
try {
// 使用 deleteTableData 来删除数据
await sqlite.deleteTableData('content', `WHERE id = ${id}`)
return true
} catch (err) {
// 错误处理
console.error('删除失败:', err)
return false
}
} else {
console.log('id为空')
return false
}
}
在vue中使用
1. 新增/修改
我这里直接使用 insertOrReplaceContent 方法:
以下为数据结构
this.dataForm = {
id: null, // 没有id则是新增, 有id则是修改
content: '内容',
timeOnlyDate: 0, // 0代表boolean类型的false
time: '2025-03-17',
type: '我说的'
}
import { deleteContent, insertOrReplaceContent, selectContent } from '../../../sql/mapper/content'
methods: {
// 保存按钮
async saveBtn() {
let isSuccess = await insertOrReplaceContent(this.dataForm)
if (isSuccess) {
uni.$u.toast('保存成功, 即将返回上一页!');
setTimeout(() => {
// 返回上一页
uni.navigateBack({
delta: 1
})
}, 1500)
} else {
uni.$u.toast('保存失败,请重试');
}
}
}
2. 查询
查询列表
methods: {
// 获取数据
async getList() {
this.chatList = await selectContent()
}
}
根据id 查询单个数据
场景: 点击列表进入详情页,通过获取url上的id来查询单个数据
async onLoad(options) {
// 接收url上的id
if (options.id) {
let data = await selectContent(`WHERE id = ${options.id}`)
if (data.length) {
this.dataForm = data[0]
}
}
},
3. 删除
async delBtn() {
uni.showModal({
title: '提示',
content: '确定删除吗?',
success: async (res) => {
if (res.confirm && this.dataForm.id) {
let isSuccess = await deleteContent(this.dataForm.id)
if (isSuccess) {
uni.$u.toast('删除成功!');
}
}
}
})
},
查看数据库

安卓开发环境中数据库所在地址:
根据sqlite.js文件里的dbPath来寻找
/Android/data/io.dcloud.HBuilder/app/Hbuilder/....
例如 /Android/data/io.dcloud.HBuilder/app/Hbuilder/doc/sqlite/database.db
找到 这个db文件
打包后会路径会变成
/Android/data/uni.UNI234567(你的uni包名)/...


4511

被折叠的 条评论
为什么被折叠?



