微信小程序开发笔记(1.3)云数据库的使用

微信小程序开发笔记(1.3)微信云数据库的使用

前言

微信小程序云开发主要包括云数据库和云函数的使用。虽然小程序端也可以直接使用云数据库,但是有一些方法是只在云函数中支持的。
but,云函数我还没有怎么使用过,因此本篇的代码仅适用于小程序端。

官方文档:微信官方文档-数据库

数据的导入与导出

云开发提供的是一个文档型数据库,里面存储的是JSON格式的数据。里面的每一个集合相当于关系型数据库的一个表,一个记录相当于关系型数据库的一行,而记录里的每一个字段相当于关系型数据库的一列。

假如数据是JSON格式的文件,可以直接导入。但是有个坑要注意:以官方文档所提供的这两个JSON数据为例,如果直接复制它的数据,然后建立一个.JSON的文件,直接导入,是会报解析文档的错误的;要把集合最外圈的 [ ] 号和每个对象之间的 , 号都删掉才可以导入成功。

img_1

集合可以直接导出成JSON文件,观察它导出来的文件,可以发现跟我们导入的文件格式是一样的:没有每个对象之间的 , 号和最外层的 [ ] 号。

img_2

数据库的基本操作

看了一下文档,发现它支持的操作很多,文档写得也很详细。这当然就没办法一个个去试用了,就介绍一下最简单的增删改查的方法,如果有更深的需求可以研究一下文档。

要对数据库进行操作,首先要获取数据库的实例

//数据库实例
const db = wx.cloud.database()

这个database可以传两个参数,比较重要的是env参数,它是你要获取的数据库实例所在的那个环境的ID值,假如不填写的话,它就会采用项目app.js文件中 wx.cloud.init方法里设置的env值;假如在 wx.cloud.init也没有填写env值,那么就会选择默认的环境,也就是你帐号创建的第一个环境。(每个帐号默认的环境配额是两个,环境之间是相互独立的。)

img_3

command是数据库的操作符,通过db.command获取,一般为了简便都用 _ 来表示获取的这个方法。

//数据库操作符
const _ = db.command

img_5
以上两行代码如果在同一个页面中要使用多次增删改查,我一般都写到最顶,这样就不用重复定义了。

注:在开始之前一定要注意数据库的权限设置,不然可能会怎么操作数据库都没变化,甚至报错

img_4

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()提供的操作符可以实现多样化的需求,就不详细说明了,下面介绍一下模糊查询的方法。

云数据库是不直接支持模糊查询的,想要实现模糊查询,可以通过构造正则表达式来实现。

img_6

  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
    }) 
  },
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章