js数据库操作(js连接数据库代码)

最近做功能需要浏览器自己备份一份数据,但是本地数据还需要支持条件查询。

于是,查找了一下是否有浏览器数据库这种东西。发现了Web SQL和IndexedDB这两个东西,前者是关系型数据库,后者是NoSQL类型的。因为功能需要关系型查询,所以准备选用前者,但是前者兼容性有问题,而且不是标准的规范,而且停止了更新。
js数据库操作(js连接数据库代码)

实践了一下发现Web SQL在火狐等浏览器上确实是不支持的,但是Chrome、Safari是支持的。本来想对于支持的使用Web SQL去做,不支持的使用IndexedDB采用另一台存储方案。不过在无意中发现了persistencejs。

persistencejs有好多套SQL的方案。对于浏览器提供了Web SQL存储和内存存储(支持导入到LocalStorage)两种方案。

所以对于支持Web SQL的,采用persistencejs的WebSQL方案。

对于不支持Web SQL的,采用内存方案,并将数据持久化到LocalStorage。

但是因为内存方案会比WebSQL方案多一个从LocalStorage读取数据和把输入存入LocalStorage两个步骤。

所以为了统一接口,我添加了dataInit和save接口。

dataInit对于WebSQL方案不会做任何事情,但是对于内存方案会执行loadFromLocalStorage读取数据。

save接口将替代flush接口,但是唯一不同的是内存方案会再执行完flush以后,执行saveToLocalStorage。

但是考虑到频繁saveToLocalStorage会影响性能,此处采用了我上一篇写的‘JS中实现函数在指定时间内单次执行’,实现在2秒内只会持久化一次。

基本上实现后封装成PersistenceSQL如下:(项目采用ReactJS编写)

import WebSQL from ‘./WebSQL’;import Tools from ‘../Tools’;import persistence_meta from ‘./persistencejs/persistence’import {defaultTypeMapper, config} from ‘./persistencejs/persistence.store.sql’import websql_meta from ‘./persistencejs/persistence.store.websql’import memorysql_meta from ‘./persistencejs/persistence.store.memory’class PersistenceSQL { constructor() { this._sql_arg = { name: ‘persistencedb’, description: ‘the persistence database’, maxSize: 5*1024*1024, // 字节 } this.sql_init = false this.persistence = persistence_meta.createPersistence() this.persistence.store = this.persistence.store || {}; this.persistence.store.sql = { defaultTypeMapper: defaultTypeMapper, config: config }; this.init() } static instance() { if (Tools.isNone(PersistenceSQL.persistenceSQL)) { PersistenceSQL.persistenceSQL = new PersistenceSQL() } return PersistenceSQL.persistenceSQL.persistence } initWebSQL() { this.persistence.store.websql = {}; this.persistence.store.websql.config = websql_meta.persistence.store.websql.config let arg = this._sql_arg this.persistence.store.websql.config(this.persistence, arg.name, arg.description, arg.maxSize); this.persistence.dataInit = (call_back)=>{ if (!Tools.isNone(call_back)) { call_back() } } this.persistence.save = this.persistence.flush } initMemorySQL() { this.persistence.store.memory = {} this.persistence.store.memory.config = memorysql_meta.config let arg = this._sql_arg this.persistence.store.memory.config(this.persistence, arg.name); this.persistence.dataInit = this.persistence.loadFromLocalStorage let saveToLocalStorage = Tools.exeOnceAtTime(()=>{ this.persistence.saveToLocalStorage() }, 2000) this.persistence.save = ()=>{ this.persistence.flush() saveToLocalStorage() } } init() { if (WebSQL.judgeSupport()) { try { this.initWebSQL() } catch (e) { this.initMemorySQL() } } else { this.initMemorySQL() } }}export default PersistenceSQL

对于’./persistencejs/persistence’、’./persistencejs/persistence.store.sql’、’./persistencejs/persistence.store.websql’、’./persistencejs/persistence.store.memory’这四个文件,大部分网上的代码都是通过在html中标签引入的。此处采用CommonJS的方式进行了使用。

然后对数据库进行使用:

表结构定义:(第一次定义完以后,第二次执行这段代码将使用原先创建的表,不会再次执行创建表)

let persistence = PersistenceSQL.instance()this.test_table = persistence.define(‘test’, { test_id: ‘INT’, xxxx_id: ‘INT’, day_time_stamp: ‘INT’, type: ‘INT’, user_name: ‘TEXT’, content: ‘JSON’,});this.test_table.index([‘test_id’, ‘day_time_stamp’, ‘xxxx_id’], {unique: true})persistence.schemaSync()persistence.dataInit()

数据的存入:

let persistence = PersistenceSQL.instance()let TestTable = this.test_tablefor (let i = 0; i < args.length; i ) { let arg = args[i] let record = new TestTable({ test_id: arg.test_id, xxxx_id: xxxx_id, day_time_stamp: Tools.getNowDayTimeStamp(arg.time_stamp), type: arg.type, user_name: arg.user_name, content: arg.content, }) persistence.add(record)}persistence.save()

数据查询:

let persistence = PersistenceSQL.instance()let TestTable = this.test_tablelet query1 = new persistence.AndFilter( new persistence.PropertyFilter(‘test_id’, ‘=’, test_id), new persistence.PropertyFilter(‘day_time_stamp’, ‘=’, time_stamp))if (id_from > 0) { query1 = new persistence.AndFilter( query1, new persistence.PropertyFilter(‘test_id’, ‘<‘, id_from) )}let query2 = new persistence.AndFilter( new persistence.PropertyFilter(‘test_id’, ‘=’, test_id), new persistence.PropertyFilter(‘day_time_stamp’, ‘<‘, time_stamp))let query = TestTable.all().and(query1).or(query2).order(“day_time_stamp”, false).order(‘test_id’, false).limit(message_count);query.list(null, (data)=>{ let ans = [] if (data.length == 0) { call_back(ans) return } data.forEach((item)=>{ print(item.content) ans.push(item) }) call_back(ans)})

对于查询persistencejs中封装了许多查询接口,可以在官方的介绍中看到:

https://github.com/coresmart/persistencejs

发表评论

登录后才能评论