clientdb.md 6.4 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 19 20 21 22 23
## 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)

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

**注意**

- `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 63
- 在HBuilderX 3.0以前的版本,使用该组件需要在插件市场单独引用`<uni-clientDB>插件`,另见:[https://ext.dcloud.net.cn/plugin?id=3256](https://ext.dcloud.net.cn/plugin?id=3256)

雪洛's avatar
雪洛 已提交
64
以下文章重点介绍`clientDB`的js API。至于组件的用法,另见[文档](uniCloud/unicloud-db.md)
Q
qiang 已提交
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 91

## 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
雪洛 已提交
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
**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 已提交
109 110 111 112 113 114 115
**使用说明**

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

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


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

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