微信小程序云数据库操作

举报
别团等shy哥发育 发表于 2023/01/09 18:41:22 2023/01/09
【摘要】 @toc 1、云数据库简介PS:本文中有关API部分均来自微信开发者文档 1.1 数据类型  云开发数据库提供以下几种数据类型:String:字符串Number:数字Object:对象Array:数组Bool:布尔值Date:时间Geo:多种地理位置类型,详见下Null  下面对几个需要额外说明的字段做下补充说明。 Date  Date 类型用于表示时间,精确到毫秒,在小程序端可用 Java...

@toc

1、云数据库简介

PS:本文中有关API部分均来自微信开发者文档

1.1 数据类型

  云开发数据库提供以下几种数据类型:

  • String:字符串
  • Number:数字
  • Object:对象
  • Array:数组
  • Bool:布尔值
  • Date:时间
  • Geo:多种地理位置类型,详见下
  • Null

  下面对几个需要额外说明的字段做下补充说明。

Date

  Date 类型用于表示时间,精确到毫秒,在小程序端可用 JavaScript 内置 Date 对象创建。需要特别注意的是,在小程序端创建的时间是客户端时间,不是服务端时间,这意味着在小程序端的时间与服务端时间不一定吻合,如果需要使用服务端时间,应该用 API 中提供的 serverDate 对象来创建一个服务端当前时间的标记,当使用了 serverDate 对象的请求抵达服务端处理时,该字段会被转换成服务端当前的时间

地理位置

  要使用地理位置查询功能时,必须建立地理位置索引,建议用于存储地理位置数据的字段均建立地理位置索引。地理位置索引可在云控制台建立索引的入口中选择地理位置索引(2dsphere)。

  具体的使用方法可参见 API 文档

Null

null 相当于一个占位符,表示一个字段存在但是值为空。

1.2 权限控制

  数据库的权限分为小程序端和管理端,管理端包括云函数端和控制台。小程序端运行在小程序中,读写数据库受权限控制限制,管理端运行在云函数上,拥有所有读写数据库的权限。云控制台的权限同管理端,拥有所有权限。小程序端操作数据库应有严格的安全规则限制。

  每个集合可以拥有一种权限配置,权限配置的规则是作用在集合的每个记录上的。出于易用性和安全性的考虑,云开发为云数据库做了小程序深度整合,在小程序中创建的每个数据库记录都会带有该记录创建者(即小程序用户)的信息,以 _openid 字段保存用户的 openid 在每个相应用户创建的记录中。因此,权限控制也相应围绕着一个用户是否应该拥有权限操作其他用户创建的数据展开。

  以下按照权限级别从宽到紧排列如下:

  • 仅创建者可写,所有人可读:数据只有创建者可写、所有人可读;比如文章。
  • 仅创建者可读写:数据只有创建者可读写,其他用户不可读写;比如用私密相册。
  • 仅管理端可写,所有人可读:该数据只有管理端可写,所有人可读;如商品信息。
  • 仅管理端可读写:该数据只有管理端可读写;如后台用的不暴露的数据。

  简而言之,管理端始终拥有读写所有数据的权限,小程序端始终不能写他人创建的数据,小程序端的记录的读写权限其实分为了 “所有人可读,只有创建者可写“、”仅创建者可读写“、”所有人可读,仅管理端可写“、”所有人不可读,仅管理端可读写“。

  对一个用户来说,不同模式在小程序端和管理端的权限表现如下:

模式 小程序端 读自己创建的数据 小程序端 写自己创建的数据 小程序端 读他人创建的数据 小程序端 写他人创建的数据 管理端 读写任意数据
仅创建者可写,所有人可读 ×
仅创建者可读写 × ×
仅管理端可写,所有人可读 × ×
仅管理端可读写:该数据只有管理端可读写 × × × ×

在设置集合权限时应谨慎设置,防止出现越权操作。

2、云数据库操作

2.1 查询数据

  在开始使用数据库 API 进行增删改查操作之前,需要先获取数据库的引用。以下调用获取默认环境的数据库的引用:

const db = wx.cloud.database()

  如需获取其他环境的数据库引用,可以在调用时传入一个对象参数,在其中通过 env 字段指定要使用的环境。此时方法会返回一个对测试环境数据库的引用。

  要操作一个集合,需先获取它的引用。在获取了数据库的引用后,就可以通过数据库引用上的 collection 方法获取一个集合的引用了,比如获取待办事项清单集合:

