Bootstrap

uniapp sqlite数据库封装设计总结(完结篇)

往期回顾

uniapp sqlite 数据库操作封装
uniapp sqlLite 数据库操作封装 2:如何面向对象操作数据库
uniapp sqlite3 时间查询

封装代码

数据库js

module.exports = {
	dbName: 'Bluetooth', // 数据库名称
	dbPath: '_downloads/Bluetooth.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:'DROP TABLE dbTable'
	dropTable(dbTable) {

		console.log(`DROP TABLE ${dbTable}`)
		return new Promise((resolve, reject) => {
			plus.sqlite.executeSql({
				name: this.dbName,
				sql: `DROP TABLE ${dbTable}`,
				success(e) {
					resolve(e)
				},
				fail(e) {
					reject(e)
				}
			})
		})
	},

	//-----------------------js对象方法,简化操作-------------
	///原生的sql操作
	SqlExecute(sql) {
		console.log(sql)
		return new Promise((resolve, reject) => {
			plus.sqlite.executeSql({
				name: this.dbName,
				sql: sql,
				success(e) {
					// console.log(e)
					resolve(e)
				},
				fail(e) {
					console.log(e)
					reject(e)
				}
			})
		})
	},
	//执行原生的select语句
	SqlSelect(sql) {
		console.log(sql)
		return new Promise((resolve, reject) => {
			plus.sqlite.selectSql({
				name: this.dbName,
				sql: sql,
				success(e) {
					console.log(e)
					resolve(e)
				},
				fail(e) {
					console.log(e)
					reject(e)
				}
			})
		})
	},

	//通过对象创建数据库,使用对象参数
	JsCreateTable(dbTable, data) {
		data = Object.entries(data).map(item => {
			return item[0] + ' ' + item[1]
		}).join(',')


		var sql = `CREATE TABLE IF NOT EXISTS ${dbTable}("id" INTEGER PRIMARY KEY AUTOINCREMENT,${data})`
		return this.SqlExecute(sql)
	},

	//通过对象创建数据库,使用对象的数据类型
	JsCreateTableType(dbTable, data) {
		data = Object.entries(data).map(item => {
			var typeName = ''
			switch (item[1].constructor) {
				case Number:
					if (Math.floor(item[1]) == item[1]) {
						typeName = 'INTEGER'
					} else {
						typeName = 'REAL'
					}
					break
				case String:
					typeName = 'TEXT'
					break
				case Boolean:
					typeName = 'BOOLEAN'
					break
				case Date:
					typeName = 'TEXT'
					break
			}
			return item[0] + ' ' + typeName
		}).join(',')


		var sql = `CREATE TABLE IF NOT EXISTS ${dbTable}("id" INTEGER PRIMARY KEY AUTOINCREMENT,${data})`
		// console.log(sql)
		return this.SqlExecute(sql)
	},
	//通过对象插入数据
	JsInsertTableData(dbTable, data) {
		var condition = []
		var sqlValue = []
		Object.entries(data).forEach(item => {
			condition.push(`'${item[0]}'`)
			if (item[1] != undefined) {
				if (item[1].constructor == String) {
					sqlValue.push(`'${item[1]}'`)
				} else if (item[1].constructor == Date) {

					sqlValue.push(`'${item[1].format('yyyy-MM-dd hh:mm:ss')}'`)
				} else {
					sqlValue.push(item[1])
				}
			}
		})
		condition = condition.join(',')
		sqlValue = sqlValue.join(',')
		var sql = `INSERT INTO ${dbTable} (${condition}) VALUES(${sqlValue})`
		return this.SqlExecute(sql)
	},
	//通过对象选择数据
	JsSelectTableData(dbTable, data) {
		var sql = ''
		var condition = []
		if (data == undefined || data == null || data == {}) {
			sql = `SELECT * FROM ${dbTable}`
		} else if(data.constructor == Number){
			sql = `SELECT * FROM ${daTable} where id = ${data}`
		} else {
			Object.entries(data).forEach(item => {
				if (item[1] != undefined && item[0] != 'id') {
					if (typeof(item[1] == 'string')) {
						condition.push(` ${item[0]} = '${item[1]}' `)
					} else {
						condition.push(` ${item[0]} = ${item[1]} `)
					}
				}

			})
			condition = condition.join('AND')
			sql = `SELECT * FROM ${dbTable} WHERE ${condition}`
		}


		return this.SqlSelect(sql)
	},
	//通过对象获取
	JsUpdate(dbTable, data) {
		try{
			var sql = ''
			var condition = []
			Object.entries(data).forEach(item => {
				if (item[1] != undefined && item[0] != 'id') {
					if (typeof(item[1] == 'string')) {
						condition.push(` ${item[0]} = '${item[1]}' `)
					} else {
						condition.push(` ${item[0]} = ${item[1]} `)
					}
				}
			
			})
			condition = condition.join(',')
			sql = `UPDATE ${dbTable} SET ${condition} where id = ${data.id}`
			return this.SqlExecute(sql)
		}catch(e){
			console.log(e)
			//TODO handle the exception
		}
		
	},
	JsDelete(dbTable,data){
		var sql = ''
		// debugger
		var condition = []
		try{
			if (data.constructor == Number) {
				sql = `DELETE FROM ${dbTable} where id = ${data}`
			} else {
				Object.entries(data).forEach(item => {
					if (item[1] != undefined && item[0] != 'id') {
						if (typeof(item[1] == 'string')) {
							condition.push(` ${item[0]} = '${item[1]}' `)
						} else {
							condition.push(` ${item[0]} = ${item[1]} `)
						}
					}
			
				})
				condition = condition.join('AND')
				sql = `Delete FROM ${dbTable} WHERE ${condition}`
			}
			return this.SqlExecute(sql)
		}catch(e){
			console.log(e)
		}
		
	}
}

封装示例

const SqlHelper = require('@/utils/SqlHelper.js')//封装好的代码

var t_data = {
	name: '姓名',
	age: 15,
	sex: '男'
}
module.exports = {
	dtName :'SqlTest',
	GetData(){
		return t_data
	},
	IsOpen(){
		if(!SqlHelper.isOpen()){
			SqlHelper.openSqlite()
		}
		return SqlHelper.isOpen()
	},
	Init(){
		this.IsOpen()
	 	return SqlHelper.JsCreateTableType(this.dtName,t_data)
	},
	Insert(data){
		this.IsOpen()
		return SqlHelper.JsInsertTableData(this.dtName,data)
	},
	Select(data){
		this.IsOpen()
		return SqlHelper.JsSelectTableData(this.dtName,data)
	},
	Update(data){
		this.IsOpen()
		return SqlHelper.JsUpdate(this.dtName,data)
	},
	Delete(data){
		this.IsOpen()
		return SqlHelper.JsDelete(this.dtName,data)
	}
}

如何使用

这里讲述一下如何使用我封装好的js代码。我封装采用了ORM的思想,就是把所有的sql语句全部改为js操作。ORM就是对象数据库模型,将所有的sql语句全部改为代码操作

前期准备

创建数据库和创建数据表

const SqlHelper = require('@/utils/SqlHelper.js')//封装好的sql操作
const DB_SqlTest = require('@/utils/mapper/SqlTest.js')//测试数据表

......

SqlHelper.openSqlite()//创建数据库
DB_SqlTest.Init()//创建数据表

var data = DB_SqlTest.GetData()//得到数据库对象,我们所有ORM操作都是对这个对象进行操作

/**
data = {
	id:自增主键
	name: '姓名',
	age: 15,
	sex: '男'
}

*//

