clientdb.md 7.1 KB
Newer Older
雪洛's avatar
雪洛 已提交
1 2
JQL语法相关文档已移至:[JQL语法](uniCloud/jql.md)

Q
qiang 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
## clientDB简介

> 自`HBuilderX 2.9.5`起支持在客户端直接使用`uniCloud.database()`方式获取数据库引用,即在前端直接操作数据库,这个功能被称为`clientDB`

> `HBuilderX 2.9.5`以前的用户如使用过`clientDB`,在升级后请将`clientDB`的前端库和云函数删除,新版已经在前端和云端内置了`clientDB`

大白话:传统的数据库操作只能在服务端实现,因为他在前端使用有安全问题。而uniCloud的云数据库有表结构(DB Schema)他通过简单的js表达式,配置了:各种角色权限的账号是否可以读取和写入某种规范的数据等,解决了在前端操作的安全问题;因此uniCloud的云数据库可以直接在前端调用。

使用`clientDB`的好处:**不用写服务器代码了!**

1个应用开发的一半的工作量,就此直接省去。

当然使用`clientDB`需要扭转传统后台开发观念,不再编写服务端代码,直接在前端操作数据库。但是为了数据安全,需要在数据库上配置`DB Schema`

`DB Schema`中,配置数据操作的权限和字段值域校验规则,阻止前端不恰当的数据读写。详见:[DB Schema](https://uniapp.dcloud.net.cn/uniCloud/schema)

雪洛's avatar
雪洛 已提交
19
如果想在数据库操作之前或之后需要在云端执行额外的动作(比如获取文章详情之后阅读量+1),`clientDB`提供了action云函数机制。在HBuilderX项目的`cloudfunctions/uni-clientDB-actions`目录编写上传js,参考:[action](uniCloud/jql?id=action)
Q
qiang 已提交
20 21 22 23

**注意**

- `clientDB`依赖uni-id(`1.1.10+版本`)提供用户身份和权限校验,如果你不了解uni-id,请参考[uni-id文档](https://uniapp.dcloud.net.cn/uniCloud/uni-id)
雪洛's avatar
雪洛 已提交
24
- `clientDB`依赖的uni-id需要在uni-id的config.json内添加uni-id相关配置,通过uni-id的init方法传递的参数不会对clientDB生效,参考:[uni-id 配置](uniCloud/uni-id.md?id=config)
Q
qiang 已提交
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
- 通常在管理控制台使用`clientDB`,需要获取不同角色用户拥有的权限(在权限规则内使用auth.permission),请先查阅[uni-id 角色权限](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=rbac)

## 对比:传统与clientDB云端协同的开发效率
> 演示:在线通讯录项目,渲染云端数据到视图

### 传统开发方式:
1. 传统开发你需要先写服务端代码(这里用php+mysql作为演示)用sql语法查询数据库中的数据并输出,然后再开放API。

需写27行代码,如图:
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/f0798882-cbcc-4b41-affc-7bce5ebaeb0e.png)

2. 前端用ajax携带必要参数请求API,然后将请求结果赋值给data中的变量。最终把变量在视图中渲染出来。

需写37行代码,如图:
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/d2194fea-c90e-4f02-b241-d27167ccb015.png)

> 传统云端分离的开发方式,共计:64行代码。


### clientDB的开发方式:
- 云端协同的开发方式,unicloud-db组件渲染列表。

仅:5行代码如图:
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/6d7fe2a6-1115-4535-8f3f-cdbb7c90e0ef.jpg)


雪洛's avatar
雪洛 已提交
51
**总结:基于uniCloud云端协同的开发方式,不需要写js代码,不需要写服务端的代码。直接在视图模板中写6行代码,即可完成传统开发方式需要64行代码才能完成的效果。且不仅仅是代码量的问题。整个开发过程的体验,提高了完全不止10倍的开发效率。**
Q
qiang 已提交
52 53 54 55 56 57 58 59 60


## clientDB图解
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/b673c28f-c41b-406d-8b7a-c3f4bfbf4b31.jpg)

`clientDB`的前端,有两种用法,可以用js API操作云数据库,也可以使用`<unicloud-db>`组件。