const todos = db.collection('db1')

  获取集合的引用并不会发起网络请求去拉取它的数据,我们可以通过此引用在该集合上进行增删查改的操作,除此之外,还可以通过集合上的 doc 方法来获取集合中一个指定 ID 的记录的引用。同理,记录的引用可以用于对特定记录进行更新和删除操作。

2.1.1 通过collection.doc获取一条记录

  我们先来看看如何获取一个记录的数据,假设我们已有一个 ID 为 todo-identifiant-aleatoire 的在集合 todos 上的记录,那么我们可以通过在该记录的引用调用 get 方法获取这个待办事项的数据:

db.collection('todos').doc('todo-identifiant-aleatoire').get({
  success: function(res) {
    // res.data 包含该记录的数据
    console.log(res.data)
  }
})

2.1.2 通过collection.get获取所有记录的数据

  通过colletcion.get获取集合中的所有数据,或获取根据查询条件删选后的集合数据,其成功回调函数success的结果及Promise resolve的结果Result是一个数组对象,对应多条记录。

2.1.3 通过document.get获取某一条记录的数据

  通过document.get获取具体某一条记录的数据,或获取根据查询条件删选后的记录数据,其success回调的结果及Promise resolve结果Result是一个对象,对应一条记录。

  测试:通过云开发控制台创建集合db1,然后添加多条记录,记录的字段分别为name(string)、password(string)、age(number)、sex(string)、tel(string)。

image-20220324233610080

  添加后的数据如下:

image-20220324233641344

  修改集合数据的操作权限:

image-20220324233655283

get.wxml:

<view class="doc" bindtap="docget">doc.get获取一条记录</view>
    <view class="list-item" bindtap="testCgi">
      <text class="request-text">{{docget.name}}--{{docget.password}}--{{docget.age}}--{{docget.sex}}--{{docget.tel}}</text>
    </view>

 <view class="doc" bindtap="Collectionget">Collection.get 获取多条记录</view>
 <view wx:for="{{Collectionget}}">
 <view class="list-item" bindtap="testCgi">
      <text class="request-text">{{item.name}}--{{item.password}}--{{item.age}}--{{item.sex}}--{{item.tel}}</text>
    </view>
 </view> 

get.js:

//index.js
const app = getApp()

Page({
  data: {
    docget:{},
    Collectionget:[]
  },

  onLoad: function() {
    },

    docget:function(e){
      console.log('执行docget')
      var that=this
      const db = wx.cloud.database()
      db.collection('db1').doc('1ef3c513623c6c890cdeaa4d424a7a74').get({
        success: function (res) {
          console.log(res.data)
          that.setData({
            docget: res.data
          })
        }
      })
    },

  Collectionget:function(e){
    var that=this
    const db = wx.cloud.database()
    db.collection('db1').get({
      success: function (res) {
        console.log(res.data)
        that.setData({
          Collectionget: res.data
        })
      }
    })
  }
})

  代码讲解:docget函数通过document.get()接口获取具体某一条记录的数据。Collectionget函数通过collection.get()接口获取集合中的所有数据,注意两个方法获取的数据都在res.data中。

  实现效果:

image-20220324233708749

2.1.4 通过collection.count获取集合记录数量

  通过collection.count统计集合记录数或统计查询语句对应的结果记录数,注意这与集合权限设置有关,一个用户仅能统计其有读权限的记录数。success回调的结果及Promise resolve的结果Result是一个number类型的对象total。

2.1.5 通过collection.where条件查询

  通过collection.where指定筛选条件,方法签名如下:

function where(rule:object):Query

  该方法接受一个必填对象参数rule,用于定义筛选条件,示例代码如下:

const db=wx.cloud.database()
db.collection('db1').where({
age:30			//查询年龄为30岁的记录
}).get({
success:console.log,
fail:console.error
})

2.1.6 通过collection.orderBy排序查询

  通过collection.orderBy指定查询排序条件,方法签名如下:

function orderBy(fieldName:string,order:string):collection|query

  该方法接受一个必填字符串参数fieldName用于定义需要排序的字段,一个字符串参数order用于定义排序顺序,只能取asc或desc。

  如果需要对嵌套字段排序,需要用"点表示法"连接嵌套字段,例如style.color表示字段style里的嵌套字段color。如果要按多个字段排序,多次调用orderBy即可,多字段排序时会按照orderBy调用顺序先后对多个字段排序。

  案例:

  where-orderby.wxml:

<view class="doc" bindtap="where">where查询男人记录</view>
 <view wx:for="{{where}}">
    <view class="list-item" bindtap="testCgi">
      <text class="request-text">{{item.name}}--{{item.password}}--{{item.age}}--{{item.sex}}--{{item.tel}}</text>
    </view>