async function action(){//所有操作都是异步操作。使用async和await进行封装
	var resData;//用于存放查询结果
	data.id = null;//插入时,id不能重复,自动生成
	
	//增
	await DB_SqlTest.Insert(data)//插入数据
	
	//查
	await DB_SqlTest.Select(data).then(res=>resData = res)//查询,then存放成功结果
	resData.name = '新名字'//修改resData的部分参数,用于更新	

	//改
	await DB_SqlTest.Update(resData);//更新是按照Id更新


	//删
	await DB_SqlTest.delete(resData);//更新是按照Id更新
	
}

action()//执行异步函数

这里我对查和删进行了一些判断

data类型sql语句
{data1:value1,data2:value2}select * from dbName where [ data1 = value1 AND…]
Numberselect * from dbName where id = data
{},undefined,nullselect * from dbName

data类型sql语句
{data1:value1,data2:value2}delete dbName where [ data1 = value1 AND…]
Numberdelete dbName where id = data

数据库操作再封装

之前我们将数据库的sql语句改成了JS的操作,这次我们希望用一个总数据库封装来封装所有的数据表的操作

ORM是对象数据库

将数据库sql语句改成ORM操作
并且保留原生sql操作入口
将所有业务打包给总业务
总业务操作
数据库创建+数据表创建+数据表连接
数据库已封装操作
业务1
业务2
业务3
单独业务操作
已存入数据表名称
生成对应字段
生成对应字段
ORM增删改查+对应参数
数据表名称
对象
数字
无效对象
数据表ORM对应数据
创建数据表
重新创建数据表
获取原型参数
数据库操作封装
已存入数据库名称
ORM增删改查
参数1:数据表名称
参数2:对应数据
数据库名称
原生sql查询
原生sql执行
数据库sqlite源生操作
open打开/创建数据库
execute执行sql语句
创建表
删除表
close关闭数据库
select查询sql语句
返回查询结果

封装代码

SqlHelper.js,之前写过了,现在再写一次

module.exports = {
	dbName: 'Bluetooth', // 数据库名称
	dbPath: '_downloads/Bluetooth.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:'DROP TABLE dbTable'
	dropTable(dbTable) {

		console.log(`DROP TABLE ${dbTable}`)
		return new Promise((resolve, reject) => {
			plus.sqlite.executeSql({
				name: this.dbName,
				sql: `DROP TABLE ${dbTable}`,
				success(e) {
					resolve(e)
				},
				fail(e) {
					reject(e)
				}
			})
		})
	},

	//-----------------------js对象方法,简化操作-------------
	///原生的sql操作
	SqlExecute(sql) {
		console.log(sql)
		return new Promise((resolve, reject) => {
			plus.sqlite.executeSql({
				name: this.dbName,
				sql: sql,
				success(e) {
					// console.log(e)
					resolve(e)
				},
				fail(e) {
					console.log(e)
					reject(e)
				}
			})
		})
	},
	//执行原生的select语句
	SqlSelect(sql) {
		console.log(sql)
		return new Promise((resolve, reject) => {
			plus.sqlite.selectSql({
				name: this.dbName,
				sql: sql,
				success(e) {
					console.log(e)
					resolve(e)
				},
				fail(e) {
					console.log(e)
					reject(e)
				}
			})
		})
	},

	//通过对象创建数据库,使用对象参数
	JsCreateTable(dbTable, data) {
		data = Object.entries(data).map(item => {
			return item[0] + ' ' + item[1]
		}).join(',')


		var sql = `CREATE TABLE IF NOT EXISTS ${dbTable}("id" INTEGER PRIMARY KEY AUTOINCREMENT,${data})`
		return this.SqlExecute(sql)
	},

	//通过对象创建数据库,使用对象的数据类型
	JsCreateTableType(dbTable, data) {
		data = Object.entries(data).map(item => {
			var typeName = ''
			switch (item[1].constructor) {
				case Number:
					if (Math.floor(item[1]) == item[1]) {
						typeName = 'INTEGER'
					} else {
						typeName = 'REAL'
					}
					break
				case String:
					typeName = 'TEXT'
					break
				case Boolean:
					typeName = 'BOOLEAN'
					break
				case Date:
					typeName = 'TEXT'
					break
			}
			return item[0] + ' ' + typeName
		}).join(',')


		var sql = `CREATE TABLE IF NOT EXISTS ${dbTable}("id" INTEGER PRIMARY KEY AUTOINCREMENT,${data})`
		// console.log(sql)
		return this.SqlExecute(sql)
	},
	//通过对象插入数据
	JsInsertTableData(dbTable, data) {
		var condition = []
		var sqlValue = []
		Object.entries(data).forEach(item => {
			condition.push(`'${item[0]}'`)
			if (item[1] != undefined) {
				if (item[1].constructor == String) {
					sqlValue.push(`'${item[1]}'`)
				} else if (item[1].constructor == Date) {

					sqlValue.push(`'${item[1].format('yyyy-MM-dd hh:mm:ss')}'`)
				} else {
					sqlValue.push(item[1])
				}
			}
		})
		condition = condition.join(',')
		sqlValue = sqlValue.join(',')
		var sql = `INSERT INTO ${dbTable} (${condition}) VALUES(${sqlValue})`
		return this.SqlExecute(sql)
	},
	//通过对象选择数据
	JsSelectTableData(dbTable, data) {
		var sql = ''
		var condition = []
		if (data == undefined || data == null || data == {}) {
			sql = `SELECT * FROM ${dbTable}`
		} else if(data.constructor == Number){
			sql = `SELECT * FROM ${daTable} where id = ${data}`
		} else {
			Object.entries(data).forEach(item => {
				if (item[1] != undefined && item[0] != 'id') {
					if (typeof(item[1] == 'string')) {
						condition.push(` ${item[0]} = '${item[1]}' `)
					} else {
						condition.push(` ${item[0]} = ${item[1]} `)
					}
				}

			})
			condition = condition.join('AND')
			sql = `SELECT * FROM ${dbTable} WHERE ${condition}`
		}


		return this.SqlSelect(sql)
	},
	//通过对象获取
	JsUpdate(dbTable, data) {
		try{
			var sql = ''
			var condition = []
			Object.entries(data).forEach(item => {
				if (item[1] != undefined && item[0] != 'id') {
					if (typeof(item[1] == 'string')) {
						condition.push(` ${item[0]} = '${item[1]}' `)
					} else {
						condition.push(` ${item[0]} = ${item[1]} `)
					}
				}
			
			})
			condition = condition.join(',')
			sql = `UPDATE ${dbTable} SET ${condition} where id = ${data.id}`
			return this.SqlExecute(sql)
		}catch(e){
			console.log(e)
			//TODO handle the exception
		}
		
	},
	JsDelete(dbTable,data){
		var sql = ''
		// debugger
		var condition = []
		try{
			if (data.constructor == Number) {
				sql = `DELETE FROM ${dbTable} where id = ${data}`
			} else {
				Object.entries(data).forEach(item => {
					if (item[1] != undefined && item[0] != 'id') {
						if (typeof(item[1] == 'string')) {
							condition.push(` ${item[0]} = '${item[1]}' `)
						} else {
							condition.push(` ${item[0]} = ${item[1]} `)
						}
					}
			
				})
				condition = condition.join('AND')
				sql = `Delete FROM ${dbTable} WHERE ${condition}`
			}
			return this.SqlExecute(sql)
		}catch(e){
			console.log(e)
		}
		
	}
}

业务控制文件,通过原型链赋予多个参数
DB_Entity.js

const SqlHelper = require('@/utils/SqlHelper.js')
//时间格式化封装
Date.prototype.format = function(fmt) {
	if(fmt == undefined){
		fmt = 'yyyy-MM-dd hh:mm:ss'
	}
	var o = {
		'M+': this.getMonth() + 1, //月份 
		'd+': this.getDate(), //日 
		'h+': this.getHours(), //小时 
		'm+': this.getMinutes(), //分 
		's+': this.getSeconds(), //秒 
		'q+': Math.floor((this.getMonth() + 3) / 3), //季度 
		'S': this.getMilliseconds() //毫秒 
	}
	if (/(y+)/.test(fmt)) {
		fmt = fmt.replace(RegExp.$1, (this.getFullYear() + '').substr(4 - RegExp.$1.length))
	}
	for (var k in o) {
		if (new RegExp('(' + k + ')').test(fmt)) {
			fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k])
				.length)))
		}
	}
	return fmt
}

