数据库基础
数据库是干什么的
数据库顾名思义,就是数据和库,即存放数据的仓库。这里面的数据指数字、文本、图片、视频等它们被放在一起,需要使用的时候可以拿出来。在现实生活中,有很多数据库的例子:
身份证数据库
我们每个人都有一张身份证,身份证上的信息如姓名、生日、性别、籍贯等都是数据库(表)里面存储的内容。在国家机关中,有一个将所有人的信息集中放在一起的仓库,它存储了十四亿条数据,每条数据又包含着姓名、生日、性别、籍贯等数据内容。当你在办理某些业务时,输入身份证号,即可看到你的其他信息,这就是一个常用的数据库查询的例子。此时,每个 身份证号 是唯一存在的,就是整个数据库的索引。
QQ 数据库
我们常常使用 QQ ,这是一个即时通信工具,实际上,在腾讯公司的技术部门,就有一个大型的数据库,这个数据库包含很多用户的信息,每个用户的信息就是数据库的一条数据,这个数据中有 QQ号、昵称、生日、个性签名等内容。此时,每个 QQ号 是唯一存在的,就是整个数据库的索引。
数据库的结构
传统的数据库的结构如下:
- 数据库(database)
- 数据表(table)
- 数据行(row)
- 字段(field),相当于 Excel 中的列,每个字段都有自己的数据类型。
在上面身份证例子中,整个户籍管理仓库就是一个数据库,这个数据库里面,可能有多张数据表,比如学籍表、身份证表、驾驶执照表等。以身份证表为例,这个表中存放着14亿条数据行,每个数据行标识着一个人。每一行都有一个唯一标识的字段,与其他字段区分开,这个字段就是身份证号,还有其他字段,比如姓名、民族、性别字段等。每个字段有不同的数据类型,身份证号数据类型为长数字,姓名的数据类型为字符串,出生日期的数据类型为日期。
Excel 类比数据库
邮箱小程序设计
页面设计
这个小程序设计的主题是送信和收信,所以仅安排了三个简单的界面,即
- 注册界面
- 写信界面
- 收信界面
数据库设计
在这个简单的小程序中,我们需要存储用户信息和信件信息。因此我们的数据库中需要两个数据表,用户信息数据表中需要存储用户的头像、昵称、ID,信件信息需要存储信件的收件人、内容和发件人ID。两个数据库可以通过**昵称(收件人姓名)**联系起来。
编程实现
页面实现
TabBar
"tabBar": {
"list": [{
"pagePath": "pages/index/index",
"text": "注册"
}, {
"pagePath": "pages/dend/index",
"text": "发信"
}, {
"pagePath": "pages/receive/index",
"text": "收信"
}]
},
注册页面
包含登录按钮,姓名输入框以及注册按钮。
<!--index.wxml-->
<view class="container">
<!-- 头像 -->
<view ><image class="avatar" src="{{avatar}}"></image></view>
<button bindtap="Login">点击使用微信登录</button>
<input bindinput="bindKeyInput" type="text" class="inputBox" placeholder="填写你的姓名"/>
<button style="margin-top: 20rpx;" bindtap="Yes">注册</button>
</view>
写信页面
<!--pages/dend/index.wxml-->
<view class="container">
<strong>发信</strong>
<input bindinput="inputRecer" type="text" class="inputBox" placeholder="填写收件人"/>
<input bindinput="inputContent" type="text" class="inputBox" placeholder="填写内容"/>
<button bindtap="Sendit">发送</button>
</view>
收信页面
这里需要使用列表渲染。
<view class="container">
<strong>收件箱</strong>
<!-- 列表渲染 -->
<view class="Mailcard" wx:for='{{MailList}}' wx:key='index'>
<view style="display:block">内容:{{item.content}} </view>
<view style="display:block">收件人:{{item.rece}}</view>
</view>
</view>
数据库创建
创建集合
打开云开发控制台,在数据库中创建两个集合。分别取名TestBase
和Mails
,分别存储用户信息和信件信息。
:::caution 图中其他数据库集合和本例子无关,请不用理会。 :::
设置读写权限
在集合页面,设置数据权限为所有用户可读,仅创建者可读写。
如此,数据库创建就完成了。
注册功能
需求分析
在页面注册时,我们需要要求用户填写自己的姓名,再通过微信登录获取用户的openid作为唯一的标识。然后将拿到的信息与已存在的数据库比对,如果这个用户注册过,就提示注册过了,如果没有,就向数据库TestBase
添加一条新的用户数据。
用户登录
使用微信提供的 API 获取用户登录,并得到其头像。
Login(e) {
// 微信登录
var that = this
//调用登录接口
wx.login({
success: function () {
wx.getUserInfo({
success: function (res) {
}
})
}
})
wx.getUserProfile({
desc:'获取用户信息',
success: (res) => {
// 获取userInfo的状态数据
console.log(res)
this.setData({
// 获取头像
avatar: res.userInfo.avatarUrl,
isLogin:1
})
},
})
},
获取openid
由于微信直接提供的 openid 是秘密的,因此我们必须要解密之后才能使用 openid ,这里就要借助云函数进行实现了。
在 cloudfuctions 文件夹创建云函数 getOpenId
,图中其他的函数不需要理会,与本例子无关。
在 getOpenId
的 index 文件中创建 openid 解析函数,如下:
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init({ // 初始化云开发环境
env: cloud.DYNAMIC_CURRENT_ENV // 当前环境的常量
})
const db = cloud.database()
// 云函数入口函数
exports.main = async (event, context) => {
const wxContext = cloud.getWXContext()
// 返回当前用户的身份信息,用于数据库记录和查询
return {
event,
openid: wxContext.OPENID,
fromopenid: wxContext.FROM_OPENID,
appid: wxContext.APPID,
unionid: wxContext.UNIONID,
}
}
云函数调用
回到页面的 index.js 文件,在文件中调用这个云函数。
async getOpenId() {
const {
result: {
// 创建调用结果
openid,
fromopenid
}
} = await (await this.cloud()).callFunction({
// 声明要调用的云函数
name: 'getOpenId'
}).catch(e => {
let flag = e.toString()
flag = flag.indexOf('FunctionName') == -1 ? flag : '请在cloudfunctions文件夹中getOpenId上右键,创建部署云端安装依赖,然后再次体验'
wx.hideLoading()
wx.showModal({
content: flag, // "网络服务异常,请确认网络重新尝试!"
showCancel: false
})
throw new Error(flag)
})
// 返回解密结果
if (openid !== "") return openid
return fromopenid
},
然后我们尝试登录,查看是否正常获取了 openid :
如图,已经获取到了数据容器中。
填写姓名
使用 input 以及其自带的响应事件,创建输入框。
<input bindinput="bindKeyInput" type="text" class="inputBox" placeholder="填写你的姓名"/>
data: {
//...
// 输入内容
inputValue: "占位姓名",
//...
},
bindKeyInput: function (e) {
this.setData({
inputValue: e.detail.value
})
},
写入数据库
在上面的步骤中,我们已经得到了用户的 openid 以及用户填写的姓名,现在,我们要把注册信息写到数据库中。
首先,为注册按钮绑定事件。
先调用获取 openid 函数,得到 openid (上面只创建了功能,并没有调用) 。
this.getOpenId().then(async openid => {
console.log("OpenID: " + openid)
this.setData({
UserID: openid
})
})
接着,初始化云环境:
const db = wx.cloud.database({
// 在下面填写你的云开发 ID
env: ''
})
然后在数据表中判断这个 ID 是否已经注册过,这就需要用到 db.where.get
API。让我们看一下官方是如何解释这个方法的:
Collection.where(condition: Object): Collection
指定查询条件,返回带新查询条件的新的集合引用
参数
condition: Object
查询条件
返回值
Collection
在这里,我们使用 where 去查询这个 openid 是否已经存在。
db.collection('TestBase').where({
// 筛选条件
_openid: this.data.UserID
}).get().then(ress => {
// 如果存在 如何处理
})
可以通过 data.length
来判断数据行是否为空,如果已经存在,那么我们就应该要提示用户已注册:
if (ress.data.length != 0) {
wx.showModal({
title: '抱歉',
content: '用户已存在',
})
}
如果不为空,我们就要使用 db.collection('').add
方法添加数据:
db.collection('TestBase').add({
// data 字段表示需新增的 JSON 数据,在这里向数据库写入数据
data: {
// 让 id 标识为用户唯一的 openid
_id: this.data.UserID,
// 头像
Avatar:this.data.avatar,
// 姓名
Name:this.data.inputValue
},
success: function (res) {
// res 是一个对象,其中有 _id 字段标记刚创建的记录的 id
console.log(res)
wx.showModal({
title: '成功',
content: '上传成功',
})
}
})
我们执行一下,观察数据库中是否已经添加了新的数据:
显然,这里已经增加了一条新的用户数据。
数据库调用步骤
经过上面的例子,我们可以总结出数据库调用的步骤:
一、初始化云环境
cloud.init({ // 初始化云开发环境
env: cloud.DYNAMIC_CURRENT_ENV // 当前环境的常量
})
二、声明数据库
const db = wx.cloud.database({
// 在下面填写你的云开发 ID
env: ''
})
三、调用API进行处理
比如上面的查询和新增,实际上,数据库有增删改查等能力,这在微信小程序文档中有详细的说明,也可以参考这篇文章 (opens in a new tab)
写信功能
需求分析
在写信功能中,我们需要指定收件人,以及写入信的内容,这里定义了两个输入框,用于获取这两个内容。获取得到这些信息之后,我们首先要到用户数据表中判断这个收件人是否为我们的用户,如果不是,那么就提示,如果是,就把这封信写入到信件数据表中。
文本框信息获取
data: {
Content:'',
Rece:'',
RecrID:''
},
inputContent: function (e) {
this.setData({
Content: e.detail.value
})
},
inputRecer: function (e) {
this.setData({
Rece: e.detail.value
})
},
判断是否填写了内容
在发送按钮点击事件中进行判断。
if(this.data.Content===''|this.data.Rece===''){
wx.showModal({
title: '注意',
content: '请先输入完整内容',
})
}
判断是否存在这个收信人
同样是调用 where 方法来判断数据表中是否有这个收件人数据:
db.collection('TestBase').where({
// 筛选条件
Name:this.data.Rece
}).get().then(ress => {
})
这里这个函数返回了一个数据 ress ,这个数据中包含了数据库中这个 Name
用户对应的所有数据,我们可以使用 ress.data[0]
得到它。我们通过 console.log
方法打印出 ress
的内容。现在我们看看控制台输出的 ress 究竟是什么:
显然,它返回了一个 Array 数组,这个数组只有一个元素,即 data[0]
,这个元素中返回了四个参数,我们需要的是这个 _openid
参数,它表示了收件人的唯一标识。因此可以通过ress.data[0]
得到它,并把它放到临时的容器中。
db.collection('TestBase').where({
// 筛选条件
Name:this.data.Rece
}).get().then(ress => {
// 判断返回的data长度是否为0,如果为0的话就证明数据库中没有存在该数据,然后进行添加操作
// 得到了对应姓名的 openid
// highlight-start
console.log(ress);
this.setData({
RecrID:ress.data[0]._openid
})
// highlight-end
if (ress.data.length === 0) {
wx.showModal({
title: '抱歉',
content: '用户不存在',
})
return;
}
else{
// 用户存在,添加信件数据,另一个数据库
}
})
写入信件数据
与写入用户数据十分类似,不再赘述:
// 用户存在,添加信件数据,另一个数据库
db.collection('Mails').add({
// data 字段表示需新增的 JSON 数据,在这里向数据库写入数据
data: {
// 收件人姓名
rece: this.data.Rece,
// 收件人id
receID:this.data.RecrID,
// 新建内容
content:this.data.Content
},
success: function (res) {
// res 是一个对象,其中有 _id 字段标记刚创建的记录的 id
console.log(res)
wx.showModal({
title: '成功',
content: '上传成功',
})
}
})
收信
需求分析
收信时,我们需要拿着自己的姓名去信件数据库逐一匹配,如果是发给自己的信,就拿出来,其他的不管。然后通过微信能力列表渲染到界面。
数据库比对
同样是使用 where
方法进行比对,将通过比对 openid
就可以得到只属于自己的内容:
onShow: function () {
var that=this;
const db = wx.cloud.database({
// 填写你的云开发 ID
env: 'nannan-1g1q4u2i02398ecf'
})
// 在数据库里面添加新表 TestBase
db.collection('Mails').where({
// 筛选条件,这样查询之后只会获取发给自己的信息,空着就行,不用填参数
_openid:''
}).get().then(ress => {
console.log(ress)
that.setData({
MailList:ress.data
})
})
},
为什么在 onShow 函数中进行?因为我们希望,每次打开这个页面就去更新我们获得的数据信息。进行这个步骤之后,数据容器 MailList
就得到了全部属于我的信件。
列表渲染
我们看看 MailList
中有什么:
这与云开发数据库中的信息能够对上:
除了一条为张三的数据外,所有 aaa 的数据都获取下来了。
然后列表渲染:
<view class="Mailcard" wx:for='{{MailList}}' wx:key='index'>
<view style="display:block">内容:{{item.content}} </view>
<view style="display:block">收件人:{{item.rece}}</view>
</view>
实现结果: