文章目录
一、uniapp中使用sqlite
1.什么是sqlite
SQLite是一种轻量级的关系型数据库管理系统。它是一个自包含、无服务器的数据库引擎,可以在客户端程序中直接嵌入,并且不需要独立的数据库服务器进程。SQLite使用简单的SQL语言,支持大多数标准的SQL语法和功能,包括事务、索引和触发器等。SQLite的数据库以单个文件的形式存储在主机文件系统中,可以轻松地将数据库文件在不同的设备间进行传输和共享。由于其小巧、快速、灵活和可移植的特性,SQLite广泛用于各种嵌入式系统、移动应用程序和其他小型项目中。
2.如何在uniapp中使用sqlite
这是h5+的教学文档:https://www.html5plus.org/doc/zh_cn/sqlite.html
这是我借鉴别人封装后的sqlite模块
sqlite.js
module.exports = {
dbName: "security", // 数据库名称
dbPath: "_doc/security.db", // 数据库地址,推荐以下划线为开头 _doc/xxx.db
// 判断数据库是否打开
isOpen() {
// 数据库打开了就返回 true,否则返回 false
var open = plus.sqlite.isOpenDatabase({
name: this.dbName, // 数据库名称
path: this.dbPath, // 数据库地址
});
return open;
},
// 创建数据库 或 有该数据库就打开
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);
},
});
});
},
// 数据库建表 sql:'CREATE TABLE IF NOT EXISTS dbTable("id" varchar(50),"name" TEXT)
// 创建 CREATE TABLE IF NOT EXISTS 、 dbTable 是表名,不能用数字开头、括号里是表格的表头
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);
},
});
});
},
// 数据库删表 sql:'DROP TABLE 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);
},
});
});
},
// 向表格里添加数据 sql:'INSERT INTO dbTable VALUES('x','x','x')' 对应新增
// 或者 sql:'INSERT INTO dbTable ('x','x','x') VALUES('x','x','x')' 具体新增
// 插入 INSERT INTO 、 dbTable 是表名、根据表头列名插入列值
insertTableData(dbTable, data, condition) {
// 判断有没有传参
if (dbTable !== undefined && data !== undefined) {
// 判断传的参是否有值
var 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("错误添加");
});
}
},
// 根据条件向表格里添加数据 有数据更新、无数据插入
// (建表时需要设置主键) 例如 --- "roomid" varchar(50) PRIMARY KEY
insertOrReplaceData(dbTable, data, condition) {
// 判断有没有传参
if (dbTable !== undefined && data !== undefined) {
if (condition == undefined) {
var sql = `INSERT OR REPLACE INTO ${dbTable} VALUES('${data}')`;
} else {
var sql = `INSERT OR REPLACE 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("错误添加");
});
}
},
// 查询获取数据库里的数据 sql:'SELECT * FROM dbTable WHERE lname = 'lvalue''
// 查询 SELECT * FROM 、 dbTable 是表名、 WHERE 查找条件 lname,lvalue 是查询条件的列名和列值
selectTableData(dbTable, lname, lvalue, cc, dd) {
if (dbTable !== undefined) {
// 第一个是表单名称,后两个参数是列表名,用来检索
if (lname !== undefined && cc !== undefined) {
// 两个检索条件
var sql = `SELECT * FROM ${dbTable} WHERE ${lname} = '${lvalue}' AND ${cc} = '${dd}'`;
}
if (lname !== undefined && cc == undefined) {
console.log('是否条件查询')
// 一个检索条件
var sql = `SELECT * FROM ${dbTable} WHERE ${lname} = '${lvalue}'`;
console.log(sql);
}
if (lname == undefined) {
var sql = `SELECT * FROM ${dbTable}`;
}
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("错误查询");
});
}
},
// 删除表里的数据 sql:'DELETE FROM dbTable WHERE lname = 'lvalue''
// 删除 DELETE FROM 、 dbTable 是表名、 WHERE 查找条件 lname,lvalue 是查询条件的列名和列值
deleteTableData(dbTable, lname, lvalue, ww, ee) {
if (dbTable !== undefined) {
if (lname == undefined) {
var sql = `DELETE FROM ${dbTable}`;
} else {
if (ww !== undefined) {
// 两个检索条件
var sql = `DELETE FROM ${dbTable} WHERE ${lname} = '${lvalue}' AND ${ww} = '${ee}'`;
} else {
// 一个检索条件
var sql = `DELETE FROM ${dbTable} WHERE ${lname} = '${lvalue}'`;
}
}
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("错误删除");
});
}
},
// 修改数据表里的数据 sql:"UPDATE dbTable SET 列名 = '列值',列名 = '列值' WHERE lname = 'lvalue'"
// 修改 UPDATE 、 dbTable 是表名, data: 要修改的列名=修改后列值, lname,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:"SELECT * FROM dbTable ORDER BY 'id' DESC LIMIT 15 OFFSET 'num'"
// dbTable 表名, ORDER BY 代表排序默认正序, id 是排序的条件 DESC 代表倒序,从最后一条数据开始拿
// LIMIT 15 OFFSET '${num}',这句的意思是跳过 num 条拿 15 条数据, num 为跳过多少条数据是动态值
// 例 初始num设为0,就从最后的数据开始拿15条,下次不拿刚获取的数据,所以可以让num为15,这样就能一步一步的拿完所有的数据
pullSQL(dbTable,pageNum=1, pageSize=5, key1, value1 ) {
let start = (pageNum - 1) * pageSize;
let size = pageSize;
let sql = ''
if (key1 && value1) {
sql = `SELECT * FROM ${dbTable} WHERE ${key1} = '${value1}' ORDER BY time DESC LIMIT '${size}' OFFSET '${start}'`;
}else {
sql = `SELECT * FROM ${dbTable} ORDER BY time DESC LIMIT '${size}' OFFSET '${start}'`;
}
return new Promise((resolve, reject) => {
plus.sqlite.selectSql({
name: this.dbName,
sql: sql,
success(e) {
resolve(e);
},
fail(e) {
reject(e);
},
});
});
},
};
这是基于上面的sqlite.js二次封装的sqlite_mixin.js
operateSqlite.js
import DB from "@/common/util/sqlite.js";
const sqobj = {
data() {
return {
listData: [],
};
},
methods: {
// 打开数据库
openSQL() {
// 这个是查询有没有打开数据库
let open = DB.isOpen();
console.log("数据库状态", open ? "开启" : "关闭");
if (!open) {
DB.openSqlite()
.then((res) => {
console.log("数据库已打开");
})
.catch((error) => {
console.log("数据库开启失败");
});
}
},
// 关闭数据库
closeSQL() {
// 这个是查询有没有打开数据库
let open = DB.isOpen();
if (open) {
DB.closeSqlite()
.then((res) => {
console.log("数据库已关闭");
})
.catch((error) => {
console.log("数据库关闭失败");
});
}
},
// 创建表
createTable(tableName, sql) {
console.log('创建表', tableName)
let open = DB.isOpen();
if (open) {
this.openSQL();
// let sql = '"id" INTEGER PRIMARY KEY AUTOINCREMENT,"name" text,"content" text,"time" text';
// 创建表 DB.createTable(表名, 表的列)
DB.createTable(tableName, sql)
.then((res) => {
console.log(`创建${tableName}表成功`);
this.showToast(`创建${tableName}表成功`);
})
.catch((error) => {
console.log("创建表失败");
});
} else {
console.log("数据库未打开");
}
},
// 删除表
dropTable(tableName){
let open = DB.isOpen();
if (open) {
// 删除表 DB.dropTable(表名)
DB.dropTable(tableName)
.then((res) => {
console.log(`删除${tableName}表成功`);
})
.catch((error) => {
console.log("删除表失败");
});
} else {
console.log("数据库未打开");
}
},
// 新增表数据
insertTableData(tableName,arr, sql, condition) {
console.log('插入表数据', arr)
this.feng.showTips('插入表数据', "none", 1000);
let open = DB.isOpen();
if (open) {
arr.map((item) => {
// let time = this.formatDate(new Date().getTime());
// let sql = `'${item.name}','${item.content}','${time}'`;
// let condition = "'name','content','time'";
// 新增 DB.insertTableData(表名, 对应表头列的数据)
DB.insertOrReplaceData(tableName, sql, condition)
.then((res) => {
console.log("新增数据成功");
this.feng.showTips('本地保存成功', "none", 3000);
this.selectTableData(tableName);
})
.catch((error) => {
console.log("失败", error);
});
});
} else {
console.log("数据库未打开");
}
},
// 查询表数据
selectTableData(tableName, key, value) {
let open = DB.isOpen();
if (open) {
// 查询表 DB.selectTableData(表名,查询条件列名,查询条件列值)
console.log('查询表数据', tableName, key, value)
if (key && value) {
return new Promise((resolve, reject) => {
DB.selectTableData(tableName, key, value)
.then((res) => {
console.log(`按照条件${key}查询的${tableName}表数据`, res);
resolve(res)
})
.catch((error) => {
console.log("查询失败", error);
reject(error)
});
});
} else {
DB.selectTableData(tableName)
.then((res) => {
console.log(`${tableName}表数据`, res);
})
.catch((error) => {
console.log("查询失败", error);
});
}
} else {
console.log("数据库未打开");
}
},
// 分页查询表数据
selectTableDataByPage(tableName, page, size, key, value) {
let open = DB.isOpen();
if (open) {
// 分页查询表 DB.selectTableDataByPage(表名,查询条件列名,查询条件列值,页码,每页条数)
if (key && value) {
DB.pullSQL(tableName, key, value, page, size)
.then((res) => {
console.log(`分页按照条件${key}查询的${tableName}表数据`, res);
this.listData = res;
})
.catch((error) => {
console.log("查询失败", error);
});
} else {
DB.pullSQL(tableName, page, size)
.then((res) => {
console.log(`分页查询${tableName}表数据`, res);
this.listData = res;
})
.catch((error) => {
console.log("查询失败", error);
});
}
} else {
console.log("数据库未打开");
}
},
// 删除表数据
deleteTableData(tableName, key, value) {
let open = DB.isOpen();
if (open) {
// 删除表 DB.deleteTableData(表名,查询条件列名,查询条件列值)
if (key && value) {
DB.deleteTableData(tableName, key, value)
.then((res) => {
console.log("删除表数据成功");
// this.selectTableData(tableName);
})
.catch((error) => {
console.log("删除失败", error);
});
} else {
DB.deleteTableData(tableName)
.then((res) => {
console.log("删除表数据成功");
// this.selectTableData(tableName);
})
.catch((error) => {
console.log("删除失败", error);
});
}
} else {
console.log("数据库未打开");
}
},
// 提示框
showToast: function (str) {
uni.showToast({
icon: "none",
title: str,
mask: true,
});
},
// 时间戳转年月日
formatDate(data) {
let now = new Date(data);
var year = now.getFullYear(); //取得4位数的年份
var month =
now.getMonth() + 1 < 10 ?
"0" + (now.getMonth() + 1) :
now.getMonth() + 1;
var date = now.getDate() < 10 ? "0" + now.getDate() : now.getDate();
var hour = now.getHours() < 10 ? "0" + now.getHours() : now.getHours();
var minute =
now.getMinutes() < 10 ? "0" + now.getMinutes() : now.getMinutes();
var second =
now.getSeconds() < 10 ? "0" + now.getSeconds() : now.getSeconds();
return (
year +
"-" +
month +
"-" +
date +
" " +
hour +
":" +
minute +
":" +
second
);
}
},
};
export default sqobj;
在页面中使用sqlite
- 引入mixin
<script>
import sqObj from '@/mixin/operateSqlite.js'
export default {
mixins: [sqObj],
</script>
- 打开数据库,创建表
<script>
import uniRequest from "uni-request";
import bus from "@/common/util/bus.js";
import sqObj from '@/mixin/operateSqlite.js'
export default {
components: {},
mixins: [sqObj],
created(){
this.openSQL() // 打开数据库
this.creatTable() // 创建security表
},
creatTable(){
let sql =
'"id" INTEGER PRIMARY KEY AUTOINCREMENT,"name" text,"age" number,"time" text';
this.createTable("security", sql); // 创建表
}
- 剩下的增删改查就不一一列举了,很简单,只需要根据需要写sql就可以了,和上面的创建表操作基本一样。
二、云打包sqlite的坑
1. sqlite模块找不到
在真机调试的时候可以正常使用sqlite,但是云打包app之后报上面这个错
解决方案
在hubuildx中点击manifest.json->app模块配置->勾选SQLite模块
这是云打包解决方案,离线打包可以看看这位大佬写的解决方案https://blog.csdn.net/qq_37021104/article/details/107382209
2. 勾选了模块,打包之后sqlite不生效。
1. 可能是db文件的存储路径问题,具体如下:
路径推荐使用_doc/xxx.db
,_doc
目录下支持读写操作。
2. 可能没有自动创建库文件
具体解决方案可以参考:https://ask.dcloud.net.cn/article/35729
document.addEventListener('plusready', function(e){
// 确保_doc/test.db文件存在
plus.io.requestFileSystem( plus.io.PRIVATE_DOC, function(fs){
fs.root.getFile('test.db', {create:true}, function(fileEntry){
console.log('ensure test.db file!');
// 打开数据库,创建表等等操作。。。
});
});
}, false);
3. 在onload钩子中创建表不执行,放在created中
我开始是这么写的
onLoad() {
console.log("onload哈哈哈哈");
this.openSQL();
let sql =
'"id" INTEGER PRIMARY KEY AUTOINCREMENT,"name" text,"age" number,"time" text';
this.createTable("security", sql); // 创建表
},
不清楚为什么不执行,console都可以打印,就不不走this.createTable
,改为created
就好了