//测试单
function TestTask(){
	this.dtName='TestTask'
	this.data = {
		number:'测试编号',
		testLine:'测试线路',
		location:'测试地点',
		testUnit:'测试厂家',
		tester:'测试人员',
		electricity:'220kv',
		createTime:new Date().format()
	}
}
//测试段,每个测试单对应多个测试段
function TestSection(){
	this.dtName='TestSection'
	this.data={
		taskId:1,//测试单id
		sectionName:'测试段名称',
		node1:'节点1',
		node2:'节点2'
	}
}
//测试功能,每个测试段可以触发多个测试功能,这个作为测试功能使用
function TestFunction(){
	this.dtName='TestFunction'
	this.data={
		taskId:1,//测试单id
		sectionId:1,//测试段id
		Rab:1.1,
		Rbc:2.2,
		Rac:3.3,
	}
}

var Entity=[]//用于批量赋予数据库操作原型
var DT = {}//用于设置数据库对象
Entity.push(TestTask)
Entity.push(TestSection)
Entity.push(TestFunction)

Entity.forEach(item=>{
	item.prototype = {
		GetData(){
			return this.data
		},
		IsOpen(){
			if(!SqlHelper.isOpen()){
				SqlHelper.openSqlite()
			}
			return SqlHelper.isOpen()
		},
		Drop(){
			SqlHelper.dropTable(this.dtName)
		}
		,
		Init(){
			this.IsOpen()
		 	return SqlHelper.JsCreateTableType(this.dtName,this.data)
		},
		Insert(data){
			this.IsOpen()
			return SqlHelper.JsInsertTableData(this.dtName,data)
		},
		Select(data){
			this.IsOpen()
			return SqlHelper.JsSelectTableData(this.dtName,data)
		},
		Update(data){
			this.IsOpen()
			return SqlHelper.JsUpdate(this.dtName,data)
		},
		Delete(data){
			this.IsOpen()
			return SqlHelper.JsDelete(this.dtName,data)
		}
	}
	var model = new item()
	DT[model.dtName] = item
	// console.log(new item().GetData())
})




module.exports={
	DT:DT,
	Init(){//创建
		this.DT.forEach(item=>{
			new item().Init()
		})
	},
	ReInit(){//重新创建
		this.DT.forEach(item=>{
			new item().Drop()
		})
		this.Init()
	},
	SqlHelper:SqlHelper
}

在main.js里面全局引用

import DB_Entity from '@/utils/mapper/DB_Entity.js'
Vue.prototype.$DB = DB_Entity

代码使用:
注意,我这里把所有的操作都封装成了Promise,推荐使用ayanc和await来控制异步

const DB_Entity = require('@/utils/mapper/DB_Entity.js')


......
		TestBtn() {
			// console.log(DB_Entity.DT)
			var DT_Model = DB_Entity.DT.TestFunction
			var model = new DT_Model()

			var model_data = model.GetData()

			async function action() {
				await model.Init()
				await model.IsOpen()
				await model.Insert(model_data).then(res=>{
					console.log(res)
				}).catch(
					err=>{
						console.log(err)
					}
				)
				await model.Select(model_data).then(res => {
					model_data = res[0]
					console.log(res)
				})
				model_data.taskId = 2
			
				await model.Update(model_data).then(res=>{
					console.log(res)
				}).catch(err=>{
					console.log(err)
				})
				console.log('更新')
				await model.Select(model_data).then(res=>console.log(res))
				await model.Delete(model_data)
				
				

			}
			
			action()


		},

测试结果

存在多次打印

