目录
云对象
创建云对象
客户端调用
二、Schema(表结构)
什么是Schema?
如何编写DB Schema
Schema的一级节点
客户端直连数据库
字段属性
字段类型bsonType
默认值defaultValue/forceDefaultValue
云对象,其实是对云函数的封装。和创建云函数一样,在uniCloud/cloudfunctions
目录右键新建云函数,选择云对象类型,输入云对象名称创建云对象,此处以云对象todo为例,创建的云对象包含一个index.obj.js
。
默认云对象模板是不包含任何方法的,我们为此对象添加一个add方法作为示例。
// cloudfunctions/todo/index.obj.js
module.exports = {
add: function(title = '', content = '') {
title = title.trim()
content = content.trim()
if(!title || !content) {
return {
errCode: 'INVALID_TODO',
errMsg: 'TODO标题或内容不可为空'
}
}
// ...其他逻辑,如操作todo数据表添加数据
return {
errCode: 0,
errMsg: '创建成功'
}
}
}
至此云对象todo已经有了一个可以访问的方法了。接下来看如何使用客户端调用此云对象内的方法
户端通过uniCloud.importObject
方法获取云对象的实例,并可以通过此实例调用云对象内的方法。用法如下
const todo = uniCloud.importObject('todo')
try {
const res = await todo.add('title demo', 'content demo') //导入云对象后就可以直接调用该对象的方法了,注意使用异步await
console.log(res)
} catch (e) {
console.log(e.errCode)
console.log(e.errMsg)
}
Schema也称架构是限制数据库的一些权限。如果直接在页面调用数据库是需要校验的。直接就能操作数据库是一件很危险的事。
DB Schema
是基于 JSON 格式定义的数据结构的规范。
每张表/集合,都有一个表名.schema.json的文件,来描述表的信息、字段的信息。
一个表的简单schema.json示例如下
{
"bsonType": "object", // 固定节点
"description": "该表的描述",
"required": [], // 必填字段列表
"properties": { // 该表的字段清单
"_id": { // 字段名称,每个表都会带有_id字段
"description": "ID,系统自动生成"
// 这里还有很多字段属性可以设置
},
"field2": { // 字段2,每个表都会带有_id字段
"description": ""
// 这里还有很多字段属性可以设置
}
}
}
在HBuilderX中编写schema,有良好的语法提示和语法校验,还可以本地调试,是更为推荐的schema编写方案。
创建schema
uniCloud
项目右键,选择创建database目录
(如已有目录则忽略)新建数据集合schema
HBuilderX内创建的schema新建和保存时不会自动上传
上传schema
下载schema
HBuilderX中运行前端项目,在控制台选择连接本地云函数,或者本地云函数/云对象直接运行,此时本地编写的schema可直接生效,无需上传。方便编写调试。
web控制台上编辑DB Schema
保存后是实时在现网生效的,请注意对现网商用项目的影响。
{
"bsonType": "object", // 固定节点
"description": "表的描述",
"required": [], // 必填字段
"permission": {
"read": false, // 前端非admin的读取记录权限控制。默认值是false,即可以不写。可以简单的true/false,也可以写表达式
"create": false, // 前端非admin的新增记录权限控制。默认值是false,即可以不写。可以简单的true/false,也可以写表达式
"update": false, // 前端非admin的更新记录权限控制。默认值是false,即可以不写。可以简单的true/false,也可以写表达式
"delete": false, // 前端非admin的删除记录权限控制。默认值是false,即可以不写。可以简单的true/false,也可以写表达式
"count": false // 前端非admin的求数权限控制。默认值是true,即可以不写。可以简单的true/false,也可以写表达式
},
"properties": { // 表的字段清单
"_id": { // 字段名称,每个表都会带有_id字段
"description": "ID,系统自动生成"
// 这里还有很多字段属性可以设置
}
},
"fieldRules":[
// 字段之间的约束关系。比如字段开始时间小于字段结束时间。也可以只校验一个字段。支持表达式
]
}
注意
从云端下载对应的Schema
点击database,再选择下载所有DB Schema 这个选项。
.开权限
只是下载下来Schema是没办法使用的,因为没有开权限。修改对应的Schema表里的permission里的对应权限的操作,最简单的就是把false修改为true。
新建表
不需要在云端数据库直接建表,可以在HBuilder X里新建SChema表,之后再上传到云端就可以同步了。
客户端直连
基本 | bsonType | any | 字段类型,如json object、字符串、数字、bool值、日期、时间戳,具体见下表bsonType可用类型 |
基本 | arrayType | String | 数组项类型,bsonType="array" 时有效,HBuilderX 3.1.0+ 支持,具体见下表arrayType可用类型 |
基本 | title | string | 标题,开发者维护时自用。在schema2code生成前端表单代码时,默认用于表单项前面的label |
基本 | description | string | 描述,开发者维护时自用。在生成前端表单代码时,如果字段未设置componentForEdit,且字段被渲染为input,那么input的placehold将默认为本描述 |
基本 | defaultValue | string|Object | 默认值 |
则resume.schema.json
按如下编写。
{
"bsonType": "object",
"required": ["name", "birth_year", "tel", "email"],
"permission": {
"read": true,
"create": true,
"update": true,
"delete": true
},
"properties": {
"_id": {
"description": "ID,系统自动生成"
},
"name": {
"bsonType": "string",
"title": "姓名",
"trim": "both",
"minLength": 2,
"maxLength": 17
},
"birth_year": {
"bsonType": "int",
"title": "出生年份",
"minimum": 1950,
"maximum": 2020
},
"tel": {
"bsonType": "string",
"title": "手机号码",
"pattern": "^\\+?[0-9-]{3,20}$",
"trim": "both"
},
"email": {
"bsonType": "string",
"title": "email",
"format": "email",
"trim": "both"
},
"address": {
"bsonType": "object",
"title": "地址",
"required": ["city"],
"properties": {
"city": {
"bsonType": "string",
"title": "城市"
},
"street": {
"bsonType": "string",
"title": "街道",
"trim": "both"
}
}
},
"intro":{
"bsonType": "string",
"title": "简介",
"trim": "both"
}
}
}
意:
schema保存后,可以通过代码测试。注意在uniCloud web控制台修改数据不受schema限制,只有通过JQL操作数据时schema才生效。
我们在前端测试工程里新加一个按钮“添加数据”
可以看到,不符合规则的数据无法通过JQL操作入库。可以依次把各个字段的测试值修正为合法格式测试,直到可以正常入库。
成功后,res会返回新增记录的id,也可以在web控制台看到新增的数据。
失败的提示语也可以通过errorMessage自定义。
成功后,再次点击“添加数据”按钮,会发现重复数据插入。避免这种情况需要设置索引,比如将tel字段设为唯一索引。详见
官方推出了openDB
开源数据库规范,包括用户表、文章表、商品表等很多模板表,这些模板表均已经内置DB Schema
,可学习参考。详见
schema 国际化方案 详见
复杂格式说明:
var timestamp = new Date().getTime();
。它的好处是屏蔽了时区差异。阿里云和腾讯云的云端时区是0,但在HBuilderX本地运行云函数时,如果是中国的电脑,时区则会变成8,导致显示错乱。所以推荐使用时间戳。但时间戳是一串记录毫秒的数字,不合适直接渲染到前端界面上。推荐的做法是在前端渲染时使用defaultValue和forceDefaultValue都是默认值,即新增一行数据记录时,如果字段内容未提供,则按默认值填充该字段内容。但2者也有区别,如下:
在实际开发中,forceDefaultValue常用于设置为当前服务器时间、当前登录用户id、客户端ip等。 这些数据都不能通过前端上传,不安全。过去只能在云端写云函数操作。在schema配置后则可以不用写云函数。使用JQL新增数据记录时会自动补齐这些数据。
defaultValue/forceDefaultValue
内可以使用固定值,还可以使用预置变量$env
,形式如下:
"forceDefaultValue": {
"$env": "now"
}
预置变量$env
可取值如下:
变量 | 说明 |
---|---|
now | 当前服务器时间戳 |
clientIP | 当前客户端IP |
uid | 当前用户Id,基于uni-id 。如果当前用户未登录或登录状态无效会报错 |
示例:
// 指定默认值为true
"defaultValue": true
// 指定强制默认值为当前服务器时间戳
"forceDefaultValue": {
"$env": "now"
}
// 指定强制默认值为当前客户端IP
"forceDefaultValue": {
"$env": "clientIP"
}
// 指定强制默认值为当前客户id
"forceDefaultValue": {
"$env": "uid"
}
以resume
表为例,新增一个字段create_time
,表示记录的创建时间。
该字段的defaultValue
指定为服务器时间。新增记录时,若前端不传该字段,则默认为当前服务器时间。若前端传一个指定的值,则以传的值为准。
{
"bsonType": "object",
"required": [],
"properties": {
"create_time": {
"bsonType": "timestamp",
"title": "创建时间",
"defaultValue": {
"$env": "now"
}
}
}
}