前言
微信小程序直接调用云数据库(云开发模式)是微信提供的一种Serverless架构方案,它允许前端(小程序端)在没有传统后端服务器的情况下直接操作数据库。 以下是关于该机制的原理架构图 、流程图 及使用详解。
一、 原理架构图
微信小程序云开发采用了 Serverless 架构。传统的开发模式需要"小程序前端 -> 后端服务器(API) -> 数据库",而云开发模式则是"小程序前端 -> 云数据库(通过微信私有协议)"。
1. 架构示意
graph TD
subgraph "客户端"
A[小程序前端代码]
end
subgraph "微信基础设施"
B[微信 APP 宿主环境]
C[云开发控制台/基础设施]
end
subgraph "云开发资源"
D[(云数据库 - JSON)]
E[云函数]
F[云存储]
end
A -- 1. 调用 wx.cloud/init --> B
A -- 2. 调用 db.collection --> B
B -- 3. 微信私有协议/鉴权 --> C
C -- 4. 安全规则校验 --> D
D -- 5. 返回JSON数据 --> C
C -- 6. 返回结果 --> A
style A fill:#e1f5fe,stroke:#01579b
style D fill:#fff9c4,stroke:#fbc02d
style C fill:#f3e5f5,stroke:#8e24aa
2. 核心组件解析
- 小程序前端: 运行在小程序环境中的代码,通过微信提供的 SDK (
wx.cloud) 发起请求。 - 微信私有协议: 数据传输不经过公网 HTTP,而是通过微信客户端底层通道,速度更快,且自带微信登录态,无需手动管理 Token。
- 安全规则: 这是"直接调用"的安全基石。数据库根据配置的 JSON 规则(如
auth.openid)判断当前用户是否有权读/写数据,替代了传统后端的权限校验逻辑。 - 云数据库: 一个 MongoDB 文档型数据库,数据以 JSON 格式存储。
二、 调用流程图
当小程序端执行一条 db.collection('xxx').get() 时,底层发生了以下流程:
sequenceDiagram
participant User as 用户/小程序前端
participant SDK as 微信客户端 SDK
participant Cloud as 微信云服务网关
participant DB as 云数据库实例
User->>SDK: 1. 调用 API (如 db.collection('user').get())
Note right of User: 传入环境ID (env)
SDK->>SDK: 2. 本地检查云环境初始化状态
SDK->>Cloud: 3. 建立私有连接通道
Note right of SDK: 自动携带 AppID, OpenID, UnionID
Cloud->>Cloud: 4. 身份鉴权 (获取用户身份)
Cloud->>DB: 5. 发送数据库请求指令
Note over DB, Cloud: 6. 执行【安全规则】校验
alt 权限校验失败
DB-->>Cloud: 返回 Permission Denied
Cloud-->>SDK: 返回错误信息
SDK-->>User: Catch Error
else 权限校验通过
DB->>DB: 7. 执行查询/写入操作
DB-->>Cloud: 8. 返回数据结果
Cloud-->>SDK: 9. 封装返回数据
SDK-->>User: 10. Promise Resolve (返回数据)
end
关键点说明:
- 自动鉴权: 最大的特点是 "免登录"。SDK 会自动获取用户的 OpenID 并传给云端,开发者不需要写登录接口。
- 安全规则拦截: 如果在控制台配置了"仅创建者可写",当用户 A 尝试修改用户 B 的数据时,Cloud 层会在第 6 步直接拦截,报错
database permission denied。
三、 使用详解
要实现小程序直接调用云数据库,需遵循以下步骤。
1. 环境初始化
在调用任何云能力之前,必须先初始化。
javascript
// app.js
App({
onLaunch: function () {
if (!wx.cloud) {
console.error('请使用 2.2.3 或以上的基础库以使用云能力');
} else {
wx.cloud.init({
// env 参数说明:
// env: 'your-env-id' // 云开发环境ID,可在云开发控制台获取
traceUser: true, // 自动上报用户信息
});
}
}
});
2. 获取数据库引用
javascript
const db = wx.cloud.database();
// 指定特定环境(如果有多个环境)
// const db = wx.cloud.database({ env: 'your-env-id' });
3. CRUD 操作示例
(1) 增 - Insert
javascript
// 添加数据
db.collection('todos').add({
data: {
description: '学习云开发',
due: new Date('2023-12-31'),
tags: ['cloud', 'database'],
location: new db.Geo.Point(113, 23), // 地理位置
done: false
}
})
.then(res => {
console.log('添加成功,记录ID:', res._id);
})
.catch(err => {
console.error('添加失败', err);
});
(2) 查 - Query
javascript
// 获取数据
db.collection('todos').where({
_openid: 'xxx' // 此处通常不需要手动填,如果开启了安全规则,系统会自动校验
})
.get()
.then(res => {
// res.data 是一个数组
console.log('查询结果:', res.data);
});
// 获取单条记录
db.collection('todos').doc('record-id-here').get()
.then(res => {
console.log(res.data);
});
(3) 改 - Update
注意:update 只能修改符合 where 条件或通过 doc 指定的记录。
javascript
db.collection('todos').doc('record-id-here').update({
data: {
done: true // 将 done 字段改为 true
}
})
.then(res => {
console.log('更新成功,影响行数:', res.stats.updated);
});
(4) 删 - Remove
注意:在小程序端直接调用 remove 删除多条记录通常受限制,建议一次删除一条或使用云函数批量删除。
javascript
db.collection('todos').doc('record-id-here').remove()
.then(res => {
console.log('删除成功');
});
4. 权限管理(安全规则)- 核心中的核心
小程序直接调用数据库之所以安全,是因为数据库安全规则。 在微信开发者工具 -> 云开发控制台 -> 数据库 -> 选择集合 -> 权限设置,有以下常见模式:
- 仅创建者可写,所有人可读:
- 适合:文章、帖子、评论。
- 原理:系统自动检查记录中的
_openid是否与当前用户的_openid一致。
- 仅创建者可读写:
- 适合:个人隐私数据(如购物车、个人设置)。
- 所有人可读,仅创建者可写:
- 适合:字典数据、配置数据。
- 自定义安全规则:
- 使用 JSON 语法定义复杂的逻辑。例如:
"read": true, "write": "auth.openid == doc._openid"。
- 使用 JSON 语法定义复杂的逻辑。例如:
5. 数据类型支持
云数据库支持丰富的数据类型,不同于传统的 MySQL,它直接支持:
- GeoJSON: 地理位置点
db.Geo.Point,支持地理位置查询(如查找附近的人)。 - Date: 时间对象
new Date()。 - Null: 空值。
- 嵌套对象: JSON 对象多层嵌套。
四、 总结
1.微信小程序直接调用云数据库 的核心优势在于:
- 开发效率高: 省去了搭建服务器、编写 API 接口、维护数据库连接池的工作。
- 安全性强: 通过微信底层鉴权和安全规则,实现了前端直接操作数据库且不泄露数据。
- 成本低: 按量付费,对于中小型应用极其友好。
2.适用场景:
- 快速原型开发(MVP)。
- 逻辑相对简单的 CRUD 应用(如备忘录、简单的商城、预约系统)。
- 企业内部员工或者B端项目多为表单提交,列表详情展示类(用户量较小) 不适用场景:
- 复杂的事务处理(如涉及多表关联、复杂的金钱流转逻辑)。
- C端日活高应用,高并发、高吞吐量的写操作(小程序端有连接数和频率限制)。
- 需要高度保密的计算逻辑(逻辑放在前端容易被反编译,此时应使用云函数)。