15:22:35.486 CREATE TABLE IF NOT EXISTS TestFunction("id" INTEGER PRIMARY KEY AUTOINCREMENT,taskId INTEGER,sectionId INTEGER,Rab REAL,Rbc REAL,Rac REAL) at utils/SqlHelper.js:69
15:22:35.495 INSERT INTO TestFunction ('taskId','sectionId','Rab','Rbc','Rac') VALUES(1,1,1.1,2.2,3.3) at utils/SqlHelper.js:69
15:22:35.503 [Object] {}  at pages/report/report_add/index.js:79
15:22:35.506 SELECT * FROM TestFunction WHERE  taskId = '1' AND sectionId = '1' AND Rab = '1.1' AND Rbc = '2.2' AND Rac = '3.3'  at utils/SqlHelper.js:87
15:22:35.514 [Object] [{"id":2,"taskId":1,"sectionId":1,"Rab":1.1,"Rbc":2.2,"Rac":3.3},{"id":3,"taskId":1,"sectio...} at utils/SqlHelper.js:93
15:22:35.518 [Object] [{"id":2,"taskId":1,"sectionId":1,"Rab":1.1,"Rbc":2.2,"Rac":3.3},{"id":3,"taskId":1,"sectio...} at pages/report/report_add/index.js:87
15:22:35.520 UPDATE TestFunction SET  taskId = '2' , sectionId = '1' , Rab = '1.1' , Rbc = '2.2' , Rac = '3.3'  where id = 2 at utils/SqlHelper.js:69
15:22:35.529 [Object] {}  at pages/report/report_add/index.js:92
15:22:35.534 更新 at pages/report/report_add/index.js:96
15:22:35.536 SELECT * FROM TestFunction WHERE  taskId = '2' AND sectionId = '1' AND Rab = '1.1' AND Rbc = '2.2' AND Rac = '3.3'  at utils/SqlHelper.js:87
15:22:35.540 [Object] [{"id":2,"taskId":2,"sectionId":1,"Rab":1.1,"Rbc":2.2,"Rac":3.3}]  at utils/SqlHelper.js:93
15:22:35.542 [Object] [{"id":2,"taskId":2,"sectionId":1,"Rab":1.1,"Rbc":2.2,"Rac":3.3}]  at pages/report/report_add/index.js:97
15:22:35.548 Delete FROM TestFunction WHERE  taskId = '2' AND sectionId = '1' AND Rab = '1.1' AND Rbc = '2.2' AND Rac = '3.3'  at utils/SqlHelper.js:69

封装代码更新记录

2023年6月13日

添加数据库修改列,数据库重建功能,优化了部分代码逻辑

我们在开发的过程中,数据库的列经常会增减,但是由于sqlite的特点,无法删除列,只能增加列。我们可以尝试直接删除然后重新添加的方法,但是这样数据也就随之没有了

感谢这篇博客提供的sql语句
在SQLite现有表的指定列后面,使用SQL添加新列

代码部分

SqlHelper


module.exports = {
	dbName: 'Bluetooth', // 数据库名称
	dbPath: '_downloads/Bluetooth.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:'DROP TABLE dbTable'
	dropTable(dbTable) {
		console.log(`DROP TABLE ${dbTable}`)
		return new Promise((resolve, reject) => {
			plus.sqlite.executeSql({
				name: this.dbName,
				sql: `DROP TABLE ${dbTable}`,
				success(e) {
					resolve(e)
				},
				fail(e) {
					reject(e)
				}
			})
		})
	},
	//-----------------------js对象方法,简化操作-------------
	///原生的sql操作
	SqlExecute(sql) {
		console.log(sql)
		return new Promise((resolve, reject) => {
			plus.sqlite.executeSql({
				name: this.dbName,
				sql: sql,
				success(e) {
					// console.log(e)
					resolve(e)
				},
				fail(e) {
					console.log(e)
					reject(e)
				}
			})
		})
	},
	//执行原生的select语句
	Select(sql) {
		console.log(sql)
		return new Promise((resolve, reject) => {
			plus.sqlite.selectSql({
				name: this.dbName,
				sql: sql,
				success(e) {
					console.log(e)
					resolve(e)
				},
				fail(e) {
					console.log(e)
					reject(e)
				}
			})
		})
	},
	//通过对象创建数据库,使用对象参数
	JsCreateTable(dbTable, data) {
		data = Object.entries(data).map(item => {
			return item[0] + ' ' + item[1]
		}).join(',')


		var sql = `CREATE TABLE IF NOT EXISTS ${dbTable}("id" INTEGER PRIMARY KEY AUTOINCREMENT,${data})`
		return this.SqlExecute(sql)
	},
	//通过对象创建数据库,使用对象的数据类型
	JsCreateTableType(dbTable, data) {
		data = Object.entries(data).map(item => {
			var typeName = ''
			switch (item[1].constructor) {
				case Number:
					if (Math.floor(item[1]) == item[1]) {
						typeName = 'INTEGER'
					} else {
						typeName = 'REAL'
					}
					break
				case String:
					typeName = 'TEXT'
					break
				case Boolean:
					typeName = 'BOOLEAN'
					break
				case Date:
					typeName = 'TEXT'
					break
			}
			return item[0] + ' ' + typeName
		}).join(',')


		var sql = `CREATE TABLE IF NOT EXISTS ${dbTable}("id" INTEGER PRIMARY KEY AUTOINCREMENT,${data})`
		// console.log(sql)
		return this.SqlExecute(sql)
	},
	GetCol(dbTable){//uniapp 的sqlite不支持直接查询数据列名
		var that = this
		async function action(){
			try{
				return that.Select(`PRAGMA table_info(${dbTable})`).then(res=>{
					console.log(res)
				}).catch(err=>{
					console.log(err)
				})
			}catch(e){
				console.log(e)
			}
		}
		
		action()
	}
	,
	JsReInit(dbTable,oldData,newData){
		var that = this
		var columnOld = []
		var columnNew = []
		var saveCol = ['id']//保留的列
		var addCol = []//增加的列
		
		for(var key in oldData){
			columnOld.push(key)
		}
		
		for(var key in oldData){
			columnNew.push(key)
		}
		columnOld.forEach(item => {
		    if (columnNew.includes(item)) {
		        saveCol.push(item)
		    }
		})
		
		columnNew.forEach(item => {
		    if (!columnOld.includes(item)) {//找到新列增加的
		        addCol.push(item)
		    }
		})
		
		addCol =addCol.join(',')
		console.log(saveCol)
		saveCol = saveCol.join(',')
		var that =this
		var sqlStrs = []
		backup_table = dbTable + '_backup' + new Date().format()
		sqlStrs.push(`alter table ${dbTable} rename to ${backup_table}`)
		sqlStrs.push(`insert into ${dbTable}(${saveCol}) select ${saveCol} from ${backup_table}`)
		// sqlStrs.push(`drop table ${backup_table}`)
		console.log(sqlStrs)
		async function action(){
			try{
				await that.SqlExecute(sqlStrs[0])
				await that.JsCreateTableType(dbTable,newData)//创建新数据库
				await that.SqlExecute(sqlStrs[1])
				// await that.SqlExecute(sqlStrs[2])
			}catch(e){
				//TODO handle the exception
				console.log(e)
			}
			
		}
		
		
		action()
		
	},
	//通过对象插入数据
	JsInsertTableData(dbTable, data) {
		var condition = []
		var sqlValue = []
		Object.entries(data).forEach(item => {
			condition.push(`'${item[0]}'`)
			if (item[1] != undefined) {
				if (item[1].constructor == String) {
					sqlValue.push(`'${item[1]}'`)
				} else if (item[1].constructor == Date) {

					sqlValue.push(`'${item[1].format('yyyy-MM-dd hh:mm:ss')}'`)
				} else {
					sqlValue.push(item[1])
				}
			}
		})
		condition = condition.join(',')
		sqlValue = sqlValue.join(',')
		var sql = `INSERT INTO ${dbTable} (${condition}) VALUES(${sqlValue})`
		return this.SqlExecute(sql)
	},
	//通过对象选择数据
	JsSelectTableData(dbTable, data) {
		var sql = ''
		var condition = []
		if (data == undefined || data == null || data == {}) {
			sql = `SELECT * FROM ${dbTable}`
		} else if(data.constructor == Number){
			sql = `SELECT * FROM ${daTable} where id = ${data}`
		} else {
			Object.entries(data).forEach(item => {
				if (item[1] != undefined && item[0] != 'id') {
					if (typeof(item[1] == 'string')) {
						condition.push(` ${item[0]} = '${item[1]}' `)
					} else {
						condition.push(` ${item[0]} = ${item[1]} `)
					}
				}

			})
			condition = condition.join('AND')
			sql = `SELECT * FROM ${dbTable} WHERE ${condition}`
		}


		return this.Select(sql)
	},
	//通过对象获取
	JsUpdate(dbTable, data) {
		try{
			var sql = ''
			var condition = []
			Object.entries(data).forEach(item => {
				if (item[1] != undefined && item[0] != 'id') {
					if (typeof(item[1] == 'string')) {
						condition.push(` ${item[0]} = '${item[1]}' `)
					} else {
						condition.push(` ${item[0]} = ${item[1]} `)
					}
				}
			
			})
			condition = condition.join(',')
			sql = `UPDATE ${dbTable} SET ${condition} where id = ${data.id}`
			return this.SqlExecute(sql)
		}catch(e){
			console.log(e)
			//TODO handle the exception
		}
		
	},
	JsDelete(dbTable,data){
		var sql = ''
		// debugger
		var condition = []
		try{
			if(data.id != undefined || data.id!= null){
				sql = `DELETE FROM ${dbTable} where id = ${data.id}`
			}else if (data.constructor == Number) {
				sql = `DELETE FROM ${dbTable} where id = ${data}`
			} else {
				Object.entries(data).forEach(item => {
					if (item[1] != undefined && item[0] != 'id') {
						if (typeof(item[1] == 'string')) {
							condition.push(` ${item[0]} = '${item[1]}' `)
						} else {
							condition.push(` ${item[0]} = ${item[1]} `)
						}
					}
			
				})
				condition = condition.join('AND')
				sql = `Delete FROM ${dbTable} WHERE ${condition}`
			}
			return this.SqlExecute(sql)
		}catch(e){
			console.log(e)
		}
		
	}
}

DB_Entity

const SqlHelper = require('@/utils/SqlHelper.js')


Date.prototype.format = function(fmt) {
	if(fmt == undefined){
		fmt = 'yyyy-MM-dd hh:mm:ss'
	}
	var o = {
		'M+': this.getMonth() + 1, //月份 
		'd+': this.getDate(), //日 
		'h+': this.getHours(), //小时 
		'm+': this.getMinutes(), //分 
		's+': this.getSeconds(), //秒 
		'q+': Math.floor((this.getMonth() + 3) / 3), //季度 
		'S': this.getMilliseconds() //毫秒 
	}
	if (/(y+)/.test(fmt)) {
		fmt = fmt.replace(RegExp.$1, (this.getFullYear() + '').substr(4 - RegExp.$1.length))
	}
	for (var k in o) {
		if (new RegExp('(' + k + ')').test(fmt)) {
			fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k])
				.length)))
		}
	}
	return fmt
}
//测试单
function TestTask(){
	this.dtName='TestTask'
	this.data = {
		number:'测试编号',
		testLine:'测试线路',
		location:'测试地点',
		location_index:'0-0-0',
		province:'XX省',
		city:'XX市',
		area:'XX区',
		testUnit:'测试厂家',
		tester:'测试人员',
		electricity:'220kv',
		mode:'测试方式',
		isSave:0,
		createTime:new Date().format()
	}
}
//测试段,每个测试单对应多个测试段
function TestSection(){
	this.dtName='TestSection'
	this.data={
		taskId:1,//测试单id
		get sectionName(){
			return `${this.node1} ~ ${this.node2}`
		},
		sectionLength:1000,
		node1:'节点1',
		node2:'节点2',
		startNode:0,
		endNode:1000,
		factory:'XX'
	}
}
//测试功能,每个测试段可以触发多个测试功能,这个作为测试功能使用
function TestFunction(){
	this.dtName='TestFunction'
	this.data={
		taskId:1,//测试单id
		sectionId:1,//测试段id
		RA:0.0,
		RB:0.0,
		RC:0.0,
		value4:0.0,
		RA_status:'正常',
		RB_status:'正常',
		RC_status:'正常',
		
		RA_description : 'A相描述',
		RB_description : 'B相描述',
		RC_description : 'C相描述',
		status:'0000',
		electric:0.0,
		voltage: 0.0,
		mode:'单端接地',
		createTime:new Date().format()
	}
}

