Koa.js 数据库
我们正在接收请求,但不会将它们存储在任何地方。我们需要一个数据库来存储数据。我们将使用名为
MongoDB 的著名 NoSQL 数据库。要安装和阅读 Mongo,请转到此链接。
为了在 Koa 中使用 Mongo,我们需要一个用于节点的客户端 API。我们有多种选择,但是对于本教程,我们将坚持使用 mongoose。 Mongoose 用于 Node for MongoDB 中的
文档建模。文档建模意味着,我们将创建一个
模型(很像面向文档编程中的
类),然后我们将使用这个模型(就像我们在 OOP 中创建
一个类的文档)。我们所有的处理都会在这些"文档"上完成,最后,我们会将这些文档写入我们的数据库中。
设置Mongoose
既然我们已经安装了 Mongo,让我们安装 mongoose,就像我们安装其他节点包一样。
$ npm install--save mongoose
在开始使用 mongoose 之前,我们必须使用 Mongo shell 创建一个数据库。要创建新数据库,请打开终端并输入"mongo"。一个 Mongo shell 将启动,输入以下内容。
将为您创建一个新数据库。每当您打开 Mongo shell 时,它都会默认为"test"db,您必须使用与上述相同的命令更改为您的数据库。
要使用 mongoose,我们需要在 app.js 文件中使用它,然后连接到在 mongodb://localhost 上运行的 mongod 服务
var koa = require('koa');
var _ = require('koa-router')();
var app = koa();
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_db');
app.use(_.routes());
app.listen(3000);
现在我们的应用程序连接到我们的数据库,让我们创建一个新模型。这个模型将作为我们数据库中的一个集合。要创建新模型,请在定义任何路由之前使用以下代码。
var koa = require('koa');
var _ = require('koa-router')();
var app = koa();
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_db');
var personSchema = mongoose.Schema({
name: String,
age: Number,
nationality: String
});
var Person = mongoose.model("Person", personSchema);
app.use(_.routes());
app.listen(3000);
上面的代码定义了一个人的模式,用于创建一个猫鼬模型
人。
保存文档
现在我们将创建一个新的 html 表单,它将获取一个人的详细信息并将其保存到我们的数据库中。要创建表单,请在 views 目录中创建一个名为 person.pug 的新视图文件,内容如下。
html
head
title Person
body
form(action = "/person", method = "POST")
div
label(for = "name") Name:
input(name = "name")
br
div
label(for = "age") Age:
input(name = "age")
br
div
label(for = "nationality") Nationality:
input(name = "nationality")
br
button(type = "submit") Create new person
还要在 index.js 中添加一个新的 get 路由来呈现此文档。
var koa = require('koa');
var _ = require('koa-router')();
var app = koa();
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_db');
var personSchema = mongoose.Schema({
name: String,
age: Number,
nationality: String
});
var Person = mongoose.model("Person", personSchema);
_.get('/person', getPerson);
function *getPerson(next){
this.render('person');
yield next;
}
app.use(_.routes());
app.listen(3000);
转到 localhost:3000/person 检查我们的表单是否正确显示。请注意,这只是 UI,它尚未工作。这就是我们的表单的外观。
我们现在将在 '/person' 定义一个 post 路由处理程序来处理这个请求。
var koa = require('koa');
var _ = require('koa-router')();
var app = koa();
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_db');
var personSchema = mongoose.Schema({
name: String,
age: Number,
nationality: String
});
var Person = mongoose.model("Person", personSchema);
_.post('/person', createPerson);
function *createPerson(next){
var self = this;
var personInfo = self.request.body; //Get the parsed information
if(!personInfo.name || !personInfo.age || !personInfo.nationality){
self.render(
'show_message', {message: "Sorry, you provided wrong info", type: "error"});
} else {
var newPerson = new Person({
name: personInfo.name,
age: personInfo.age,
nationality: personInfo.nationality
});
yield newPerson.save(function(err, res) {
if(err)
self.render('show_message',
{message: "Database error", type: "error"});
else
self.render('show_message',
{message: "New person added", type: "success", person: personInfo});
});
}
}
app.use(_.routes());
app.listen(3000);
在上面的代码中,如果我们收到任何空字段或没有收到任何字段,我们将发送错误响应。但是,如果我们收到一个格式良好的文档,那么我们会从 Person 模型创建一个 newPerson 文档,并使用
newPerson.save() 函数将其保存到我们的数据库中。这是在 mongoose 中定义的,并接受回调作为参数。这个回调有两个参数,
error 和
response。这将呈现 show_message 视图,因此我们也需要创建它。
要显示来自该路由的响应,我们还需要创建一个
show_message 视图。使用以下代码创建一个新视图。
html
head
title Person
body
if(type = "error")
h3(style = "color:red") #{message}
else
h3 new person, name:
#{person.name}, age:
#{person.age} and nationality:
#{person.nationality} added!
以下是我们在成功提交表单后收到的回复 (show_message.pug)。
我们现在有一个用于创建人物的界面!
检索文档
Mongoose 提供了很多检索文档的功能,我们将重点介绍其中三个。所有这些函数也都将回调作为最后一个参数,就像保存函数一样,它们的参数是错误和响应。
这三个函数是-
Model.find(conditions, callback)
此函数查找与条件对象中的字段匹配的所有文档。 Mongo 中使用的相同运算符也适用于 mongoose。例如,这将从个人集合中获取所有文档。
Person.find(function(err, response){
console.log(response);
});
这将获取字段名称为"Ayush"且年龄为 20 的所有文档。
Person.find({name: "Ayush", age: 20},
function(err, response){
console.log(response);
});
我们也可以提供我们需要的投影,即我们需要的字段。例如,如果我们只想要
国籍是
"印度人"的人的
姓名,我们使用-
Person.find({nationality: "Indian"},
"name", function(err, response) {
console.log(response);
});
Model.findOne(conditions, callback)
这个函数总是获取一个最相关的文档。它具有与 Model.find() 完全相同的参数。
Model.findById(id, callback)
这个函数接受
_id(由 mongo 定义)作为第一个参数、一个可选的投影字符串和一个回调来处理响应。例如,
Person.findById("507f1f77bcf86cd799439011",
function(err, response){
console.log(response);
});
让我们创建一个路径来查看所有人员记录。
var koa = require('koa');
var _ = require('koa-router')();
var app = koa();
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_db');
var personSchema = mongoose.Schema({
name: String,
age: Number,
nationality: String
});
var Person = mongoose.model("Person", personSchema);
_.get('/people', getPeople);
function *getPeople(next){
var self = this;
yield Person.find(function(err, response){
self.body = response;
});
}
app.use(_.routes());
app.listen(3000);
更新文档
Mongoose 提供了三个更新文档的函数。
Model.update(condition, updates, callback)
此函数接受一个条件并更新对象作为输入,并将更改应用于集合中与条件匹配的所有文档。例如,以下代码会将所有 Person 文档更新为具有"美国人"国籍。
Person.update({age: 25},
{nationality: "American"},
function(err, response){
console.log(response);
});
Model.findOneAndUpdate(condition, updates, callback)
它完全按照所说的去做。根据查询查找一个文档并根据第二个参数更新该文档。它还需要一个回调作为最后一个参数。例如,
Person.findOneAndUpdate({name: "Ayush"},
{age: 40},
function(err, response){
console.log(response);
});
Model.findByIdAndUpdate(id, updates, callback)
此函数更新由其 id 标识的单个文档。例如,
Person.findByIdAndUpdate("507f1f77bcf86cd799439011",
{name: "James"},
function(err, response){
console.log(response);
});
让我们创建一条路线来更新人员。这将是一个 PUT 路由,以 id 作为参数并在有效负载中提供详细信息。
var koa = require('koa');
var _ = require('koa-router')();
var app = koa();
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_db');
var personSchema = mongoose.Schema({
name: String,
age: Number,
nationality: String
});
var Person = mongoose.model("Person", personSchema);
_.put('/people/:id', updatePerson);
function *updatePerson() {
var self = this;
yield Person.findByIdAndUpdate(self.params.id,
{$set: {self.request.body}}, function(err, response){
if(err) {
self.body = {
message: "Error in updating person with id " + self.params.id};
} else {
self.body = response;
}
});
}
app.use(_.routes());
app.listen(3000);
要测试此路线,请在您的终端中输入以下内容(将 id 替换为您创建的人员的 id)。
curl-X PUT--data "name = James&age = 20&nationality = American" https://localhost:3000/people/507f1f77bcf86cd799439011
这将使用上述详细信息更新与路由中提供的 id 关联的文档。
删除文档
我们已经介绍了
Create、
Read 和
Update,现在我们将看到如何使用 mongoose 删除文档。这里有三个函数,和update一模一样。
Model.remove(condition, [callback])
此函数将条件对象作为输入并删除所有符合条件的文档。例如,如果我们需要删除所有 20 岁的人,
Model.findOneAndRemove(condition, [callback])
此函数根据条件对象删除
单个、最相关的文档。例如,
Person.findOneAndRemove({name: "Ayush"});
Model.findByIdAndRemove(id, [callback])
此函数删除由其 id 标识的单个文档。例如,
Person.findByIdAndRemove("507f1f77bcf86cd799439011");
现在让我们创建一个从数据库中删除人员的路由。
var koa = require('koa');
var _ = require('koa-router')();
var app = koa();
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_db');
var personSchema = mongoose.Schema({
name: String,
age: Number,
nationality: String
});
var Person = mongoose.model("Person", personSchema);
_.delete('/people/:id', deletePerson);
function *deletePerson(next){
var self = this;
yield Person.findByIdAndRemove(self.params.id, function(err, response){
if(err) {
self.body = {message: "Error in deleting record id " + self.params.id};
} else {
self.body = {message: "Person with id " + self.params.id + " removed."};
}
});
}
app.use(_.routes());
app.listen(3000);
要对此进行测试,请使用以下 curl 命令-
curl-X DELETE https://localhost:3000/people/507f1f77bcf86cd799439011
这将删除具有给定 ID 的人,并生成以下消息。-
{message: "Person with id 507f1f77bcf86cd799439011 removed."}
这总结了我们如何使用 MongoDB、mongoose 和 Koa 创建简单的 CRUD 应用程序。要进一步探索猫鼬,请阅读 API 文档。