uniapp 使用sqlite存储聊天记录篇
最近使用sqlite进行了聊天记录存取,故来写一篇记录一下·及相关坑的避免!!!
挺早了解过sqlite 这个东西,这从尝试算是真正接触了。
故事开头是这么回事,项目需求是使用腾讯IM做一个咨询服务,就涉及到了消息的一个持久化处理,腾讯那边值存储7天,然后提供接口让我们的后台可以去拉去消息记录,但是拉取回来的消息记录字段差距太大了,压根没办法直接使用,后来做了一个和后端联动,利用后台拉去的记录进行历史记录拉取,后来效果任然是差强人意。于是决定使用这个东西来存一下聊天记录。
由于暂时需求上只是利用她来存储聊记录,所以并未对相关api做过多的封装,如果后期需求上去了再去对他进行封装吧。
废话不多说进入主题:
第一步:在App模块配置中勾选sqlite,然后制作自定义基座
第二步(非必要):考虑到项目的整体整洁对相关基础接口进行Promise封装,主要是为了方便后期的一个链式调用回调的逻辑处理
我这边是再utils目录下建立一个sqlite的全局mixin js文件,到时候混入到全局,方便使用,省去import的麻烦。
下面是伪代码:(我这边存在不同用户使用同一手机登陆的情况,所以动态匹配了数据库存储路径,达到账号切换信息不丢失,当然有更好的解决方案我暂时还没想好,之前页考虑过使用sql给每个字段添加用户ID进行区分,但是这个腾讯那边的字段和关键之似乎是不支持这么干的所以最终觉得,以多库存储的形式来解决。)
export default {data(){return {options:{name:'Appname',path:`_doc/appNAme${uni.getStorageSync('userInfo').phoneNumber}.db`,success:(e)=>{this.openDataBaseSuccess(e)},fail:(e)=>{this.openDataBaseFail(e)}},shutDataBase:{name:'tcwangApp',success:(e)=>{this.closeDataBaseSuccess(e)},fail:(e)=>{this.closeDataBaseFail(e)}}}},methods:{//打开数据库,不存在则直接创建数据库不建议传参,定义参数 以满足//若需要暗data里的例子传参即可openDataBase(options = this.options){return new Promise ((res,rej)=>{void plus.sqlite.openDatabase({name:'tcwangApp',path:`_doc/tcwangApp${uni.getStorageSync('userInfo').phoneNumber}.db`,success:(e)=>{this.openDataBaseSuccess(e)res(e)},fail:(e)=>{this.openDataBaseFail(e)rej(e)}});})},openDataBaseSuccess(e){console.log('If you see me,dataBase open success',e);},openDataBaseFail(e){console.error('If you see me,dataBase open fail',e);},//检查sqlite打开情况checkDataBase(option){let options = {}if(option){options = option}else{options = {name:'tcwangApp',path:'_doc/tcwangApp.db',}}console.log(plus.sqlite.isOpenDatabase(option));},closeDatabase(options = this.shutDataBase){void plus.sqlite.closeDatabase(options);},//关闭databasecloseDataBaseSuccess(e){console.log('If you see me,dataBase close success',e);},closeDataBaseFail(e){console.error('If you see me,dataBase close fail',e);},//sqlite事务执行transaction(options='begin'){return new Promise((res,rej)=>{void plus.sqlite.transaction({name: 'tcwangApp',operation:options ,success: function(e){res(e)},fail: function(e){rej(e)console.error('transaction failed: '+JSON.stringify(e));}});})},//增删改数据changeData(sql){return new Promise((res,rej)=>{void plus.sqlite.executeSql({name: 'tcwangApp',sql: sql,success: function(e){res(e)},fail: function(e){rej(e)console.error('executeSql failed: '+JSON.stringify(e));}});})},//查询selectDataBase(sql){return new Promise((res,rej)=>{void plus.sqlite.selectSql({name: 'tcwangApp',sql: sql,success: (e) => {res(e)console.log('select dataBase success');},fail: (e) => {rej(e)console.error('select fail,balabala');}});})},onFail(error){console.error('hasErr',error);}}
}
接下来就是数据库的链接和表的建立和增删查改了,我这边暂时用不上复杂的事务啊怎么样,所以各位看官老爷届时自行更改,我这边提供一个思路。
changedatabase(){this.openDataBase()let sql = 'create table if not exists im_record (id INTEGER PRIMARY KEY AUTOINCREMENT,conversationID varchar(50) UNIQUE,time DATETIME,im_detail TEXT)'this.changeData(sql).then(res=>{})let _this = thisconsole.log(this.conversations,'this.conversations');this.conversations.forEach(item=>{test()async function test(){try{let insertData = `insert into im_record (conversationID,time,im_detail) values ("${item.conversationID}", "${item.lastMessage.lastTime}","${AESUtil.encrypt(JSON.stringify(item)).replaceAll('/','-')}")`await _this.changeData(insertData).then(res=>{console.log('action success!');_this.saveDetailMsg(item.conversationID,item.unreadCount)}).catch(()=>{var a =nullreturn a.length})}catch (err){let insertData =`UPDATE im_record SET time="${item.lastMessage.lastTime}", im_detail="${AESUtil.encrypt(JSON.stringify(item)).replaceAll('/','-')}" WHERE conversationID="${item.conversationID}"`_this.changeData(insertData).then(res=>{console.log('更新数据成功action success!');_this.saveDetailMsg(item.conversationID,item.unreadCount)})console.log(1234)}}}) let selectData = `select * from im_record order by time DESC`this.selectDataBase(selectData).then(res=>{let arr = []res.forEach(item=>{arr.push(JSON.parse(AESUtil.decrypt(item.im_detail.replaceAll('-','/'))) )})this.conversations1 = arrif(arr.length <1){adminSendMsg().then(res => {this.$store.dispatch('getConversation');});}console.log(res,'查询成功');})},
注意之所以使用async 、awite主要是因为try catch只能捕获同步代码中的错误,这样就使得promise异步抛出的错误无法捕捉影响代码实现逻辑。我这边是先打开数据库,如果已经打开了抛出错误,直接建表
let sql = 'create table if not exists im_record (id INTEGER PRIMARY KEY AUTOINCREMENT,conversationID varchar(50) UNIQUE,time DATETIME,im_detail TEXT)'
由于sqlite在uniapp中没有办法使用可视化工具,所以就比较考验sql功底了,可以赵后端小伙伴帮忙。
然后开始插入数据,为了保证数据的唯一性,为每一条记录添加UNIQUE防止重复插入,如果已经存在则通过try catch 执行数据更新,让数据保持最新状态
let insertData =`UPDATE im_record SET time="${item.lastMessage.lastTime}", im_detail="${AESUtil.encrypt(JSON.stringify(item)).replaceAll('/','-')}" WHERE conversationID="${item.conversationID}"`
最后进行排序查询的结果就可以直接使用了,
接下来就是每一条消息的存储了,方法是一样的
建表
let sql = 'create table if not exists msg_dtail1 (id INTEGER PRIMARY KEY AUTOINCREMENT,conversationID TEXT,time DATETIME,msg_dtail TEXT)'
存储
let sql = `insert into msg_dtail1 (time,msg_dtail,conversationID) values ("${item.time}","${AESUtil.encrypt(JSON.stringify(item)).replaceAll('/','-')}","${item.conversationID}")`
我这边是根据未读消息进行存储的,所以不存在重复,所以不需要更新,删除时消息列和聊天记录一并删除即可
let sql = `DELETE FROM im_record2 WHERE conversationID="${e.conversationID}"`;
具体逻辑是一致的
在sql语句编写是要注意:笔者差点被坑疯掉,也是没认真看官方的文档的后果吧,(主要他说这玩意和mysql语句大体保持一致,小声比比)
就是写语句是插入和更新数据要用双引号抱起来,单引号是不行的,否则他就报错给你看说什么token:\\\\
笔者这边对数据的操作方法进行了封装,可见上方的sqlite.js文件中,写的比较乱,需要有一定基础查看,提供一种解决思路吧。
欢迎指正、留言
uniapp 使用sqlite存储聊天记录篇相关推荐
- php sqlite存入文件夹,PHP_小文件php+SQLite存储方案,我们草根站长购买的虚拟主机 - phpStudy...
小文件php+SQLite存储方案 我们草根站长购买的虚拟主机往往都有文件数量限制,大量小文件占用大量资源,落伍精华区也有兄弟推荐豆瓣的解决方法,但是要有主机权限.只能另装思路,采用php+SQLit ...
- cocos2d-x中使用可加密Sqlite存储玩家数据
手机游戏当中的数据存储是一个重要的课题.cocos2d-x发展到现在的版本2.1.4,已经直接实现了对sqlite的支持(extensions/LocalStorage),这对我们一般的数据存储已经够 ...
- EChat(简易聊天项目)五、存储聊天记录中的图片
利用文件存储实现存储聊天记录中的图片 首先先需要使聊天界面可以发送图片,然后再对其进行存储操作 ①修改Msg类,增加了imgpath,即图片路径 public class Msg {public st ...
- android sqlite存对象,【Android基础】Android SQLite存储自定义对象
Android SQLite存储自定义对象 在SQLite数据库中可存储的数据类型有NULL.INTEGER.REAL(浮点型).TEXT.BOOL,一共是五种数据类型.在Android开发中,我们存 ...
- android sqlite 存储对象,SQLite存储对象
前言 sqliteDataBase能存储的数据类型有: 1.NULL:空值. 2.INTEGER:带符号的整型,具体取决有存入数字的范围大小. 3.REAL:浮点数字,存储为8-byte IEEE浮点 ...
- android聊天,存储聊天记录sqlite
项目中有聊天模块,需要用到打开activity的时候初始化聊天记录的情况.大致情况如下: 辅助类:ChatSQLiteHelper 在第一次时会调用oncreate方法(判断的标准是schedul ...
- 高性能Sqlite存储模型对象解密
前言 首先写这篇文章之前祝大家元旦快乐,然后自我介绍一下,我叫吴海超(WHC)在iOS领域有丰富的开发架构经验Github以后我也会以文章的形式分享具有实战意义的文章给大家,希望能够给大家有所帮助. ...
- 【Android游戏开发十三】(保存游戏数据 [下文])详解SQLite存储方式
上一篇跟各位童鞋介绍了SharedPreference 和 File流如何存储数据,并且推荐使用FileOutputStream/FileInputStream来存储咱们游戏数据,那么这一篇则是像大家 ...
- C/C++ SQLite 之基础篇
文章目录: 1. 下载 SQLite3 源码: 2. 下载 SQLite3.dll 文件: 3. 生成 SQLite3.lib 文件 : 4. 生成或者下载 SQL ...
最新文章
- 服务器根目录文件配置文件,在文档根目录中存储安装和配置文件
- oracle: to_char,to_date
- U盘容量减少的解决办法
- 在哪里查看计算机配置的网络协议簇,tcp/ip协议簇
- 良性计算机病毒对计算有没有危害机系统,154、计算机病毒有良性和恶性之分,其中, – 手机爱问...
- 天大校花,博士发Nature,30岁不到当耶鲁教授!
- 用JS实现移动的窗口
- hive拉链表实现方案一
- mysql引擎互转问题
- MongoDB最简单的入门教程之二 使用nodejs访问MongoDB 1
- Map转成JSON对象
- java for循环内执行多线程
- Ubuntu18.04 一条命令安装VLC视频播放器 可倍速播放
- 通用API接口签名算法(参考淘宝)
- Unity中下载图片、音频和视频
- linux环境下java输出乱码,linux java 输出乱码问题
- 在校园网中进行无线路由器设置
- 疯狂的架构——著名科技公司组织结构图一览
- 用vue写轮子的一些心得(五)——Slides轮播组件
- 谷歌的无痕模式有什么好处_为什么Google的新搜索结果设计是黑暗的模式