var Entity=[]//用于批量赋予数据库操作原型
var DT = {}//用于设置数据库对象
Entity.push(TestTask)
Entity.push(TestSection)
Entity.push(TestFunction)

Entity.forEach(item=>{
	item.prototype = {
		GetData(){
			return this.data
		},
		IsOpen(){
			if(!SqlHelper.isOpen()){
				SqlHelper.openSqlite()
			}
			return SqlHelper.isOpen()
		},
		Drop(){
			SqlHelper.dropTable(this.dtName)
		},
		Init(){
			this.IsOpen()
		 	return SqlHelper.JsCreateTableType(this.dtName,this.data)
		},
		ReInit(newData){
			return SqlHelper.JsReInit(this.dtName,this.data,newData)
		},
		TestInsert(){
			return SqlHelper.JsInsertTableData(this.dtName,this.data)
		},
		Insert(data){
			this.IsOpen()
			return SqlHelper.JsInsertTableData(this.dtName,data)
		},
		Select(data){
			this.IsOpen()
			return SqlHelper.JsSelectTableData(this.dtName,data)
		},
		Update(data){
			this.IsOpen()
			return SqlHelper.JsUpdate(this.dtName,data)
		},
		Delete(data){
			this.IsOpen()
			return SqlHelper.JsDelete(this.dtName,data)
		}
	}
	var model = new item()
	DT[model.dtName] = model 
	// console.log(new item().GetData())
})




module.exports={
	DT:DT,
	Init(){//创建
		SqlHelper.openSqlite()
		Entity.forEach(item=>{
			new item().Init()
		})
	},
	ReInit(){//重新创建
		Entity.forEach(item=>{
			new item().Drop()
		})
		this.Init()
	},
	SqlHelper:SqlHelper
}
更新逻辑
重命名
复制数据
table`旧`
table_old
table`新`

因为我们更新包括删除和增加列,删除列会导致数据丢失。所以我将所有的table_old 都加了个时间戳,进行保存

我尝试过直接获取列名,但是uniapp的sqlite不支持该语句

PRAGMA table_info(tableName)。所以代码需要有两个对象,一个是旧数据库的data,一个是新数据库的data

如何运行

将原表的数据修改

在这里插入图片描述

