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

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

        本文将手把手教你如何在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包名)/...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值