全部內容都是微信小程序文檔裏面的,手動記錄總結只爲留下更深的記憶,有興趣能夠通讀:小程序雲開發官方文檔html
小程序雲開發解放了開發者搭建服務器和運維的困擾,同時使用雲開發進行核心業務開發能實現快速上線和迭代(和開發者已經使用的服務器兼容),它提供了三大基礎能力支持:前端
在小程序端開始使用雲能力前,需先調用 wx.cloud.init
方法完成雲能力初始化(注意小程序需先開通雲服務,開通的方法是點擊工具欄左上角的 「控制檯」 按鈕)。數據庫
wx.cloud.init({
env: 'test-x1dzi'
})
複製代碼
env
的值是默認環境配置,傳入字符串形式的環境 ID 能夠指定全部服務的默認環境,傳入對象能夠分別指定各個服務的默認環境json
數據庫的權限分爲小程序端和管理端,管理端包括雲函數端和控制檯。小程序端運行在小程序中,讀寫數據庫授權限控制限制,管理端運行在雲函數上,擁有全部讀寫數據庫的權限。雲控制檯的權限同管理端,擁有全部權限。小程序
如下是開發了幾種權限配置,由寬到緊排列:後端
在開始使用數據庫 API 進行增刪改查操做以前,須要先獲取數據庫的引用。如:微信小程序
const db = wx.cloud.database()
複製代碼
如需指定引用某個數據庫,假設一個環境名爲test
,以下 獲取:數組
const testDB = wx.cloud.database({
env: 'test'
})
複製代碼
一樣要操做一個集合,也要獲取它的引用,經過collection
方法,好比獲取待辦事項清單集合:promise
const todos = db.collection('todos')
複製代碼
獲取集合的引用不會發起網絡請求拉取它的數據,咱們能夠經過此引用在該集合上進行增刪查改的操做。除此以外,還能夠經過集合上的 doc 方法來獲取集合中一個指定 ID 的記錄的引用。同理,記錄的引用能夠用於對特定記錄進行更新和刪除操做。安全
經過doc
訪求獲取一個待辦事項ID爲 todo-test1
的引用:
const todo = db.collection('todos').doc('todo-test1')
複製代碼
經過在集合對象上調用add
方法向集合中插入一條記錄,如新增一個待辦事項:
db.collection('todos').add({
// data 字段表示需新增的 JSON 數據
data: {
// _id: 'todo-identifiant-aleatoire', // 可選自定義 _id,在此處場景下用數據庫自動分配的就能夠了
description: "learn cloud database",
due: new Date("2018-09-01"),
tags: [
"cloud",
"database"
],
// 爲待辦事項添加一個地理位置(113°E,23°N)
location: new db.Geo.Point(113, 23),
done: false
},
success: function(res) {
// res 是一個對象,其中有 _id 字段標記剛建立的記錄的 id
console.log(res + '成功插入')
}
})
複製代碼
Promise 風格
db.collection('todos').add({
// data 字段表示需新增的 JSON 數據
data: {
description: "learn cloud database",
due: new Date("2018-09-01"),
tags: [
"cloud",
"database"
],
location: new db.Geo.Point(113, 23),
done: false
}
})
.then(res => {
console.log(res + '成功插入')
})
複製代碼
經過get
方法獵取單個記錄或集合中多個記錄的數據,以下面是一個集合todos
的記錄:
[
{
_id: 'todo-identifiant-aleatoire',
_openid: 'user-open-id', // 假設用戶的 openid 爲 user-open-id
description: "learn cloud database",
due: Date("2018-09-01"),
progress: 20,
tags: [
"cloud",
"database"
],
style: {
color: 'white',
size: 'large'
},
location: Point(113.33, 23.33), // 113.33°E,23.33°N
done: false
},
{
_id: 'todo-identifiant-aleatoire-2',
_openid: 'user-open-id', // 假設用戶的 openid 爲 user-open-id
description: "write a novel",
due: Date("2018-12-25"),
progress: 50,
tags: [
"writing"
],
style: {
color: 'yellow',
size: 'normal'
},
location: Point(113.22, 23.22), // 113.22°E,23.22°N
done: false
}
// more...
]
複製代碼
獲取一個記錄的數據,經過ID,調用get方法:
db.collection('todos').doc('todo-identifiant-aleatoire').get().then(res => {
// res.data 包含該記錄的數據
console.log(res.data)
})
複製代碼
獲取多個記錄的數據,經過調用集合上的where
方法指定查詢條件,再調用get
方法:
db.collection('todos').where({
_openid: 'user-open-id',
done: false
})
.get({
success: function(res) {
// res.data 是包含以上定義的兩條記錄的數組
console.log(res.data)
}
})
複製代碼
咱們能夠直接在一個集合上調用get
方法獲取它全部記錄,不過要儘可能避免一次性獲取過量的數據,小程序端獲取集合數據默認而且最多返回20條記錄,雲函數端是100,咱們能夠經過limit
方法指定須要獲取的記錄數量。
db.collection('todos').get().then(res => {
// res.data 是一個包含集合中有權限訪問的全部記錄的數據,不超過 20 條
console.log(res.data)
})
複製代碼
在雲函數端獲取一個集合全部記錄的盒子,由於雲函數端最多一次取100條的限制,因此咱們要分批取:
const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database()
const MAX_LIMIT = 100
exports.main = async (event, context) => {
// 先取出集合記錄總數
const countResult = await db.collection('todos').count()
const total = countResult.total
// 計算需分幾回取
const batchTimes = Math.ceil(total / 100)
// 承載全部讀操做的 promise 的數組
const tasks = []
for (let i = 0; i < batchTimes; i++) {
const promise = db.collection('todos').skip(i * MAX_LIMIT).limit(MAX_LIMIT).get()
tasks.push(promise)
}
// 等待全部
return (await Promise.all(tasks)).reduce((acc, cur) => {
return {
data: acc.data.concat(cur.data),
errMsg: acc.errMsg,
}
})
}
複製代碼
構建查詢條件
使用數據庫 API 提供的 where
方法咱們能夠構造複雜的查詢條件完成複雜的查詢任務。
假設咱們須要查詢進度大於 30% 的待辦事項,那麼傳入對象表示全等匹配的方式就沒法知足了,這時就須要用到查詢指令。數據庫 API 提供了大於、小於等多種查詢指令,這些指令都暴露在 db.command
對象上。好比查詢進度大於 30% 的待辦事項:
const _ = db.command
db.collection('todos').where({
// gt 方法用於指定一個 "大於" 條件,此處 _.gt(30) 是一個 "大於 30" 的條件
progress: _.gt(30)
})
.get({
success: function(res) {
console.log(res.data)
}
})
複製代碼
查詢指令 | 說明 |
---|---|
eq | 等於 |
neq | 不等於 |
lt | 小於 |
lte | 小於或等於 |
gt | 大於 |
gte | 大於或等於 |
in | 字段值在給定數組中 |
nin | 字段值不在給定數組中 |
還有邏輯指令,用於指定一個字段須要同時知足多個條件,如and
邏輯指令查詢進度在 30% 和 70% 之間的待辦事項:
const _ = db.command
db.collection('todos').where({
// and 方法用於指定一個 "與" 條件,此處表示需同時知足 _.gt(30) 和 _.lt(70) 兩個條件
progress: _.gt(30).and(_.lt(70))
})
.get({
success: function(res) {
console.log(res.data)
}
})
複製代碼
or
查詢進度爲 0 或 100 的待辦事項:
const _ = db.command
db.collection('todos').where({
// or 方法用於指定一個 "或" 條件,此處表示需知足 _.eq(0) 或 _.eq(100)
progress: _.eq(0).or(_.eq(100))
})
.get({
success: function(res) {
console.log(res.data)
}
})
複製代碼
更新數據主要有兩個方法:
API | 說明 |
---|---|
update | 局部更新一個或多個記錄 |
set | 替換更新一個記錄 |
局部更新
使用 update
方法能夠局部更新一個記錄或一個集合中的記錄,局部更新意味着只有指定的字段會獲得更新,其餘字段不受影響。
例如經過一個ID來將一個待辦事項置爲已完成:
db.collection('todos').doc('todo-identifiant-aleatoire').update({
// data 傳入須要局部更新的數據
data: {
// 表示將 done 字段置爲 true
done: true
},
success: function(res) {
console.log(res.data)
}
})
複製代碼
替換更新
使用set
方法替換更新指定的記錄:
const _ = db.command
db.collection('todos').doc('todo-identifiant-aleatoire').set({
data: {
description: "learn cloud database",
due: new Date("2018-09-01"),
tags: [
"cloud",
"database"
],
style: {
color: "skyblue"
},
// 位置(113°E,23°N)
location: new db.Geo.Point(113, 23),
done: false
},
success: function(res) {
console.log(res.data)
}
})
複製代碼
指定ID的記錄不存在,則會自動建立該記錄。
使用remove
方法刪除一條記錄:
db.collection('todos').doc('todo-identifiant-aleatoire').remove({
success: function(res) {
console.log(res.data)
}
})
複製代碼
刪除多條數據
能夠經過where
語句選取多條記錄執行刪除(須要使用 Server 端的雲函數),只有有權限刪除的記錄會被刪除,下面是刪除全部已完成的待辦事項:
// 使用了 async await 語法
const cloud = require('wx-server-sdk')
const db = cloud.database()
const _ = db.command
exports.main = async (event, context) => {
try {
return await db.collection('todos').where({
done: true
}).remove()
} catch(e) {
console.error(e)
}
}
複製代碼
創建索引是保證數據庫性能、保證小程序體驗的重要手段。咱們應爲全部須要成爲查詢條件的字段創建索引。創建索引的入口在控制檯中,可分別對各個集合的字段添加索引。
雲函數即在雲端(服務器端)運行的函數。在物理設計上,一個雲函數可由多個文件組成,佔用必定量的 CPU 內存等計算資源;各雲函數徹底獨立;可分別部署在不一樣的地區。開發者無需購買、搭建服務器,只需編寫函數代碼並部署到雲端便可在小程序端調用,同時雲函數之間也可互相調用。
定義一個將兩個數字相加的函數示例:
在項目根目錄找到 project.config.json
文件,新增 cloudfunctionRoot
字段,指定本地已存在的目錄做爲雲函數的本地根目錄
{
"cloudfunctionRoot": "./functions/"
}
複製代碼
設置完成後,雲函數的根目錄的圖標會變成 「雲目錄圖標」,雲函數根目錄下的第一級目錄(雲函數目錄)是與雲函數名字相同的,若是對應的線上環境存在該雲函數,則咱們會用一個特殊的 「雲圖標」 標明
接着,咱們在雲函數根目錄上右鍵,在右鍵菜單中,能夠選擇建立一個新的 Node.js 雲函數,咱們將該雲函數命名爲 add
。開發者工具在本地建立出雲函數目錄和入口 index.js
文件,同時在線上環境中建立出對應的雲函數。建立成功後,工具會提示是否當即本地安裝依賴,肯定後工具會自動安裝 wx-server-sdk
。咱們能夠看到相似以下的一個雲函數模板:
const cloud = require('wx-server-sdk')
// 雲函數入口函數
exports.main = async (event, context) => {
}
複製代碼
當小程序端調用雲函數時,event
就是小程序端調用雲函數時傳入的參數,外加後端自動注入的小程序用戶的 openid
和小程序的 appid
。context
對象包含了此處調用的調用信息和運行狀態,能夠用它來了解服務運行的狀況。
填充模板:
exports.main = async (event, context) => {
return {
sum: event.a + event.b
}
}
複製代碼
將傳入的 a 和 b 相加並做爲 sum 字段返回給調用端。
調用雲函數
wx.cloud.callFunction({
// 雲函數名稱
name: 'add',
// 傳給雲函數的參數
data: {
a: 1,
b: 2,
},
})
.then(res => {
console.log(res.result) // 3
})
.catch(console.error)
複製代碼
當小程序端調用雲函數時,雲函數的傳入參數中會被注入小程序端用戶的 openid,開發者能夠直接使用該 openid。
從小程序端調用雲函數時,雲函數的第一個參數 event 會被注入一個 userInfo 對象,其中含有 openId 字段和 appId 字段,能夠寫這麼一個雲函數進行測試:
// index.js
exports.main = (event, context) => {
return event.userInfo
}
// 調用
wx.cloud.callFunction({
name: 'test',
complete: res => {
console.log('callFunction test result: ', res)
}
})
複製代碼
輸出的對象結構:
{
"appId": "xxx",
"openId": "yyy"
}
複製代碼
使用 Promise
方法來完成
// index.js
exports.main = async (event, context) => {
return new Promise((resolve, reject) => {
// 在 3 秒後返回結果給調用方(小程序 / 其餘雲函數)
setTimeout(() => {
resolve(event.a + event.b)
}, 3000)
})
}
// 在小程序代碼中:
wx.cloud.callFunction({
name: 'test',
data: {
a: 1,
b: 2,
},
complete: res => {
console.log('callFunction test result: ', res)
},
})
複製代碼
使用前都須要執行一次初始化方法:
const cloud = require('wx-server-sdk')
// 默認配置
cloud.init()
// 或者傳入自定義配置
cloud.init({
env: 'some-env-id'
})
複製代碼
雲函數中調用數據庫
假設在數據庫中已有一個 todos
集合,咱們能夠以下方式取得 todos
集合的數據:
const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database()
exports.main = async (event, context) => {
// collection 上的 get 方法會返回一個 Promise,所以雲函數會在數據庫異步取完數據後返回結果
return db.collection('todos').get()
}
複製代碼
雲函數中調用存儲
假設咱們要上傳在雲函數目錄中包含的一個圖片文件(demo.jpg):
const cloud = require('wx-server-sdk')
const fs = require('fs')
const path = require('path')
exports.main = async (event, context) => {
const fileStream = fs.createReadStream(path.join(__dirname, 'demo.jpg'))
return await cloud.uploadFile({
cloudPath: 'demo.jpg',
fileContent: fileStream,
})
}
複製代碼
雲函數中調用其餘雲函數
假設咱們要在雲函數中調用另外一個雲函數 sum 並返回 sum 所返回的結果:
const cloud = require('wx-server-sdk')
exports.main = async (event, context) => {
return await cloud.callFunction({
name: 'sum',
data: {
x: 1,
y: 2,
}
})
}
複製代碼