var that = this
var oldData= {//这个是原来数据库的数据
	......
}
var DB = new that.$DB.DT.TestTask()
async function action(){
	try{
		await DB.ReInit(oldData)//重建就行了
		
		var res =await DB.Select()
		console.log('---------------------')
	}catch(e){ 
		//TODO handle the exception
		console.log(e)
	}

运行成功,新增的列是null

在这里插入图片描述

封装代码更新 2023年7月14日

根据实际使用的情况。发现数据表名称还是主动键入好一点

//一层遍历
function GetParam(obj) {
	var res = []
	for (var key in obj) {
		if (obj[key] != undefined) {
			if (obj[key] != '') {
				res.push([key, obj[key]])
			}
		}
	}
	res = res.map(item => {
		if (item[1].constructor == String) {
			console.log('成功')
			item[1] = `'${item[1]}'`
		}
		return item.join('=')
	})
	res = res.join(' AND ')
	if (res != '') {
		res = ' where ' + res
	}
	return res
}
//得到对象个数
function GetCount(data){
    var count = 0
    for(var key in data){
        count++
    }

    return count
}
//二层遍历
function GetParam2(data, _condition) {
	var res = []
	for (var key1 in data) {
		for (var key2 in data[key1]) {
			var value = data[key1][key2]
			if (value != undefined && value != '') {
				res.push([`${key1}.${key2}`, value])
			}
		}
	}

	res = res.map(item => {
		if (item[1].constructor == String) {
			return `${item[0]} = '${item[1]}'`
		} else {
			return item.join('=')
		}
	})
	if (_condition != undefined) {
		res = res.concat(_condition)
	}
	res = res.join(' AND ')
	if (res != '') {
		res = ' where ' + res
	}
	return res
}
//得到对象深度
function GetDeep(obj) {
	// console.log(obj)
	var res = 1;
	(function myDeep(obj, num) {
		if (typeof obj === 'object') {
			for (var key in obj) {
				if (typeof obj[key] === 'object') {
					myDeep(obj[key], num + 1);
				} else {
					res = res < num + 1 ? num + 1 : res;
				}
			}
		} else {
			res = res > num ? res : num;
		}
	})(obj, 1)

	// console.log('lalal')
	return res;
}
module.exports = {
	dbName: 'Bluetooth', // 数据库名称
	dbPath: '_downloads/Bluetooth.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) {
					console.log(e)
					resolve(e) // 成功回调
				},
				fail(e) {
					console.log(e)
					reject(e) // 失败回调
				}
			})
		})
	},

	// 关闭数据库
	closeSqlite() {
		return new Promise((resolve, reject) => {
			plus.sqlite.closeDatabase({
				name: this.dbName,
				success(e) {
					resolve(e)
				},
				fail(e) {
					reject(e)
				}
			})
		})
	},
	// 数据库删表 sql:'DROP TABLE dbTable'
	dropTable(dbTable) {
		console.log(`DROP TABLE ${dbTable}`)
		return new Promise((resolve, reject) => {
			plus.sqlite.executeSql({
				name: this.dbName,
				sql: `DROP TABLE ${dbTable}`,
				success(e) {
					resolve(e)
				},
				fail(e) {
					reject(e)
				}
			})
		})
	},
	//-----------------------js对象方法,简化操作-------------
	///原生的sql操作
	SqlExecute(sql) {
		console.log(sql)
		return new Promise((resolve, reject) => {
			plus.sqlite.executeSql({
				name: this.dbName,
				sql: sql,
				success(e) {
					// console.log(e)
					resolve(e)
				},
				fail(e) {
					console.log(e)
					reject(e)
				}
			})
		})
	},
	//执行原生的select语句
	Select(sql) {
		console.log(sql)
		return new Promise((resolve, reject) => {
			plus.sqlite.selectSql({
				name: this.dbName,
				sql: sql,
				success(e) {
					console.log(e)
					resolve(e)
				},
				fail(e) {
					console.log(e)
					reject(e)
				}
			})
		})
	},
	//通过对象创建数据库,使用对象参数
	JsCreateTable(dbTable, data) {
		data = Object.entries(data).map(item => {
			return item[0] + ' ' + item[1]
		}).join(',')


		var sql = `CREATE TABLE IF NOT EXISTS ${dbTable}("id" INTEGER PRIMARY KEY AUTOINCREMENT,${data})`
		return this.SqlExecute(sql)
	},
	//通过对象创建数据库,使用对象的数据类型
	JsCreateTableType(dbTable, data) {
		data = Object.entries(data).map(item => {
			var typeName = ''
			switch (item[1].constructor) {
				case Number:
					if (Math.floor(item[1]) == item[1]) {
						typeName = 'INTEGER'
					} else {
						typeName = 'REAL'
					}
					break
				case String:
					typeName = 'TEXT'
					break
				case Boolean:
					typeName = 'BOOLEAN'
					break
				case Date:
					typeName = 'TEXT'
					break
			}
			return item[0] + ' ' + typeName
		}).join(',')


		var sql = `CREATE TABLE IF NOT EXISTS ${dbTable}("id" INTEGER PRIMARY KEY AUTOINCREMENT,${data})`
		// console.log(sql)
		return this.SqlExecute(sql)
	},
	GetCol(dbTable) { //uniapp 的sqlite不支持直接查询数据列名
		var that = this
		async function action() {
			try {
				return that.Select(`PRAGMA table_info(${dbTable})`).then(res => {
					console.log(res)
				}).catch(err => {
					console.log(err)
				})
			} catch (e) {
				console.log(e)
			}
		}

		action()
	},
	JsReInit(dbTable, newData, oldData) {
		var that = this
		var columnOld = []
		var columnNew = []
		var saveCol = ['id'] //保留的列
		var addCol = [] //增加的列

		for (var key in oldData) {
			columnOld.push(key)
		}

		for (var key in oldData) {
			columnNew.push(key)
		}
		columnOld.forEach(item => {
			if (columnNew.includes(item)) {
				saveCol.push(item)
			}
		})

		columnNew.forEach(item => {
			if (!columnOld.includes(item)) { //找到新列增加的
				addCol.push(item)
			}
		})

		addCol = addCol.join(',')
		console.log(saveCol)
		saveCol = saveCol.join(',')
		var that = this
		var sqlStrs = []
		backup_table = dbTable + '_backup' + new Date().format()
		sqlStrs.push(`alter table ${dbTable} rename to ${backup_table}`)
		sqlStrs.push(`insert into ${dbTable}(${saveCol}) select ${saveCol} from ${backup_table}`)
		// sqlStrs.push(`drop table ${backup_table}`)
		console.log(sqlStrs)
		async function action() {
			try {
				await that.SqlExecute(sqlStrs[0])
				await that.JsCreateTableType(dbTable, newData) //创建新数据库
				await that.SqlExecute(sqlStrs[1])
				// await that.SqlExecute(sqlStrs[2])
			} catch (e) {
				//TODO handle the exception
				console.log(e)
			}

		}
		action()

	},
	//通过对象插入数据
	JsInsertTableData(dbTable, data) {
		var condition = []
		var sqlValue = []
		Object.entries(data).forEach(item => {
			if (item[1] != undefined) {
				condition.push(`'${item[0]}'`)
				if (item[1].constructor == String) {
					sqlValue.push(`'${item[1]}'`)
				} else if (item[1].constructor == Date) {

					sqlValue.push(`'${item[1].format('yyyy-MM-dd hh:mm:ss')}'`)
				} else {
					sqlValue.push(item[1])
				}
			}
		})
		condition = condition.join(',')
		sqlValue = sqlValue.join(',')
		var sql = `INSERT INTO ${dbTable} (${condition}) VALUES(${sqlValue})`
		return this.SqlExecute(sql)
	},
	//通过对象选择数据
	JsSelectTableData(dbTable, data) {
		var sql = ''
		var condition = []
		if (data == undefined || data == null || data == {}) {
			sql = `SELECT * FROM ${dbTable}`
		} else if (data.constructor == Number) {
			sql = `SELECT * FROM ${daTable} where id = ${data}`
		} else {
			Object.entries(data).forEach(item => {
				if (item[1] != undefined && item[0] != 'id') {
					if (typeof(item[1] == 'string')) {
						if (item[1] == '') {
							condition.push(` ${item[0]} = '${item[1]}' `)
						}
					} else {
						condition.push(` ${item[0]} = ${item[1]} `)
					}
				}
			})
			condition = condition.join('AND')
			sql = `SELECT * FROM ${dbTable} WHERE ${condition}`
		}
		return this.Select(sql)
	},
	//通过对象深度取值
	JsSelect(data) {
		var sql = ''
		var tableName = []
		var condition = ''
		var deep = GetDeep(data)
		if(deep == 3){
			if(GetCount(data) == 1){
				for(var key in data){
					tableName = key
					data= data[key]
					break
				}
				condition = GetParam(data)
			}else{
				condition = GetParam2(data)
				for(var key in data){
					tableName.push(key)
				}
				tableName = tableName.join(',') + ' '
			}
		}else{
			console.log(data,'对象深度应为3')
		}
		sql = 'select * from ' + tableName + condition
		// console.log(sql)
		return this.Select(sql)
	},

	//通过对象获取
	JsUpdate(dbTable, data) {
		try {
			var sql = ''
			var condition = []
			Object.entries(data).forEach(item => {
				if (item[1] != undefined && item[0] != 'id') {
					if (typeof(item[1] == 'string')) {
						condition.push(` ${item[0]} = '${item[1]}' `)
					} else {
						condition.push(` ${item[0]} = ${item[1]} `)
					}
				}

			})
			condition = condition.join(',')
			sql = `UPDATE ${dbTable} SET ${condition} where id = ${data.id}`
			return this.SqlExecute(sql)
		} catch (e) {
			console.log(e)
			//TODO handle the exception
		}

	},
	JsDelete(dbTable, data) {
		var sql = ''
		// debugger
		var condition = []
		try {
			if (data.id != undefined || data.id != null) {
				sql = `DELETE FROM ${dbTable} where id = ${data.id}`
			} else if (data.constructor == Number) {
				sql = `DELETE FROM ${dbTable} where id = ${data}`
			} else {
				Object.entries(data).forEach(item => {
					if (item[1] != undefined && item[0] != 'id') {
						if (typeof(item[1] == 'string')) {
							condition.push(` ${item[0]} = '${item[1]}' `)
						} else {
							condition.push(` ${item[0]} = ${item[1]} `)
						}
					}

				})
				condition = condition.join('AND')
				sql = `Delete FROM ${dbTable} WHERE ${condition}`
			}
			return this.SqlExecute(sql)
		} catch (e) {
			console.log(e)
		}

	}
}

使用举例

//引入文件
const $sqlHelper = require('@/utils/SqlHelper.js')//文件相对位置
//打开数据库
$sqlHelper.openSqlite()
//创建数据表
$sqlHelper.JsCreateTableType('tableName',{//主动添加id且为自动递增
	Name:'小王',
	Age:1,
	Sex:'女'
})
//插入数据
$sqlHelper.JsInsertTableData('tableName',{
	Name:'小王',
	Age:1,
	Sex:'女'
})
//查询数据
$sqlHelper.Select('select * from tableName')//sql直接查询
$sqlHelper.JsSelect({//条件判断查询
	TestDB:{
		Age:4
	}
})


日期2023年10月7日,添加字段自动添加

