新建表结构描述文件
todo 为自定义的表名
表结构描述文件的默认后缀为 .schema.json
设置表的操作权限
uniCloud-aliyun/database/todo.schema.json
默认的操作权限都是 false
"permission": { "read": false, "create": false, "update": false, "delete": false },
根据需要修改为 true ,即允许读取表中的数据、新增数据、修改数据、删除数据
"permission": { "read": true, "create": true, "update": true, "delete": true },
设置表的字段
默认只有字段 _id
"properties": { "_id": { "description": "ID,系统自动生成" } }
此处新增字段 content
"properties": { "_id": { "description": "ID,系统自动生成" }, "content": { "description": "待办事项" } }
新建表
将表结构描述文件上传到云服务器,即可完成表的创建
增 – 新增数据 add
async save() { // 输入cdb 可快捷生成 const db = uniCloud.database(); // 在表 todo 中新增数据 {content: '写日记'} let res = await db.collection('todo').add({ content: '写日记' }) if (res.result.code === 0) { uni.showToast({ title: '新增成功!' }); } },
批量新增,传入对象数组即可。
.add([{ name: '张三' },{ name: '李四' },{ name: '王五' }])
删 – 删除数据 remove
通过 unicloud-db 组件快捷删除数据
<unicloud-db ref="udb" collection="todo" v-slot:default="{data, loading, error}"> <view v-if="error">{{error.message}}</view> <view v-else-if="loading">正在加载...</view> <view v-else> <ol> <li v-for="item in data"> {{ item.content}} <button @click="del(item._id)">删除</button> </li> </ol> </view> </unicloud-db>
del(id) { this.$refs.udb.remove(id) },
通过 remove 删除单条数据
使用 .doc(id)
del(id) { uni.showModal({ content: '确定删除?', success: async (res) => { if (res.confirm) { const db = uniCloud.database(); let remove_res = await db.collection('todo').doc(id).remove() if (remove_res.result.errCode === 0) { uni.showToast({ title: '删除成功!' }); } } } }) },
通过 remove 批量删除数据
使用 .where()
// 删除字段a的值大于2的文档 .where({ a: dbCmd.gt(2) }).remove() // 清理全部数据 .where({ _id: dbCmd.exists(true) }).remove()
通过 remove 清空数据
不推荐
db.collection('todo').remove()
会清空 todo 表内的所有数据!
改 – 修改数据 update
仅会修改 update 中传入的字段
async edit(item) { const db = uniCloud.database(); let id = item._id let newItem = item delete newItem['_id'] let res = await db.collection("todo").doc(id) .update(newItem) if (res.result.errCode=== 0) { uni.showToast({ title: '修改成功!' }); } }
async edit(item) { const db = uniCloud.database(); let res = await db.collection("todo").where({ _id: item._id }) .update({ content: '读书' }) if (res.result.code === 0) { uni.showToast({ title: '修改成功!' }); } },
修改数组
更新数组时,以数组下标作为key即可
.update({ arr: { 1: "uniCloud" } })
修改对象
范例 – 更新对象方式一
.update({ info: { job: "演员" } })
范例 – 更新对象方式二
.update({ 'info.job': "演员" })
批量修改
批量更新,添加 where 搜索条件即可
.where("name=='hey'").update({ age: 18, })
使用操作符实现修改
仅在云函数/云对象中可用!
范例 – push
uniCloud-aliyun/cloudfunctions/edit_todo/index.js
'use strict'; exports.main = async (event, context) => { let { _id, newList } = event const db = uniCloud.database(); const dbcmd = db.command return db.collection("todo").where({ _id }) .update({ tag: dbcmd.push(newList) }) };
pages/index/index.vue
async edit(item) { uniCloud.callFunction({ name: 'edit_todo', data: { _id: item._id, newList: ['喝水', '吃饭'] } }) .then(res => { if (res.result.updated) { uni.showToast({ title: '修改成功!' }); this.getList() } }); },
push 单个值
dbcmd.push('新值')
push 多个值
dbcmd.push(['新值1','新值2'])
在指定的位置 push 值
(参考自微信云开发文档,uniCloud中也可用)
.update({ data: { tags: dbcmd.push({ // 从tags数组下标1开始,添加新值1和新值2 each: ['新值1','新值2'], position: 1, }) } })
原子自增/减 – inc
用于阅读数+1、收藏+1等可能多用户同时操作的场景。
原理:多个用户同时修改时,无需经历读数据、处理数据、修改数据这样漫长的过程,不会有后来者覆写前者的情况。
.update({ count: { // 收藏数 +1 fav: dbCmd.inc(1) } })
.update({ count: { // 收藏数 -1 fav: dbCmd.inc(-1) } })
原子自乘/除 – mul
原理同 inc
.update({ count: { // 收藏数 *10 fav: dbCmd.mul(10) } })
.update({ count: { // 收藏数 /10 fav: dbCmd.mul(0.1) } })
覆写 – set
将传入的值整个覆盖原内容
- 不支持批量,只能在 doc 查询到单条数据后,进行覆写
.doc('doc-id').update({ count: dbCmd.set({ fav: 1, follow: 1 }) })
查 – 读取数据 get
通过 unicloud-db 组件直接渲染读取的数据
在 collection 属性配置对应的表名即可,如 “todo”
<unicloud-db collection="todo" v-slot:default="{data, loading, error}"> <view v-if="error">{{error.message}}</view> <view v-else-if="loading">正在加载...</view> <view v-else> <ol> <li v-for="item in data"> {{ item.content}} </li> </ol> </view> </unicloud-db>
通过 get 获取数据列表
async getList() { const db = uniCloud.database(); let res = await db.collection('todo').get() if (res.success) { console.log(res.result.data) } },
通过 count 获取总数
async getTotal() { const db = uniCloud.database(); let res = await db.collection('todo').count() if (res.success) { console.log(res.result.total) } },
通过 doc 获取单条数据
常用于获取目标数据的详情
async getDetail() { let id = '65950461bd0220fad3ad39bd' const db = uniCloud.database(); let res = await db.collection('todo').doc(id).get() if (res.success) { console.log(res.result.data[0]) } },
通过 limit 限定数据条数
常和skip一起使用,实现分页查询
async getList() { const db = uniCloud.database(); let res = await db.collection('todo').limit(2).get() if (res.success) { console.log(res.result.data) } },
通过 skip 限定查询起点
常和 limit 一起使用,实现分页查询
async getList() { const db = uniCloud.database(); let res = await db.collection('todo').skip(1).get() if (res.success) { console.log(res.result.data) } },
分页查询
移动端的每页条数,建议设定为比内容占满首屏稍多一点即可。
async getList_page() { const db = uniCloud.database(); // 当前页码 let currentPage = 1 // 每页条数 let pageSize = 2 let res = await db.collection('todo').skip(pageSize * (currentPage - 1)).limit(pageSize).get() if (res.success) { console.log(res.result.data) } },
通过 orderBy 排序
async getList() { const db = uniCloud.database(); // 按创建时间,倒序排列 let res = await db.collection('todo').orderBy('createTime', 'desc').get() if (res.success) { console.log(res.result.data) } },
- 默认是正序排列 asc
通过 field 限定查询的字段
async getList() { const db = uniCloud.database(); // 仅返回 content 字段 let res = await db.collection('todo').field({ content: true }).get() if (res.success) { console.log(res.result.data) } },
通过 where 添加查询条件
单条件
async getList() { const db = uniCloud.database(); let res = await db.collection('todo').where({ content: '吃饭' }).get() if (res.success) { console.log(res.result.data) } },
多条件
async getList() { const db = uniCloud.database(); let res = await db.collection('todo').where({ title: '标题1', content: '内容1', }).get() if (res.success) { console.log(res.result.data) } },
跨字段-多条件
在 where(查询条件) 的查询条件中,综合使用 dbCmd.and({条件1},{条件2}…) 和 dbCmd.or({条件1},{条件2}…) 实现
let res = await db.where(dbCmd.and({ eventTime: dbCmd.gte(minTime.getTime()).and(dbCmd.lt(maxTime.getTime())), wallet: this.current_tab > 0 ? String(this.current_tab) : (new RegExp('', 'ig')) }, dbCmd.or({ content: new RegExp(this.keyword, 'ig'), }, { remark: new RegExp(this.keyword, 'ig'), }))).orderBy('eventTime', this.time_orderType).get()
command 指令实现复杂查询
async getList() { const db = uniCloud.database(); const dbCmd = db.command // 查询 score 值为 9 的数据 let res = await db.collection('todo').where({ score: dbCmd.eq(9) }).get() if (res.success) { this.list = res.result.data } },
更多指令见下表
范例 – in
async getList() { const db = uniCloud.database(); const dbCmd = db.command // 查询 score 值为 9 或 10 或 11 的数据 let res = await db.collection('todo').where({ score: dbCmd.in([9, 10, 11]) }).get() if (res.success) { this.list = res.result.data } },
范例 – or 的用法一(and同理)
async getList() { const db = uniCloud.database(); const dbCmd = db.command // 查询 score 值为 9 或 20 的数据 let res = await db.collection('todo').where({ score: dbCmd.eq(9).or(dbCmd.eq(20)) }).get() if (res.success) { this.list = res.result.data } },
范例 – or 的用法二(and同理)
async getList() { const db = uniCloud.database(); const dbCmd = db.command // 查询 score 值为 9 或 20 的数据 let res = await db.collection('todo').where({ score: dbCmd.or(dbCmd.eq(9), dbCmd.eq(20)) }).get() if (res.success) { this.list = res.result.data } },
正则表达式实现模糊查询
async getList() { let keyword = '标' const db = uniCloud.database(); let res = await db.collection('todo').where({ // 查询 title 字段的值中含 keyword的值 的数据 title: new RegExp(keyword, 'ig') }).get() if (res.success) { this.list = res.result.data } },