首页 > 其他分享 >微信开源组件WCDB漫谈及Demo

微信开源组件WCDB漫谈及Demo

时间:2023-06-01 11:03:44浏览次数:43  
标签:WCDB 微信 数据库 ORM Demo SQL Android


前言

移动端的数据库选型一直是一个难题,直到前段时间看到了WeMobileDev(微信前端团队)放出了第三个开源组件-WCDB

WCDB(WeChat DataBase)是微信官方的移动端数据库组件,致力于提供一个高效、易用、完整的移动端存储方案

项目目录

微信开源组件WCDB漫谈及Demo_Android

微信团队怎么说

  • 基于SQLCipher
  • WCDB-iOS/Mac
  • WCDB-Android
  • 数据库损坏修复工具WDBRepair

背景

WCDB的出现可以说解决了目前移动端数据库的几个难点

  • 首先在选型上,FMDB的SQL拼接、难以防止的SQL注入;CoreData虽然可以方便ORM,但学习成本高,稳定性堪忧,而且多线程鸡肋;另外基于C语言的sqlite我想用的人也应该不多;除了上述关系型数据库之外然后还有一些其他的Key-Value型数据库,如我用过的Realm,对于ObjC开发者来说,上手倒是没什么难度,但缺点显而易见,需要继承,入侵性强,对于单继承的OC来说这并不理想,而且对于集合类型不完全支持,复杂查询也比较无力。
  • 高效
  • 多线程高并发:WCDB支持多线程读与读、读与写并发执行,写与写串行执行。
  • 批量写操作性能测试:

批量写

ops/sec

WCDB

458000

FMDB

161000

  • 易用 WCDB支持一句代码即可将数据取出并组合为object
  • WINQ(WCDB语言集成查询):通过WINQ,开发者无须为了拼接SQL的字符串而写一大坨胶水代码。
  • ORM(Object Relational Mapping):WCDB支持灵活、易用的ORM。开发者可以很便捷地定义表、索引、约束,并进行增删改查操作。
  • 像这样
[database getObjectsOfClass:WCTSampleConvenient.class

        fromTable:tableName 

        where:WCTSampleConvenient.intValue>=10 

        limit:20];
  • 完整
  • 加密:WCDB提供基于SQLCipher的数据库加密。
  • 损坏修复:WCDB内建了Repair Kit用于修复损坏的数据库。
  • WCDB提供接口直接获取SQL的执行耗时,可用于监控性能。
  • 反注入:WCDB内建了对SQL注入的保护

ORM

在WCDB内,ORM(Object Relational Mapping)是指

  • 将一个ObjC的类,映射到数据库的表和索引;
  • 将类的property,映射到数据库表的字段;

这一过程。通过ORM,可以达到直接通过Object进行数据库操作,省去拼装过程的目的。

WCDB通过内建的宏实现ORM的功能。如下

PS:但我不建议这么做,首先要避免在.h文件中引用

CRUD

得益于ORM的定义,WCDB可以直接进行通过object进行增删改查(CRUD)操作。

//插入
Person *man = [[Person alloc] init];
man.isAutoIncrement = YES;
man.name = @"Hello, WCDB!";
man.age = 12;
return  [database insertObject:man into:TABLE_WCDB_NAME];
return [database deleteObjectsFromTable:TABLE_WCDB_NAME where:Person.studentId == studentId];
Person *person = [[Person alloc] init];
person.name = content;
return [database updateRowsInTable:TABLE_WCDB_NAME onProperties:Person.name withObject:person where:Person.studentId == studentId];
NSArray<Person *> * person = [database getObjectsOfClass:Person.class fromTable:TABLE_WCDB_NAME orderBy:Person.localID.order()];

Transaction

WCDB内可通过两种方式执行Transaction(事务),一是runTransaction:接口

这种方式要求数据库操作在一个BLOCK内完成,简单易用。

另一种方式则是获取WCTTransaction对象

WCTTransaction对象可以在类或函数间传递,因此这种方式也更具灵活性。