//一层遍历
function GetParam(obj) {
	// console.log(obj)
	var res = []
	for (var key in obj) {
		// console.log(key,obj[key])
		if (obj[key] != undefined) {
			if (obj[key] !== '') {
				// console.log(key,obj[key])
				res.push([key, obj[key]])
			}
		}
	}
	// console.log(res)
	res = res.map(item => {
		if (item[1].constructor == String) {
			console.log('成功')
			item[1] = `'${item[1]}'`
		}
		return item.join('=')
	})
	res = res.join(' AND ')
	if (res != '') {
		res = ' where ' + res
	}
	// console.log(res)
	return res
}
//得到对象个数
function GetCount(data) {
	var count = 0
	for (var key in data) {
		count++
	}

	return count
}
//二层遍历
function GetParam2(data, _condition) {
	var res = []
	for (var key1 in data) {
		for (var key2 in data[key1]) {
			var value = data[key1][key2]
			if (value != undefined && value != '') {
				res.push([`${key1}.${key2}`, value])
			}
		}
	}

	res = res.map(item => {
		if (item[1].constructor == String) {
			return `${item[0]} = '${item[1]}'`
		} else {
			return item.join('=')
		}
	})
	if (_condition != undefined) {
		res = res.concat(_condition)
	}
	res = res.join(' AND ')
	if (res != '') {
		res = ' where ' + res
	}
	return res
}
//得到对象深度
function GetDeep(obj) {
	// console.log(obj)
	var res = 1;
	(function myDeep(obj, num) {
		if (typeof obj === 'object') {
			for (var key in obj) {
				if (typeof obj[key] === 'object') {
					myDeep(obj[key], num + 1)
				} else {
					res = res < num + 1 ? num + 1 : res
				}
			}
		} else {
			res = res > num ? res : num
		}
	})(obj, 1)

	// console.log('lalal')
	return res
}
module.exports = {
	dbName: 'Bluetooth', // 数据库名称
	dbPath: '_downloads/Bluetooth.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) {
					console.log(e)
					resolve(e) // 成功回调
				},
				fail(e) {
					console.log(e)
					reject(e) // 失败回调
				}
			})
		})
	},

	// 关闭数据库
	closeSqlite() {
		return new Promise((resolve, reject) => {
			plus.sqlite.closeDatabase({
				name: this.dbName,
				success(e) {
					resolve(e)
				},
				fail(e) {
					reject(e)
				}
			})
		})
	},
	// 数据库删表 sql:'DROP TABLE dbTable'
	dropTable(dbTable) {
		console.log(`DROP TABLE ${dbTable}`)
		return new Promise((resolve, reject) => {
			plus.sqlite.executeSql({
				name: this.dbName,
				sql: `DROP TABLE ${dbTable}`,
				success(e) {
					resolve(e)
				},
				fail(e) {
					reject(e)
				}
			})
		})
	},
	//-----------------------js对象方法,简化操作-------------
	///原生的sql操作
	SqlExecute(sql) {
		console.log(sql)
		return new Promise((resolve, reject) => {
			plus.sqlite.executeSql({
				name: this.dbName,
				sql: sql,
				success(e) {
					// console.log(e)
					resolve(e)
				},
				fail(e) {
					console.log(e)
					reject(e)
				}
			})
		})
	},
	//执行原生的select语句
	Select(sql) {
		console.log(sql)
		return new Promise((resolve, reject) => {
			plus.sqlite.selectSql({
				name: this.dbName,
				sql: sql,
				success(e) {
					console.log(e)
					resolve(e)
				},
				fail(e) {
					console.log(e)
					reject(e)
				}
			})
		})
	},
	//通过对象创建数据库,使用对象参数
	JsCreateTable(dbTable, data) {
		data = Object.entries(data).map(item => {
			return item[0] + ' ' + item[1]
		}).join(',')


		var sql =
			`CREATE TABLE IF NOT EXISTS ${dbTable}("id" INTEGER PRIMARY KEY AUTOINCREMENT,"createTime" TimeStamp NOT NULL DEFAULT (datetime('now','localtime')),${data})`
		return this.SqlExecute(sql)
	},
	//通过对象创建数据库,使用对象的数据类型
	JsCreateTableType(dbTable, data) {
		data = Object.entries(data).map(item => {
			var typeName = ''
			switch (item[1].constructor) {
				case Number:
					if (Math.floor(item[1]) == item[1]) {
						typeName = 'INTEGER'
					} else {
						typeName = 'REAL'
					}
					break
				case String:
					typeName = 'TEXT'
					break
				case Boolean:
					typeName = 'BOOLEAN'
					break
				case Date:
					typeName = 'TEXT'
					break
			}
			return item[0] + ' ' + typeName
		}).join(',')


		var sql =
			`CREATE TABLE IF NOT EXISTS ${dbTable}("id" INTEGER PRIMARY KEY AUTOINCREMENT,"createTime" TimeStamp NOT NULL DEFAULT (datetime('now','localtime')),${data})`
		// console.log(sql)
		return this.SqlExecute(sql)
	},
	GetCol(dbTable) { //uniapp 的sqlite不支持直接查询数据列名
		var that = this
		async function action() {
			try {
				return that.Select(`PRAGMA table_info(${dbTable})`).then(res => {
					console.log(res)
				}).catch(err => {
					console.log(err)
				})
			} catch (e) {
				console.log(e)
			}
		}

		action()
	},
	JsReInit(dbTable, newData, oldData) {
		var that = this
		var columnOld = []
		var columnNew = []
		var saveCol = ['id'] //保留的列
		var addCol = [] //增加的列

		for (var key in oldData) {
			columnOld.push(key)
		}

		for (var key in oldData) {
			columnNew.push(key)
		}
		columnOld.forEach(item => {
			if (columnNew.includes(item)) {
				saveCol.push(item)
			}
		})

		columnNew.forEach(item => {
			if (!columnOld.includes(item)) { //找到新列增加的
				addCol.push(item)
			}
		})

		addCol = addCol.join(',')
		console.log(saveCol)
		saveCol = saveCol.join(',')
		var that = this
		var sqlStrs = []
		backup_table = dbTable + '_backup' + new Date().format()
		sqlStrs.push(`alter table ${dbTable} rename to ${backup_table}`)
		sqlStrs.push(`insert into ${dbTable}(${saveCol}) select ${saveCol} from ${backup_table}`)
		// sqlStrs.push(`drop table ${backup_table}`)
		console.log(sqlStrs)
		async function action() {
			try {
				await that.SqlExecute(sqlStrs[0])
				await that.JsCreateTableType(dbTable, newData) //创建新数据库
				await that.SqlExecute(sqlStrs[1])
				// await that.SqlExecute(sqlStrs[2])
			} catch (e) {
				//TODO handle the exception
				console.log(e)
			}

		}
		action()

	},
	//通过对象插入数据
	JsInsertTableData(dbTable, data) {
		var condition = []
		var sqlValue = []
		Object.entries(data).forEach(item => {
			if (item[1] != undefined) {
				condition.push(`'${item[0]}'`)
				if (item[1].constructor == String) {
					sqlValue.push(`'${item[1]}'`)
				} else if (item[1].constructor == Date) {

					sqlValue.push(`'${item[1].format('yyyy-MM-dd hh:mm:ss')}'`)
				} else {
					sqlValue.push(item[1])
				}
			}
		})
		condition = condition.join(',')
		sqlValue = sqlValue.join(',')
		var sql = `INSERT INTO ${dbTable} (${condition}) VALUES(${sqlValue})`
		return this.SqlExecute(sql)
	},
	//通过对象选择数据
	JsSelectTableData(dbTable, data) {
		var sql = ''
		var condition = []
		if (data == undefined || data == null || data == {}) {
			sql = `SELECT * FROM ${dbTable}`
		} else if (data.constructor == Number) {
			sql = `SELECT * FROM ${daTable} where id = ${data}`
		} else {
			Object.entries(data).forEach(item => {
				if (item[1] != undefined && item[0] != 'id') {
					if (typeof(item[1] == 'string')) {
						if (item[1] == '') {
							condition.push(` ${item[0]} = '${item[1]}' `)
						}
					} else {
						condition.push(` ${item[0]} = ${item[1]} `)
					}
				}
			})
			condition = condition.join('AND')
			sql = `SELECT * FROM ${dbTable} WHERE ${condition}`
		}
		return this.Select(sql)
	},
	//通过对象深度取值
	JsSelect(data) {
		var sql = ''
		var tableName = []
		var condition = ''
		var deep = GetDeep(data)
		if (deep == 3) {
			if (GetCount(data) == 1) {
				for (var key in data) {
					tableName = key
					data = data[key]
					break
				}
				condition = GetParam(data)
			} else {
				condition = GetParam2(data)
				for (var key in data) {
					tableName.push(key)
				}
				tableName = tableName.join(',') + ' '
			}
		} else {
			console.log(data, '对象深度应为3')
		}
		sql = 'select * from ' + tableName + condition
		// console.log(sql)
		return this.Select(sql)
	},

	//通过对象获取
	JsUpdate(dbTable, data) {
		// console.log(data) 

		try {
			var sql = ''
			var condition = []
			Object.entries(data).forEach(item => {
				if (item[1] != undefined && item[0] != 'id') {
					if (typeof(item[1] == 'string')) {
						condition.push(` ${item[0]} = '${item[1]}' `)
					} else {
						condition.push(` ${item[0]} = ${item[1]} `)
					}
				}

			})
			condition = condition.join(',')
			sql = `UPDATE ${dbTable} SET ${condition} where id = ${data.id}`
			return this.SqlExecute(sql)
		} catch (e) {
			console.log(e)
			//TODO handle the exception
		}

	},
	JsDelete(dbTable, data) {
		var sql = ''
		// debugger
		var condition = []
		try {
			if (data.id != undefined || data.id != null) {
				sql = `DELETE FROM ${dbTable} where id = ${data.id}`
			} else if (data.constructor == Number) {
				sql = `DELETE FROM ${dbTable} where id = ${data}`
			} else {
				Object.entries(data).forEach(item => {
					if (item[1] != undefined && item[0] != 'id') {
						if (typeof(item[1] == 'string')) {
							condition.push(` ${item[0]} = '${item[1]}' `)
						} else {
							condition.push(` ${item[0]} = ${item[1]} `)
						}
					}

				})
				condition = condition.join('AND')
				sql = `Delete FROM ${dbTable} WHERE ${condition}`
			}
			return this.SqlExecute(sql)
		} catch (e) {
			console.log(e)
		}

	},
	GetParam(data) {
		// console.log(data)
		var res = ''
		var deep = GetDeep(data)
		// console.log('deep',deep)
		try {
			if (GetDeep(data) == 2) {
				res = GetParam(data)
			} else if (GetDeep(data) == 3) {
				console.log('deep', 2)
				// res = GetParam2(data)
			}
		} catch (e) {
			//TODO handle the exception
			// console.log(e)
		}
		// console.log(res)
		return res
	},
	/**
	 * 测试字段是否存在
	 * @param {数据库名称} dbTable
	 * @param {测试列} colName
	 */
	TestCol(dbTable, colName) {
		var res = true

		return new Promise((success, fail) => {
			this.Select(`Select ${colName} from ${dbTable} limit 1`).then(res => {
				success(true)
			}).catch(err => {
				console.log(`${dbTable} 不存在 ${colName}`)
				success(false)
				// res = false
			})
		})

	},
	/**
	 * 添加列
	 * @param {Object} dbTable
	 * @param {Object} colName
	 * @param {Object} data
	 */
	AddCol(dbTable, colName, data) {
		var colType = this.GetColType(data)
		return this.SqlExecute(`alter table ${dbTable} add column ${colName} ${colType}`)
	},
	/**
	 * 删除列
	 * @param {Object} dbTable
	 * @param {Object} colName
	 */
	DeleteCol(dbTable, colName) {
		return this.SqlExecute(`alter table ${dbTable} drop column ${colName}`)
	},
	/**
	 * 获取数据类型
	 * @param {Object} data
	 */
	GetColType(data) {
		var res = 'TEXT'
		switch (data.constructor) {
			case Number:
				if (Math.floor(data) == data) {
					res = 'INTEGER'
				} else {
					res = 'REAL'
				}
				break
			case String:
				res = 'TEXT'
				break
			case Boolean:
				res = 'BOOLEAN'
				break
			case Date:
				res = 'TEXT'
				break
		}
		return res
	},

}