js API可以执行所有数据库操作。`<unicloud-db>`组件是js API的再封装,进一步简化查询等常用数据库操作的代码量。

Q
qiang 已提交
61
- 在HBuilderX 3.0+,`<unicloud-db>`组件已经内置,可以直接使用。文档另见:[`<unicloud-db>`组件](/uniCloud/unicloud-db)
Q
qiang 已提交
62

雪洛's avatar
雪洛 已提交
63
以下文章重点介绍`clientDB`的js API。至于组件的用法,另见[文档](uniCloud/unicloud-db.md)
Q
qiang 已提交
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90

## clientDB前端API@jssdk

`clientDB`的客户端部分主要负责提供API,允许前端编写数据库操作指令,以及处理一些客户端不太方便表示的字段,比如用户ID(详情看下面语法扩展部分)

`clientDB`支持传统的nosql查询语法,并新增了`jql`查询语法。`jql`是一种更易用的查询语法。

**传统nosql查询语法示例**

这段示例代码,在一个前端页面,直接查询了云数据库的`list`表,并且指定了`name`字段值为`hello-uni-app`的查询条件,then里的res即为返回的查询结果。

```js
// 获取db引用
const db = uniCloud.database() //代码块为cdb
// 使用uni-clientDB
db.collection('list')
  .where({
    name: "hello-uni-app" //传统MongoDB写法,不是jql写法。实际开发中推荐使用jql写法
  }).get()
  .then((res)=>{
    // res 为数据库查询结果
  }).catch((err)=>{
    console.log(err.code); // 打印错误码
		console.log(err.message); // 打印错误内容
  })
```

雪洛's avatar
雪洛 已提交
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
**jql查询语法示例**

```js
// 获取db引用
const db = uniCloud.database() //代码块为cdb
// 使用uni-clientDB
db.collection('list')
  .where('name=="hello-uni-app"')
	.get()
  .then((res)=>{
    // res 为数据库查询结果
  }).catch((err)=>{
    console.log(err.code); // 打印错误码
		console.log(err.message); // 打印错误内容
  })
```

Q
qiang 已提交
108 109 110 111 112 113 114
**使用说明**

前端操作数据库的语法与云函数一致,但有以下限制(使用jql语法时也一样):

- 上传时会对query进行序列化,除Date类型、RegExp之外的所有不可序列化的参数类型均不支持(例如:undefined)
- 为方便控制权限,禁止前端使用set方法,一般情况下也不需要前端使用set
- 更新数据库时不可使用更新操作符`db.command.inc`
雪洛's avatar
雪洛 已提交
115
- 更新数据时键值不可使用`{'a.b.c': 1}`的形式,需要写成`{a:{b:{c:1}}}`形式
Q
qiang 已提交
116 117


雪洛's avatar
雪洛 已提交
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
## 客户端事件@event

### 刷新token@refreshtoken

透传uni-id自动刷新的token给客户端

> HBuilderX 3.2.11及以上版本,clientDB会自动将刷新的token及过期时间保存在storage内。

**用法**

```js
const db = uniCloud.database()

function refreshToken({
  token,
  tokenExpired
}) {
  uni.setStorageSync('uni_id_token', token)
  uni.setStorageSync('uni_id_token_expired', tokenExpired)
}
// 绑定刷新token事件
db.on('refreshToken', refreshToken)
// 解绑刷新token事件
db.off('refreshToken', refreshToken)
```

### 错误处理@error

全局clientDB错误事件,HBuilderX 3.0.0起支持。

**用法**

```js
const db = uniCloud.database()

function onDBError({
  code, // 错误码详见https://uniapp.dcloud.net.cn/uniCloud/clientdb?id=returnvalue
  message
}) {
  // 处理错误
}
// 绑定clientDB错误事件
db.on('error', onDBError)
// 解绑clientDB错误事件
db.off('error', onDBError)
```

雪洛's avatar
雪洛 已提交
165
## JQL语法@jql
Q
qiang 已提交
166

雪洛's avatar
雪洛 已提交
167
clientDB使用JQL在客户端编写查询语句,关于JQL语法请参考:[JQL语法](uniCloud/jql.md)