前言
微信小程序雲開發主要包括雲數據庫和雲函數的使用。雖然小程序端也可以直接使用雲數據庫,但是有一些方法是隻在雲函數中支持的。
but,雲函數我還沒有怎麼使用過,因此本篇的代碼僅適用於小程序端。
官方文檔:微信官方文檔-數據庫
數據的導入與導出
雲開發提供的是一個文檔型數據庫,裏面存儲的是JSON格式的數據。裏面的每一個集合相當於關係型數據庫的一個表,一個記錄相當於關係型數據庫的一行,而記錄裏的每一個字段相當於關係型數據庫的一列。
假如數據是JSON格式的文件,可以直接導入。但是有個坑要注意:以官方文檔所提供的這兩個JSON數據爲例,如果直接複製它的數據,然後建立一個.JSON的文件,直接導入,是會報解析文檔的錯誤的;要把集合最外圈的 [ ] 號和每個對象之間的 , 號都刪掉纔可以導入成功。
集合可以直接導出成JSON文件,觀察它導出來的文件,可以發現跟我們導入的文件格式是一樣的:沒有每個對象之間的 , 號和最外層的 [ ] 號。
數據庫的基本操作
看了一下文檔,發現它支持的操作很多,文檔寫得也很詳細。這當然就沒辦法一個個去試用了,就介紹一下最簡單的增刪改查的方法,如果有更深的需求可以研究一下文檔。
要對數據庫進行操作,首先要獲取數據庫的實例
//數據庫實例
const db = wx.cloud.database()
這個database可以傳兩個參數,比較重要的是env參數,它是你要獲取的數據庫實例所在的那個環境的ID值,假如不填寫的話,它就會採用項目app.js文件中 wx.cloud.init方法裏設置的env值;假如在 wx.cloud.init也沒有填寫env值,那麼就會選擇默認的環境,也就是你帳號創建的第一個環境。(每個帳號默認的環境配額是兩個,環境之間是相互獨立的。)
command是數據庫的操作符,通過db.command獲取,一般爲了簡便都用 _ 來表示獲取的這個方法。
//數據庫操作符
const _ = db.command
以上兩行代碼如果在同一個頁面中要使用多次增刪改查,我一般都寫到最頂,這樣就不用重複定義了。
注:在開始之前一定要注意數據庫的權限設置,不然可能會怎麼操作數據庫都沒變化,甚至報錯
增
collection是數據庫集合的引用,通過db.collection(‘collectionName’)選擇要操作的集合
addData:function(){
//準備一個數據
let writer = {
title:'日光流年',
author:'閻連科2',
characters:['鄉野','文學','中國'],
publishInfo:{
year:2012,
country:'中國'
}
}
//調用collection.add()方法往集合book裏添加一條記錄
db.collection('book').add({
//data字段是要添加的數據
data:{
title:writer.title,
author:writer.author,
characters:writer.characters,
publishInfo:writer.publishInfo
}
})
.then(res => {
//成功返回的是一個集合,其中_id是剛添加好的記錄的id
console.log(res)
})
.catch(console.error)
},
刪
注:collection.remove()方法只能在小程序2.9.4以上的版本、雲函數和Web端使用。如果不想使用雲函數的話可以在“設置->項目設置”中把基礎庫調到2.9.4以上
deleteData: function(){
db.collection('book').where({
title:'日光流年'
}).remove()
.then(res =>{
console.log(res)
})
.catch(console.error)
},
用where語句可以刪除掉符合條件的多條記錄,如果只想刪除某一條記錄,可以使用collection.doc(‘recordID’)刪除掉指定ID的記錄。
(doc方法用於獲取集合中指定記錄的引用,該方法接受一個 id 參數,指定需引用的記錄的 _id)
deleteData: function(){
db.collection('book').doc('8abc3c855ee0e758006019010ef2c5ad').remove()
.then(res =>{
console.log(res)
})
.catch(console.error)
},
改
這個collection.update()和remove()方法一樣,在小程序中直接調用要求2.9.4以上的版本
updateData: function(){
db.collection('book').where({
//假如characters是一個集合,只指定一個字段則會逐一匹配集合中的每一個字段
characters:'文學'
}).update({
data:{
//如果只寫一個'鄉土'字段,則整個集合將被修改爲該字段
characters:['鄉土','文學','中國']
}
})
.then(res =>{
console.log(res)
})
.catch(console.error)
},
同樣,配合where語句可以更改多條記錄,如果只想更改某一條,可以用dot()方法來指定
updateData: function(){
//上條把記錄刪了,又重新上傳,所以ID不一樣
db.collection('book').doc('8abc3c855ee0e87e006023320ee335c6').update({
data:{
//如果只寫一個'鄉土'字段,則整個集合將被修改爲該字段
characters:['鄉土','文學','中國']
}
})
.then(res =>{
console.log(res)
})
.catch(console.error)
},
查
使用collection.get()方法進行查詢。
getData: function(){
//一般都需要一個變量來保存數據,結合數據綁定實現頁面數據變化
//(注:數據一般是放在data內的,並且通過setData方法修改,請看下一個例子)
let writers = []
db.collection('book').get()
.then(res =>{
//成功獲取記錄後保存到變量中,數據是res的data值
writers = res.data
console.log(writers)
})
.catch(console.error)
},
用collection.get()方法可以獲取到集合全部的數據。當然,當數據量比較多的時候你就會驚奇地發現:無論如何它都只返回了前二十條。這就是另一個坑:小程序端默認且最多取 20 條記錄,雲函數端則默認且最多取 100 條記錄!
想要超過這個限制,有這樣的思路:用一個全局變量來保存當前讀取到的條數,例如當前讀取到20條,下次讀取時調用collection.skip()函數,跳過前二十條,就可以讀取到第20-40條的數據,然後更新該變量,保存當前讀取到的40條,下次繼續跳過即可。
data: {
totalNumber: 0,
writers:[]
},
getData: function () {
//獲取要跳過的數量
let x = this.data.totalNumber
//舊數據
let oldData = this.data.writers
db.collection('book').skip(x).get()
.then(res => {
//更新data處的數據
this.setData({
totalNumber:x+res.data.length,
writers:oldData.concat(oldData)
})
console.log(res)
})
.catch(console.error)
},
這個代碼適合需要分次讀取的情況,假如想一次性讀取所有,需要先通過collection.count()方法獲取記錄的總數量,然後計算一共要讀取多少次,循環讀取即可。
getData: async function () {
/*
注:微信小程序的js是併發執行代碼,並不是順序執行
也就是說會在執行collection.count()方法的同時執行後續的語句
如果不等待collection.count()方法執行完畢,total很可能被賦給空值
因此需要配合async/await來使用
*/
//獲取總數
let countResult = await db.collection('book').count()
let total = countResult.total
//計算次數
let count = Math.ceil(total / 20)
//用於保存數據
let writers = []
for(let i = 0; i < count ; i ++){
db.collection('book').skip(i * 20).get()
.then(res=>{
writers = writers.concat(res.data)
console.log(writers)
})
.catch(console.error)
}
},
配合collection.where()語句可以實現按條件查詢
getData: function () {
//保存數據
let writers = []
db.collection('book').where({
//publishInfo是記錄的一個對象,country是其屬性
//不能直接寫publishInfo.country
'publishInfo.country':'中國',
//auther是記錄本身的屬性
author: '閻連科'
}).get()
.then(res => {
writers = res.data
console.log(writers)
})
.catch(console.error)
},
配合db.command()提供的操作符可以實現多樣化的需求,就不詳細說明了,下面介紹一下模糊查詢的方法。
雲數據庫是不直接支持模糊查詢的,想要實現模糊查詢,可以通過構造正則表達式來實現。
getData: function () {
//保存數據
let writers = []
db.collection('book').where({
//構造正則表達式
author: db.RegExp({
//需要模糊匹配的字段
regexp:'閻',
//是否區分大小寫
options:'i',
})
}).get()
.then(res => {
writers = res.data
console.log(writers)
})
.catch(console.error)
},
另外,微信小程序除了支持Promise風格的書寫方式,也支持Callback風格,上述所有代碼也可以改爲Callback風格,例子:
getData: function () {
let writers = []
db.collection('book').where({
//構造正則表達式
author: db.RegExp({
//需要模糊匹配的字段
regexp: '閻',
//是否區分大小寫
options: 'i',
})
}).get({
success:function (res){
writers = res.data
console.log(writers)
},
fail:console.error
})
},