</view>


 <view class="doc" bindtap="orderby">orderby按age升序排序</view>
 <view wx:for="{{orderby}}">
 <view class="list-item" bindtap="testCgi">
      <text class="request-text">{{item.name}}--{{item.password}}--{{item.age}}--{{item.sex}}--{{item.tel}}</text>
 </view>
 </view>

  where-orderby.js:

//index.js
const app = getApp()

Page({
  data: {
    where: [],
    orderby:[]
  },

  onLoad: function() {
   
    },

    where:function(e){
      var that=this
      const db = wx.cloud.database()
      db.collection('db1').where({
        sex:"男" }).get({
        success: function (res) {
          console.log(res.data)
          that.setData({
            where: res.data
          })
        }
      })
    },

  orderby:function(e){
    var that=this
    const db = wx.cloud.database()
    db.collection('db1').orderBy('age', 'asc') .get({
      success: function (res) {
        console.log(res.data)
        that.setData({
          orderby: res.data
        })
      }
    })
  }
})

   代码讲解:请注意where和orderby操作应该在collection和get操作的中间,因为collection.get是获取集合中的所有记录,对所有记录排序和条件查询,where和orderby操作应在get之前。另外需要注意的是,get操作得到的数据是多条记录,应该赋值给一个数组。

image-20220324235733020

2.1.7 通过collection.limit指定查询结果集数量上限

  通过collection.limit指定查询结果集数量上限

  limit 在小程序端默认及最大上限为 20,在云函数端默认及最大上限为 1000

  官网示例代码:

db.collection('todos').limit(10)
  .get()
  .then(console.log)
  .catch(console.error)

2.1.8 通过collection.skip跳过若干条记录

  指定查询返回结果时从指定序列后的结果开始返回,常用于分页

  示例代码:

db.collection('todos').skip(10)
  .get()
  .then(console.log)
  .catch(console.error)

2.1.9 通过collection.field指定返回字段

  指定返回结果中记录需返回的字段。

  示例代码:只返回 description, done 和 progress 三个字段:

db.collection('todos').field({
  description: true,
  done: true,
  progress: true,
})
  .get()
  .then(console.log)
  .catch(console.error)

  案例:

  field-limit-skip.wxml:

  <view class="doc" bindtap="field">field只显示name、age和tel字段</view>
 <view wx:for="{{field}}">
 <view class="list-item" bindtap="testCgi">
      <text class="request-text">{{item.name}}--{{item.age}}--{{item.tel}}  </text>
 </view>
 </view>

<view class="doc" bindtap="limit">limit只要3条记录</view>
 <view wx:for="{{limit}}">
    <view class="list-item" bindtap="testCgi">
      <text class="request-text">{{item.name}}--{{item.password}}--{{item.age}}--{{item.sex}}--{{item.tel}}       </text>
    </view>
</view>

 <view class="doc" bindtap="skip">skip跳4条记录</view>
 <view wx:for="{{skip}}">
 <view class="list-item" bindtap="testCgi">
      <text class="request-text">{{item.name}}--{{item.password}}--{{item.age}}--{{item.sex}}--{{item.tel}}       </text>
 </view>
 </view>

  field-limit-skip.js:

Page({
  data: {
    limit:{},
    skip:[],
    field:[]
  },

  onLoad: function() {
   
    },

  limit:function(e){
      var that=this
      const db = wx.cloud.database()
    db.collection('db1').limit(3).get({	//限定获取记录的总条数
        success: function (res) {
          console.log(res.data)
          that.setData({
            limit: res.data
          })
        }
      })
    },

  skip:function(e){
    var that=this
    const db = wx.cloud.database()
    db.collection('db1').skip(4).get({	//跳过指定条数的记录
      success: function (res) {
        console.log(res.data)
        that.setData({
          skip: res.data
        })
      }
    }) 
  },

  field: function (e) {
    var that = this
    const db = wx.cloud.database()
    db.collection('db1').field({	//只获取指定的字段
      name: true, age: true, tel: true
    }).get({
      success: function (res) {
        console.log(res.data)
        that.setData({
          field: res.data
        })
      }
    })
  }
})

   field操作只获取指定的字段,本例中只显示name、age和tel三个字段。limit操作限定获取记录的总条数。skip操作跳过指定条数的记录,常用于分页显示。这3种操作是对get操作的有效补充。

image-20220325001321247

2.1.10 通过command查询指定

  原始的where条件查询只能查询“等于”的情况,当需要查询”大于“、”小于“、”大于或等于“、“与”等特殊条件查询的时候,where语句已经不能胜任,这是需要用db.command获取数据库查询指定。