数据库自动完整性维护

因为我们每个程序的sqlite数据库都需要强制同步更新,比如新增表,表新增列。

const $SqlHelper = require('@/utils/SqlHelper.js')




var DB_list = [{
	DB_name: 'DeviceTree',
	data: {
		PC_Id: 1, //服务器id
		type: '是本地的还是网络的',
		isUpload: 0,
		path: '', //路径
		count: 0, //几个数据没上传
		name: '名称',
		parentId: '父节点id',
		isClick: false
	}
}, {
	DB_name: 'BluetoothData',
	data: {
		DeviceId: 1,
		RDataId:1,
		state: '0007',
		value1: 0.0019,
		value2: -0.1658,
		value3: -0.3417,
		value4: -0.0953,
		electric: 0.9903,
		voltage: 0.3512,
		isFinish: 0,
		step: 0
	}
}, {
	DB_name: 'RData',
	data: {
		DeviceId: 1,
		Ra: 0.4,
		Rb: -0.2,
		Rc: 0,
		Rab: 0.2,
		Rac: 0.4,
		Rbc: -0.2,
		Rabc: 0.2,
		La: 0.3,
		Lb: 0,
		Lc: 0.6,
		Lab: 0.4,
		Lac: 1,
		Lbc: 0.7,
		Labc: 1,
		RA_status: '正常',
		RA_description: '数据正常,在正常范围内',
		RB_status: '正常',
		RB_description: '数据正常,在正常范围内',
		RC_status: '正常',
		RC_description: '数据正常,在正常范围内',
		tester: '测试人员',
		testDevice: '测试设备',
		isUpload: 0
	}
}, {
	DB_name: 'test',
	data: {
		name: '小刘',
		age: 15,
		sex: '男',
		col1:1
	}
},{
	DB_name:'DeviceMsg',
	data:{
		DeviceId:1,
		RDataId:1,
		Msg:'测试消息',
		StartTime:'2023-12-21 13:55:26'
	}
},{
	//交叉互联过程数据
	DB_name:'DeviceCrossTemp',
	data:{
		VA:0,
		VB:0,
		VC:0,
		RAB:0,
		RAC:0,
		RBC:0,
		LAB:0,
		LAC:0,
		LBC:0,
		PAB_A:0,
		PAC_C:0,
		PBC_C:0,
		PCB_A:0,
		DeviceId:0,
		MsgId:0
	}
}]


module.exports = {
	Init() {
		if (!$SqlHelper.isOpen()) {
			$SqlHelper.openSqlite()
		}
		DB_list.forEach(item => {
			$SqlHelper.JsCreateTableType(item.DB_name, item.data)
		})
		async function action(name, data) {
			var addList = []
			Object.entries(data).forEach(async item => {
				var isExist = await $SqlHelper.TestCol(name, item[0])
				if (!isExist) {
					await $SqlHelper.AddCol(name, item[0], item[1])
					addList.push(item[0])
				}
			})
			console.log(` 数据库${name} 添加了:${addList.join(',')}`)

		}
		DB_list.forEach(item => {
			action(item.DB_name, item.data)
		})
	},
	ReInit(dbName) {
		console.log('重置数据库', dbName)
		$SqlHelper.dropTable(dbName)
		setTimeout(() => {
			DB_list.forEach(item => {
				$SqlHelper.JsCreateTableType(item.DB_name, item.data)
			})
		}, 3000)
	},
	ReInitAll() {
		var that = this
		DB_list.forEach(item => {
			that.ReInit(item.DB_name)
		})
	}
}

总结:多次封装的优点

  • 简化sql操作
  • 使用js封装,减少sql拼写错误
  • 一次导入,即可操作所有业务操作。不用导入多个文件。
  • 导入业务只需设计数据类型,自动转化成sqlite对应的数据格式
  • 不用写复杂的sql语句,将中心放在业务的逻辑代码上面
;