WINQ

WINQ(WCDB Integrated Query,音’wink’),即WCDB集成查询,是将自然查询的SQL集成到WCDB框架中的技术,基于C++实现。

  • 免去拼接SQL字符串、防注入
  • 借助IDE代码提示和编译器语法检查
  • 对于一个已绑定ORM的类,可以通过className.propertyName的方式,获得数据库内字段的映射
  • WINQ的接口包括但不限于:
  • 一元操作符:+、-、!等
  • 二元操作符:||、&&、+、-、*、/、|、&、<<、>>、<、<=、==、!=、>、>=等
  • 范围比较:IN、BETWEEN等
  • 字符串匹配:LIKE、GLOB、MATCH、REGEXP等
  • 聚合函数:AVG、COUNT、MAX、MIN、SUM等

原理

  • 初衷,适应WCDB+ORM解决SQL字符串的代码冗余和难以被编译器进行语法检查而造成的错误和时间浪费。SQL字符串太容易被注入
  • SQL抽象
  • 封装常用操作,覆盖80%的使用场景
  • 暴露底层接口,适配剩余20%的特殊情况
  • 定义常用操作
  • 特殊场景所暴露的底层接口,应该以什么形式存在?
  • SELECT、DISTINCT、ALL等等大写字母是keyword,属于SQL的保留字。
  • result-column、“table-or-subquery、expr等等小写字母是token。token可以再进一步地展开其构成的语法规则。
  • 将固定的keyword,封装为函数名,作为连接。
  • 将可以展开的token,封装为类,并在类内实现其不同的组合。
  • 在语法规则中,WHERE、LIMIT等都接受expr作为参数。因此,不管SQL多么复杂,StatementSelect也只接受Expr的参数。而其组合的能力,则在Expr类内实现。

数据库修复

  • 官方的Dump恢复方案
  • 遍历sqlite_master表,将未损坏的表和已损坏的前半部分读取出来将dump 出来的SQL语句逐行执行,最终可以得到一个等效的新DB
    功率约为30%。
  • 第一页就损坏后续无法读取
  • 备份恢复方案
  • COPY
  • 在DB完好的时候执行.dump
  • Backup API: SQLite自身提供的一套备份机制,按 Page 为单位复制到新 DB, 支持热备份。
  • 最终选择Dump + 压缩,恢复成功率达到72%
  • 解析B-tree恢复方案(RepairKit)
  • 成功率约为78%
  • 不同方案的组合
  • RepairKit 尝试恢复最新数据
  • 备份恢复 遇到错误填补漏缺
  • Dump 最后的尝试

For Android

  • 基本功能
  • 基于SQLCipher的数据库加密
  • 使用连接池实现并发读写
  • 内建 Repair Kit 可用于修复损坏数据
  • 针对占用空间大小优化的数据库备份/恢复功能
  • 日志输出重定向以及性能跟踪接口
  • 内建用于全文搜索的 mmicu FTS3/4 分词器
  • 接入与迁移
  • WCDB for Android 可通过 Maven 或 AAR 包引用,API 接口与 Android SDK 非常相近, 所以将已有的 App 迁移到 WCDB 是相当容易的。
  • Android 接入与迁移
  • 数据库修复
  • 从源码编译
  • 你可以使用预编译的依赖库(OpenSSL crypto 和 SQLCipher)来编译 WCDB for Android, 使用 Gradle 或 Android Studio 皆可。Android Studio 请导入 android 目录作为 Root Project。
  • 编译 WCDB 需要安装 Android NDK r11c 或以上,并在 android/local.properties 上配置好 SDK 与 NDK 路径。Android Studio 一般会帮你配置好。
  • 如果你需要自己编译 OpenSSL 等依赖项,你需要一个 Bash 环境(Windows 可以安装 Cygwin 或 MSys)、target 为本机的 C 编译器(如 GCC)、Perl 5 以及 Tcl。之后执行下面命令即可编译依赖项。