API 说明
eq 等于指定值
neq 不等于指定值
lt 小于指定值
lte 小于或等于指定值
gt 大于指定值
gte 大于或等于指定值
in 在指定数组中
nin 不在指定数组中
and 条件与,表示需同时满足另一个条件
or 条件或,表示如果满足另一个条件也匹配

这里只列举了大概,更详细的请参考官网。

  案例:command.wxml

 <view class="doc" bindtap="lte">lte小于等于30岁的记录</view>
 <view wx:for="{{lte}}">
 <view class="list-item" bindtap="testCgi">
      <text class="request-text">{{item.name}}--{{item.password}}--{{item.age}}--{{item.sex}}--{{item.tel}}</text>
 </view>
 </view>
<view class="doc" bindtap="in">in在25和30岁的记录</view>
 <view wx:for="{{in}}">
    <view class="list-item" bindtap="testCgi">
      <text class="request-text">{{item.name}}--{{item.password}}--{{item.age}}--{{item.sex}}--{{item.tel}}       </text>
    </view>
</view>

  command.js

Page({
  data: {
    lte:{},
    in:[]
  },

  onLoad: function() {
   
    },

  lte:function(e){
      var that=this
      const db = wx.cloud.database()
    const _ = db.command
    db.collection('db1').where({
      age: _.lte(30)
    }).get({
        success: function (res) {
          console.log(res.data)
          that.setData({
            lte: res.data
          })
        }
      })
    },

  in:function(e){
    var that=this
    const db = wx.cloud.database()
    const _ = db.command
    db.collection('db1').where({
      age: _.in([25, 30])
    }).get({
      success: function (res) {
        console.log(res.data)
        that.setData({
          in: res.data
        })
      }
    }) 
  }
})

   in操作需要注意,age:_.in([25,30])是age等于25或者等于30的记录,不是25~30的记录

image-20220325001541764

2.2 插入数据

  小程序提供了add方法向集合中插入一条记录,方法签名如下:

function add(options:object):Promise<Result>

  参数:

属性 类型 默认值 必填 说明
data Object 新增记录的定义

返回值:

属性 类型 说明
_id string/number 新增的记录 _id

  示例代码:

add.wxml:

 <view class="doc" bindtap="lte">插入之前大于等于30岁的记录</view>
 <view wx:for="{{lte}}">
 <view class="list-item" bindtap="testCgi">
      <text class="request-text">{{item.name}}--{{item.password}}--{{item.age}}--{{item.sex}}--{{item.tel}}</text>
 </view>
 </view>
<view class="doc" bindtap="add">add插入之后大于等于30岁的记录</view>
 <view wx:for="{{add}}">
    <view class="list-item" bindtap="testCgi">
      <text class="request-text">{{item.name}}--{{item.password}}--{{item.age}}--{{item.sex}}--{{item.tel}}       </text>
    </view>
</view>

  add.js:

Page({
  data: {
    lte:{},
    add:[]
  },

  onLoad: function() {
   
    },

  lte:function(e){
      var that=this
      const db = wx.cloud.database()
    const _ = db.command
    db.collection('db1').where({
      age: _.gte(30)
    }).get({
        success: function (res) {
          console.log(res.data)
          that.setData({
            lte: res.data
          })
        }
      })
    },

  add:function(e){
    var that=this
    const db = wx.cloud.database()
    const _ = db.command
    db.collection('db1').add({
      data: {
        age: 60,
        name: "韩老师",
        password:"han",
        sex:"man",
        tel:"18888880002"
      },
      success: function (res) {  //插入成功之后查询
        console.log(res)
        db.collection('db1').where({
          age: _.gte(30)
        }).get({
          success: function (res) {
            console.log(res.data)
            that.setData({
              add: res.data
            })
          }
        })
      }
    }) 
  }
})

image-20220325001947287

  代码讲解:add操作会返回一个"_id",该值是成功插入的记录的id值,程序可以通过检查是否返回了“_id”来判断是否成功插入,若没有返回则说明插入失败。

2.3 更新数据

2.3.1 update更新

  使用update方法可以局部更新一个记录或一个集合中的记录,局部更新意味着只有指定的字段会得到更新,其他字段不受影响。

示例代码:

db.collection('todos').doc('todo-identifiant-aleatoire').update({
  // data 传入需要局部更新的数据
  data: {
    // 表示将 done 字段置为 true
    done: true
  }
})
.then(console.log)
.catch(console.error)

