前言

WCDBWeChatDataBase)是微信官方的移动端数据库组件,致力于供给一个高效、易用、完好的移动端存储计划。原文|地址

它包含三个模块:

  • WCDB-iOS/Mac
  • WCDB-Android
  • 数据库损坏修正东西WCDBRepair

现在正在筹备开源中。

背景

关于iOS开发者来说,数据库的技术选型一直是个令人头痛的问题。

因为Apple供给的CoreData结构差强人意,使得开发者们纷繁将目光投向开源社区,寻找更好的存储计划。

关于微信也是如此。数据库是微信内最根底的组件之一,音讯收发、联系人、朋友圈等等业务都离不开数据库的支撑。为了满意需求,咱们也对现有计划做了比照研究:

现在移动端数据库计划按其完结可分为两类,

  • 关系型数据库,代表有CoreData、FMDB等。
    • CoreData

      它是苹果内建结构,和Xcode深度结合,能够很便利进行ORM;但其上手学习成本较高,不简略掌握。稳定性也堪忧,很简略crash;多线程的支撑也比较鸡肋。

    • FMDB

      它依据SQLite封装,关于有SQLite和ObjC根底的开发者来说,简略易懂,能够直接上手;而缺点也正是在此,FMDB仅仅将SQLite的C接口封装成了ObjC接口,没有做太多其他优化,即所谓的胶水代码(Glue Code)。运用进程需求用许多的代码拼接SQL、组装Object,并不便利。

  • key-value数据库,代表有Realm、LevelDB、RocksDB等。
    • Realm

      因其在各平台封装、优化的优势,比较受移动开发者的欢迎。关于iOS开发者,key-value的完结直接易懂,能够像运用NSDictionary一样运用Realm。并且ORM彻底,省去了组装Object的进程。但其对代码侵入性很强,Realm要求类承继RLMObject的基类。这关于单承继的ObjC,意味着不能再承继其他自界说的子类。一起,key-value数据库对较为杂乱的查询场景也比较无力。

可见,各个计划都有其共同的优势及下风,没有最好的,只要最适合的。

而关于微信来说,咱们所期望的数据库应满意:

  • 高效;增修改查的高效是数据库最根本的要求。除此之外,咱们还期望能够支撑多个线程高并发地操作数据库,以应对微信频繁收发音讯的场景。
  • ;这是微信开源的准则,也是WCDB的准则。SQLite本不是一个易用的组件:为了完结一个查询,往往咱们需求写许多拼接字符串、组装Object的胶水代码。这些代码冗长冗杂,并且简略出错,咱们期望组件能统一完结这些使命。
  • 完好;数据库操作是一个杂乱的场景,咱们期望数据库组件能完好掩盖各种场景。包含数据库损坏、监控计算、杂乱的查询、反注入等。

显然,上述各个计划都不能彻底满意微信的需求。

所以,咱们造了这个“轮子” – WCDB-iOS/Mac

WCDB-iOS/Mac

WCDB-iOS/Mac(以下简称WCDB,均指代WCDB的iOS/Mac版本),是一个依据SQLite封装的Objective-C++数据库组件,供给了如下功用:

  • 快捷的ORM和CRUD接口:经过WCDB,开发者能够快捷地界说数据库表和索引,并且无须写一坨胶水代码组装目标。
  • WINQ(WCDB语言集成查询) :经过WINQ,开发者无须拼接字符串,即可完结SQL的条件、排序、过滤等等句子。
  • 多线程高并发:根本的增删查改等接口都支撑多线程访问,开发者无需操心线程安全问题。
    • 线程间读与读、读与写操作均支撑并发履行。
    • 写与写操作串行履行,并且有依据SQLite源码优化的功用提升。可参阅另一篇文章《微信iOS SQLite源码优化实践》
  • 损坏修正:数据库损坏一直是个难题,WCDB内置了咱们自研的修正东西WCDBRepair。相同可参阅另一篇文章《微信 SQLite 数据库修正实践》
  • 计算分析:WCDB供给接口直接获取SQL的履行耗时,可用于监控功用。
  • 反注入:WCDB结构层防止了SQL注入,以防止恶意信息危害用户数据。

WCDB掩盖了数据库运用的绝大部分场景,且经过微信海量用户的验证,并将继续不断地添加新的能力。

本文是WCDB系列文章的第一篇,首要介绍WCDB-iOS/Mac的根本用法,包含:

  • ORM、CRUD与Transaction
  • WINQ
  • 高档用法

ORM

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

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

这一进程。经过ORM,能够达到直接经过Object进行数据库操作,省去组装进程的目的。

WCDB经过内建的宏完结ORM的功用。如下

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

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

关于一个已有的ObjC类,

  • 引证WCDB结构头文件#import <WCDB/WCDB.h>,并界说类遵从WCTTableCoding协议
  • WCDB_PROPERTY用于在头文件中声明绑定到数据库表的字段。
  • WCDB_IMPLEMENTATION,用于在类文件中界说绑定到数据库表的类。一起,该宏内完结了WCTTableCoding。因而,开发者无须添加更多的代码来完结WCTTableCoding的接口
  • WCDB_SYNTHESIZE,用于在类文件中界说绑定到数据库表的字段。

简略几行代码,就完结了将类和需求的字段绑定到数据库表的进程。这三个宏在称号和运用习惯上,也都和界说一个ObjC类相似,以此便于回忆。

除此之外,WCDB还供给了许多可选的宏,用于界说数据库索引、束缚等,如:

  • WCDB_PRIMARY用于界说主键
  • WCDB_INDEX用于界说索引
  • WCDB_UNIQUE用于界说唯一束缚
  • WCDB_NOT_NULL用于界说非空束缚

界说完结后,只需求调用createTableAndIndexesOfName:withClass:接口,即可创立表和索引。

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

接口会依据ORM的界说,创立对应表和索引。

CRUD

得益于ORM的界说,WCDB能够直接进行经过object进行增修改查(CRUD)操作。

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

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

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

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

Transaction

WCDB内可经过两种方法履行Transaction(事务),一是runTransaction:接口

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

这种方法要求数据库操作在一个BLOCK内完结,简略易用。

另一种方法则是获取WCTTransaction目标

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

WCTTransaction目标能够在类或函数间传递,因而这种方法也更具灵敏性。

WINQ

有心的同学可能会注意到上述比如中的一些特别语法:

  • where: Message.localID>0
  • onProperties: Message.content
  • orderBy :Message.localID.order()

这个就是WINQ。

WINQ(WCDBIntegratedQuery,音’wink’),即WCDB集成查询,是将天然查询的SQL集成到WCDB结构中的技术,依据C++完结

传统的SQL句子,通常是开发者拼接字符串完结。这种方法不只繁琐、易错,并且出错后很难定位到问题所在。一起也简略给SQL注入留下待机而动。

而WINQ将查询语言集成到了C++中,能够经过相似函数调用的方法来写SQL查询。借用IDE的代码提示和编译器的语法查看,达到易用、纠错的作用。

关于一个已绑定ORM的类,能够经过className.propertyName的方法,取得数据库内字段的映射,以此书写SQL的条件、排序、过滤等等一切句子。如下是几个比如:

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

因为WINQ经过接口调用完结SQL查询,因而在书写进程中会有IDE的代码提示和编译器的语法查看,然后提升开发功率,防止写错。

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

WINQ的接口包含但不限于:

  • 一元操作符:+、-、!等
  • 二元操作符:||、&&、+、-、*、/、|、&、<<、>>、<、<=、==、!=、>、>=等
  • 范围比较:IN、BETWEEN等
  • 字符串匹配:LIKE、GLOB、MATCH、REGEXP等
  • 聚合函数:AVG、COUNT、MAX、MIN、SUM等

但凡SQLite支撑的语法规矩,WINQ根本都有其对应的接口。且接口称号与SQLite的语法规矩根本保持一致。关于熟悉SQL的开发者,无须特别学习即可立刻上手运用。

高档用法

as重定向

依据ORM的支撑,咱们能够从数据库直接取出一个Object。但是,有时候需求取出并非是某个字段,而是有一些组合。例如:

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

这段代码从数据库中取出了音讯的最新的修改时刻,并以此将此时刻作为音讯的创立时刻,新建了一个message。这种情况下,就能够运用as重定向。

as重定向,它能够将一个查询成果重定向到某一个字段,如下:

经过as(Message.createTime)的语法,将查询成果重新指向了createTime。因而只需一行代码便可完结本来的使命。

链式调用

链式调用是指目标的接口回来一个目标,然后允许在单个句子中将调用链接在一起,而不需求变量来存储中心成果。

WCDB关于增修改查操作,都供给了对应的类以完结链式调用

  • WCTInsert
  • WCTDelete
  • WCTUpdate
  • WCTSelect
  • WCTRowSelect
  • WCTMultiSelect

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

whereorderBylimit等接口的回来值均为self,因而能够经过链式调用,更天然更灵敏的写出对应的查询。

传统的接口便利快捷,能够直接取得操作成果;链式接口则更具灵敏性,开发者能够获取数据库操作的耗时、错误信息;也能够经过遍历逐一生成object。

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

WCDB内一起支撑这两种接口,优势互补,开发者能够依据需求,挑选运用。

多表查询

SQLite支撑联表查询,在某些特定的场景下,能够起到优化功用、简化表结构的作用。

WCDB相同供给了对应的接口,并在ORM的支撑下,经过WCTMultiSelect的链式接口,能够一起从表中取出多个类的目标。

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

类字段绑定

在ORM中,咱们经过宏,将ObjC类的property绑定为数据库的一个字段。但并非一切property的类型都能绑定到字段。

WCDB内置支撑的类型有:

  • const char*的C字符串类型
  • 包含但不限于intunsignedlongunsigned longlong longunsigned long long等一切依据整型的C根本类型
  • 包含但不限于floatdoublelong double等一切依据浮点型的C根本类型
  • enum及一切依据枚举型的C根本类型
  • NSStringNSMutableString
  • NSDataNSMutableData
  • NSArrayNSMutableArray
  • NSDictionaryNSMutableDictionary
  • NSSetNSMutableSet
  • NSValue
  • NSDate
  • NSNumber
  • NSURL

但是,内置支撑得再多,也不可能彻底掩盖开发者一切的需求。因而WCDB支撑开发者自界说类字段绑定。

类只需完结WCTColumnCoding协议,即可支撑绑定。

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

  • columnTypeForWCDB接口界说类对应数据库中的类型
  • unarchiveWithWCTValue:接口界说从数据库类型反序列化到类的转化方法
  • archivedWCTValue接口界说从类序列化到数据库类型的转化方法

为了简化界说,WCDB供给了文件模版来创立类字段绑定。

  1. 首要需求装置文件模版。该模版的装置脚本集成在WCDB的编译脚本中,只需编译一次WCDB,就会自动装置文件模版。装置完结后重启Xcode,新建文件,即可看到对应的文件模版

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

  1. 挑选WCTColumnCoding

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

    • Class:需求进行字段绑定的类,这儿以NSDate为例
    • Language:WCDB支撑绑定ObjC类和C++类,这儿挑选Objective-C
    • Type In DataBase:类对应数据库中的类型。包含
      • WCTColumnTypeInteger32

      • WCTColumnTypeInteger64

      • WCTColumnTypeDouble

      • WCTColumnTypeString

      • WCTColumnTypeBinary

  1. 咱们知道NSDate是遵从NSCoding协议的,因而这儿挑选了Binary类型。即,将NSDate以二进制数据的形式存到数据库中。完结后会自动创立如下的文件模版:

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

  1. 然后只需将NSDate和NSData互相转化的方法填上去即可。如下:

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

总结

WCDB经过ORM和WINQ,表现了其易用性上的优势,使得数据库操作不再冗杂。一起,经过链式调用,开发者也能够便利地获取数据库操作的耗时等功用信息。而高档用法则扩展了WCDB的功用和用法。

因为篇幅所限,本文只介绍了WCDB最表层的功用。接下来还将共享WCDB-数据库修正三板斧。敬请期待!

引荐:iOS技术资料|地址