参考资料

微信移动端数据库组件WCDB系列(一)-iOS基础篇

微信移动端数据库组件WCDB系列(二) — 数据库修复三板斧

微信移动端数据库组件WCDB系列(三) — WINQ原理篇

微信移动数据库组件WCDB(四) — Android 特性篇

微信开源组件WCDB漫谈及Demo

注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权


标签:WCDB,微信,数据库,ORM,Demo,SQL,Android
From: https://blog.51cto.com/u_7583030/6392916

相关文章

  • 微信小程序upload多张图片同时上传
    //上传图片,选择图片chooseImage:function(e){varthat=this;wx.chooseImage({sizeType:['original','compressed'],//可以指定是原图还是压缩图,默认二者都有sourceType:['album','camera'],//可以指定来源是相册还是相机......
  • 最规范的汇编函数传参demo
    assumecs:code;记忆点:1.主函数,子函数都需要自己维护bp和sp(当然不维护也行,但是非常容易出bug,所以还是要强烈按照下面子函数头,子函数尾.主函数头尾这么写,最安全.)2.函数ip都有压栈出站自动维护但是自己要算明白栈的偏移量.codesegmentraddprocpus......
  • activeMQ Jms Demo
    概述ActiveMQ是Apache出品,最流行的,能力强劲的开源消息总线。ActiveMQ是一个完全支持JMS1.1和J2EE1.4规范的JMSProvider实现,尽管JMS规范出台已经是很久的事情了,但是JMS在当今的J2EE应用中间仍然扮演着特殊的地位详细一、什么是ActiveMQ百度解释:ActiveMQ是A......
  • 微信点赞测试点__肖sir__测试点整理
    微信点赞测试点功能:是否可以正常点赞,点赞完成以后是否会提示,多次点赞是否会多次提示性能:点赞完成以后是否快速提示点赞,点赞多了不会卡顿界面:该支付的功能界面是否按照UI原型图进行设计,字体的大小,颜色,布局是否一致,界面是否美观易用:点击点赞可以迅速点赞安全:陌生人是否可以点......
  • “此间有书”微信小程序效果图展示
    由于上传时微信官方那边不给通过,说什么涉及到图书版权信息,明明我这个估计到这一点都没有展示图书内容(哭泣)小程序分为四个模块:广场、书城、发现、我的。广场模块就是每日推荐,有句子、音乐、电影推荐(纯属个人爱好页面)书城模块就是搜索书籍、查看书籍、然后收藏书籍、短评书籍......
  • 微信小程序使用ec-canvas真机上tooltip有阴影
    问题微信小程序项目中,使用了ec-canvas绘制图表,在开发者工具中预览正常,但是在真机上点击图表tooltip会出现一层阴影,如下图所示:修改后解决之后探索到解决方案,代码如下:tooltip:{trigger:'axis',textStyle:{align:'left',textShadowBlur:10,//重点......
  • uniapp onShareAppMessage里面请求后调分享(微信小程序)
    onShareAppMessage(){constpromise=newPromise(resolve=>{request({api:'请求名',method:'POST',data:{"data":{}}}).then(res=>{resolve({......
  • Python 发送微信消息
    Python发送微信消息安装pipinstallitchat1、基本使用#使用微信接口给微信好友发送消息,importitchatnickname="迪丽热巴"send_message="测试消息"try:#1.自动登录方法,hotReload=True可以缓存,不用每次都登录,但是第一次执行时会出现一个二维码,需要......
  • python avro 数据格式使用demo
    {"name":"UEProcedures","type":"record","fields":[{"name":"imsi","type":"string"},{"name":"time_at","type":&quo......
  • java轻型内存队列处理demo
    java轻型内存队列处理demo@ComponentpublicclassConcurrentLinkedQueueUtils{staticAtpLogBizatpLogBiz;staticAuditLogtTmpDataServiceauditLogDataService;staticConcurrentLinkedQueueconList=newConcurrentLinkedQueue();privatestaticvo......