【uni-app】集成SQLite,无服务数据库

devtools/2025/3/28 17:00:29/

        在移动应用开发中,本地数据存储是提升用户体验、实现离线功能的关键能力。

        本文将手把手教你如何在uni-app跨平台应用中无缝集成轻量级嵌入式数据库SQLite,彻底摆脱网络依赖,打造高性能、高可靠性的本地数据管理方案。

首先打开manifest.json配置中SQLite的配置。

在uni项目中新建一个JS文件

sqlite.js
javascript">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'; // 空值转为 NULLif (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 = nullif (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文件

javascript">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 方法:

以下为数据结构

javascript">      this.dataForm = {id: null, // 没有id则是新增, 有id则是修改content: '内容',timeOnlyDate: 0, // 0代表boolean类型的falsetime: '2025-03-17',type: '我说的'}

javascript">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. 查询

查询列表

javascript">  methods: {// 获取数据async getList() {this.chatList = await selectContent()}}

根据id 查询单个数据

场景: 点击列表进入详情页,通过获取url上的id来查询单个数据

javascript">  async onLoad(options) {// 接收url上的idif (options.id) {let data = await selectContent(`WHERE id = ${options.id}`)if (data.length) {this.dataForm = data[0]}}},

3. 删除
javascript">    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包名)/...


http://www.ppmy.cn/devtools/168967.html

相关文章

基于Rockylinux9.5(LTS-SP4)安装MySQL Community Server 9.2.0

目录 一、安装环境及准备 1、linux操作系统环境 2、MYSQL安装包准备 二、执行安装 1、解压软件包 2、按顺序执行软件包的安装 3、启动MYSQL服务 4.配置MYSQL 一、安装环境及准备 1、linux操作系统环境 Rocky linux9.5安装在VMware虚拟机上完成Rocky linux9.5安装&am…

如何理解分布式光纤传感器?

关键词&#xff1a;OFDR、分布式光纤传感、光纤传感器 分布式光纤传感器是近年来备受关注的前沿技术&#xff0c;其核心在于将光纤本身作为传感介质和信号传输介质&#xff0c;通过解析光信号在光纤中的散射效应&#xff0c;实现对温度、应变、振动等物理量的连续、无盲区、高…

Word 小黑第40套

对应大猫43 主题 -浏览主题 -选择W样式标准文件就行 1级段落和2级段落&#xff08;用项目符号不影响原本段落文字符号 颜色修改为自动&#xff09; 整段变红的 不是把光标定位到红色字体那里 要选择几个红色字体 再创建样式 插入的空白页一定要是下一页&#xff0c;不能插空白…

个人陈述本人于2011年8月被XXX大学经济学专业录取

本人于2011年8月被XXX大学经济学专业录取。在三年的学习中&#xff0c;我渐渐领略到了经济学的独特魅力&#xff0c;对经济学产生了浓厚的兴趣。秉着专一学习态度&#xff0c;不断向着目标努力&#xff0c;我取得了优秀的成绩&#xff0c;前五学期总成绩91.08分&#xff0c;名列…

晶鑫股份迈向敏捷BI之路,永洪科技助力启程

数据驱动的时代&#xff0c;每一次技术的创新和突破都在为企业的发展注入新的动力。而敏捷性也不再是选择&#xff0c;是企业生存与发展的必要条件。作为连续5年获得中国敏捷BI第一名的永洪科技&#xff0c;通过不断地在数据技术领域深耕细作&#xff0c;再次迎来了行业内的关注…

npm 安装 pnpm 的详细步骤及注意事项

一、安装步骤 1.全局安装 pnpm npm install -g pnpm2.验证安装 pnpm -v输出版本号即表示安装成功。 二、升级 pnpm 若已安装旧版本&#xff0c;可通过以下命令升级&#xff1a; npm install -g pnpmlatest三、配置镜像加速 设置淘宝镜像 pnpm config set registry http…

LLM(5):了解 GPT 架构

1.6 对 GPT 架构的更深入了解 GPT 最初由 OpenAI 的 Radford 等人在论文《通过生成式预训练提高语言理解能力》 中提出。GPT-3 是该模型的扩展版本&#xff0c;具有更多的参数&#xff0c;并且使用了更大的数据集进行训练。此外&#xff0c;ChatGPT 中提供的原始模型是通过在大…

Go语言中package的使用规则《二》

在 Go 语言中&#xff0c;包&#xff08;Package&#xff09; 是代码组织和复用的核心单元。以下是其定义、引用规则及使用习惯的详细说明&#xff1a; 一、包的定义规则 目录与包名 一个包对应一个目录&#xff08;文件夹&#xff09;&#xff0c;目录名通常与包名一致。 包名…