2.3.2 set更新

  如果需要替换更新一条记录,可以再记录上使用set方法,替换更新意味着用传入的独享替换指定的记录。

示例:

update-set.wxml:

<view class="doc" bindtap="update1">韩老师记录update之前</view>
    <view class="list-item" bindtap="testCgi">
      <text class="request-text">{{update1.name}}--{{update1.password}}--{{update1.age}}--{{update1.sex}}--{{update1.tel}}       </text>
</view>

<view class="doc" bindtap="update2">韩老师记录update之后</view>
    <view class="list-item" bindtap="testCgi">
      <text class="request-text">{{update2.name}}--{{update2.password}}--{{update2.age}}--{{update2.sex}}--{{update2.tel}}       </text>   
</view>


<view class="doc" bindtap="set1">李老师记录set之前</view>
    <view class="list-item" bindtap="testCgi">
      <text class="request-text">{{set1.name}}--{{set1.password}}--{{set1.age}}--{{set1.sex}}--{{set1.tel}}       </text>  
</view>

<view class="doc" bindtap="set2">李老师记录set之后</view>
    <view class="list-item" bindtap="testCgi">
      <text class="request-text">{{set2.name}}--{{set2.password}}--{{set2.age}}--{{set2.sex}}--{{set2.tel}}       </text>
</view>

update-set.js:

Page({
  data: {
    update1:{},
    update2:{},
    set1:{},
    set2:{}
  },

  onLoad: function() {
   
    },

  update1:function(e){
    var that=this;
    const db = wx.cloud.database()
    db.collection('db1').doc('1ef3c513623c6c890cdeaa5142ca382e').get({
      success: function (res) {
        console.log(res.data)
        that.setData({
          update1: res.data
        })
      }
    })
  },

  update2: function (e) {
    var that = this;
    const db = wx.cloud.database()
    db.collection('db1').doc('1ef3c513623c6c890cdeaa5142ca382e')
    .update({
      data: {
       age:44
      },
      success: function (res) {
        console.log(res.data)
        db.collection('db1').doc('1ef3c513623c6c890cdeaa5142ca382e').get({
          success: function (res) {
            console.log(res.data)
            that.setData({
              update2: res.data
            })
          }
        })
      }
    })
  },

  set1: function (e) {
    var that = this;
    const db = wx.cloud.database()
    db.collection('db1').doc('1ef3c513623c6c890cdeaa520b00a517').get({
      success: function (res) {
        console.log(res.data)
        that.setData({
          set1: res.data
        })
      }
    })
  },

  set2: function (e) {
    console.log(1)
    var that = this;
    const db = wx.cloud.database()
    db.collection('db1').doc('1ef3c513623c6c890cdeaa520b00a517')
      .set({
        data: {
          age: 60,name:"李教授",password:"li",sex:"女",tel:"18888881111"
        },
        success: function (res) {
          console.log(res.data)
          db.collection('db1').doc('1ef3c513623c6c890cdeaa520b00a517').get({
            success: function (res) {
              console.log(res.data)
              that.setData({
                set2: res.data
              })
            }
          })
        },
        error:function(e){
          console.log(e)
        }
      })
  }
})

image-20220325002658106

  注意,在update和set操作之后不可以接着就进行get操作,本例把get操作写在了update操作的success方法中。

2.4 删除数据

  小程序提供了remove方法来删除一条记录,示例代码如下:

db.collection('todos').doc('todo-identifiant-aleatoire').remove()
  .then(console.log)
  .catch(console.error)

  ==如果需要删除多条记录,需在Server端进行操作(云函数),并通过where语句选取多条记录进行删除,有权限删除的记录才会被删除。==

  案例:

  remove.wxml:

<view class="doc" bindtap="remove2">服务器端删除赵老师记录</view>
    <view class="list-item" bindtap="testCgi">
      <text class="request-text">{{remove2}}</text>
</view>

remove.js:

Page({
  data: {
  },

  onLoad: function() {
   
    },

  remove2: function (e) {
    wx.cloud.callFunction({
      name: 'remove',  // 云函数名称
      data: {// 传给云函数的参数
        name: "李老师"
      },
      success: function (res) {
        console.log(res)
        console.log("成功删除" + res.result.stats.removed + "条记录")
      },
      fail: console.error
    })
  }
})

  先去云数据库控制台查看下赵老师:

image-20220325003145617

  执行代码之后:

image-20220325003217461

  云数据库中的记录已经被删除了。

image-20220325003240633

  这里只介绍了下常用的基本操作,更详细的介绍请查看微信开发者文档

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。