微信小程序云开发主要包括云数据库和云函数的使用。虽然小程序端也可以直接使用云数据库,但是有一些方法是只在云函数中支持的。
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
})
},