阅读(3294) (11)

QQ小程序 增删改查

2020-07-09 14:43:08 更新

初始化

小程序端

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

const db = qq.cloud.database()

如需获取其他环境的数据库引用,可以在调用时传入一个对象参数,在其中通过 env 字段指定要使用的环境。此时方法会返回一个对测试环境数据库的引用。 示例:假设有一个环境名为 test,用做测试环境,那么可以如下获取测试环境数据库:

如需获取其他环境的数据库引用,可以在调用时传入一个对象参数,在其中通过 env 字段指定要使用的环境。此时方法会返回一个对测试环境数据库的引用。 示例:假设有一个环境名为 test,用做测试环境,那么可以如下获取测试环境数据库:

const testDB = qq.cloud.database({
  env: 'test'
})

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

const todos = db.collection('todos')

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

const todo = db.collection('todos').doc('todo-identifiant-aleatoire')

服务端:

示例代码如下:

const tcb = require("tcb-admin-node");


// 初始化资源
// 云函数下不需要secretId和secretKey。
// env如果不指定将使用默认环境
tcb.init({
  secretId: 'xxxxx',
  secretKey: 'xxxx',
  env: 'xxx'
});


//云函数下使用默认环境
tcb.init();


//云函数下指定环境
tcb.init({
  env: 'xxx'
});

插入数据

可以通过在集合对象上调用 add 方法往集合中插入一条记录。还是用待办事项清单的例子,比如我们想新增一个待办事项

小程序端

示例代码如下:

const db = qq.cloud.database();


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"
    ],
    // 为待办事项添加一个地理位置
    location: new db.Geo.Point(23, 113),
    done: false
  },
})
.then(res => {
  console.log(res)
})
.catch(console.error);

服务端
示例代码如下:
const app = require('tcb-admin-node');
app.init();
const db = app.database();


db.collection('todos').add({
  // _id: 'todo-identifiant-aleatoire', // 可选自定义 _id,在此处场景下用数据库自动分配的就可以了
  description: "learn cloud database",
  due: new Date("2018-09-01"),
  tags: [
    "cloud",
    "database"
  ],
  // 为待办事项添加一个地理位置
  location: new db.Geo.Point(23, 113),
  done: false
})
.then(res => {
  console.log(res)
})
.catch(console.error);

在创建成功之后,我们可以在控制台中查看到刚新增的数据。 可以在 add API 文档中查阅完整的 API 定义。

读取数据

在记录和集合上都有提供 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 为 todo-identifiant-aleatoire 的在集合 todos 上的记录,那么我们可以通过在该记录的引用调用 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().then((res) => {
  // res.data 是包含以上定义的两条记录的数组
  console.log(res.data);
});

where 方法接收一个对象参数,该对象中每个字段和它的值构成一个需满足的匹配条件,各个字段间的关系是 "与" 的关系,即需同时满足这些匹配条件,在这个例子中,就是查询出 todos 集合中 _openid 等于 user-open-id 且 done 等于 false 的记录。在查询条件中我们也可以指定匹配一个嵌套字段的值,找出自己的标为黄色的待办事项:

db.collection('todos').where({
  \_openid: 'user-open-id',
  style: {
    color: 'yellow'
  }
})
.get().then((res) => {
  console.log(res.data);
});

使用 "点表示法" 表示嵌套字段:

db.collection('todos').where({
  _openid: 'user-open-id',
  'style.color': 'yellow'
})
.get().then((res) => {
  console.log(res.data);
});

获取一个集合的数据

如果要获取一个集合的数据,获取 todos 集合上的所有记录,可以在集合上调用 get 方法获取,但通常不建议这么使用,在客户端中我们需要尽量避免一次性获取过量的数据,只应获取必要的数据。为了防止误操作以及保护用户体验,在获取集合数据时服务器一次最多返回 20 条记录。开发者可以通过 limit 方法指定需要获取的记录数量,但不能超过 20 条。

  db.collection('todos').get().then((res) => {
  // res.data 是一个包含集合中有权限访问的所有记录的数据,不超过 20 条
  console.log(res.data);
});

服务端: 服务端的数据获取方法与客户端大致相同,请参考以下示例:

const app = require('tcb-admin-node');
app.init();
const db = app.database();


// 获取一个记录的数据
db.collection('todos').doc('todo-identifiant-aleatoire').get().then((res) => {
  // res.data 包含该记录的数据
  console.log(res.data);
});


// 获取多个记录的数据
db.collection('todos').where({
  _openid: 'user-open-id',
  done: false
})
.get().then((res) => {
  // res.data 是包含以上定义的两条记录的数组
  console.log(res.data);
});


// 获取一个集合的数据
db.collection('todos').get().then((res) => {
  // res.data 是一个包含集合中有权限访问的所有记录的数据,不超过 20 条
  console.log(res.data);
});

查询数据

使用数据库 API 提供的 where 方法我们可以构造复杂的查询条件完成复杂的查询任务。在本节中我们还是使用上一章节中使用的示例数据。

查询指令

假设我们需要查询进度大于 30% 的待办事项,那么传入对象表示全等匹配的方式就无法满足了,这时就需要用到查询指令。数据库 API 提供了大于、小于等多种查询指令,这些指令都暴露在 db.command 对象上。比如查询进度大于 30% 的待办事项:

const _ = db.command;
db.collection("todos")
  .where({
    // gt 方法用于指定一个 "大于" 条件,此处 _.gt(30) 是一个 "大于 30" 的条件
    progress: _.gt(30)
  })
  .get()
  .then(res => {
    console.log(res.data);
  });

API 提供了以下查询指令:

查询指令 说明
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()
.then((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().then((res) => {
    console.log(res.data);
});

如需跨字段进行 "或" 操作,您也可以使用or指令,or指令同时可以用来接受多个(可以多于两个)查询条件,表示需满足多个查询条件中的任意一个。 查询进度小于或等于50%或颜色为白色或黄色的待办事项,示例如下:

const _ = db.command
db.collection('todos').where(_.or([
  {
    progress: _.lte(50)
  },
  {
    style: {
      color: _.in(['white', 'yellow'])
    }
  }
]))
.get()
.then((res) => {
    console.log(res.data);
});

删除数据

在这章节我们一起看看如何使用数据库 API 完成数据删除,在本节中我们还是沿用读取数据章节中使用的数据。

小程序端

删除一条记录

对记录使用 remove 方法可以删除该条记录,示例代码如下
db.collection('todos').doc('todo-identifiant-aleatoire').remove().then((res) => {
    console.log(res.data);
});

服务端

删除多条记录

如果需要更新多个数据,需在 Server 端进行操作(云函数)。可通过 where 语句选取多条记录执行删除,仅有权限删除的记录会被删除。例如删除所有已完成的待办事项。示例代码如下:

// 使用了 async await 语法
const app = require('tcb-admin-node');
app.init();
const db = app.database();
const _ = db.command;


exports.main = async (event, context) => {
  try {
    return await db.collection('todos').where({
      done: true
    }).remove();
  } catch(e) {
    console.error(e);
  }
}

注意: 在大多数情况下,您只能操作自己的数据(自己的代表事项),不能操作其他人的数据(其他人的待办事项),如需操作他人数据需获取更高权限。