>  기사  >  웹 프론트엔드  >  Nodejs는 Mongoose를 사용하여 모델과 API를 만듭니다.

Nodejs는 Mongoose를 사용하여 모델과 API를 만듭니다.

php中世界最好的语言
php中世界最好的语言원래의
2018-03-16 14:22:163772검색

이번에는 Nodejs에서 Mongoose를 사용하여 모델과 API를 만드는 방법을 알려드리겠습니다. Nodejs에서 Mongoose를 사용하여 모델과 API를 만들 때 주의사항은 무엇인가요?

MongoDB는 일반적으로 사용되는 관계형 데이터베이스와는 다른 분산 문서 저장 데이터베이스입니다. BSON 형식(json 바이너리)을 저장하며, 고성능, 배포 및 사용이 용이하다는 특징이 있습니다. (자세한 내용은 백과사전을 참조하세요.) 가장 중요한 점은 JavaScript 읽기 및 쓰기를 지원한다는 것입니다. MEAN 스택 개발의 가장 큰 특징은 데이터베이스를 포함한 프런트엔드와 백엔드가 모두 JavaScript로 작성된다는 것입니다. Mongoose는 EntityFramwork(ORM-Object Relational Mapping)과 비교될 수 ​​있으며, 주요 기능은 개발자가 데이터베이스를 보다 편리하게 운영할 수 있도록 하는 것입니다. 시작하기 전에 먼저 mongodb를 설치하는 것을 잊지 마세요.

1. MongoDB 준비

1. mongo 설치 후 cmd를 이용해 설치 디렉터리 아래의 bin 디렉터리로 이동합니다. Mongo를 실행하세요. 버전 번호가 나타나면 시작이 성공한 것입니다.

"컴퓨터가 적극적으로 거부합니다"가 나타나면 지정된 데이터의 경로인 dbpath를 설정해야 합니다.

mongod --dbpath=c:\mongodb\db

성공한 후 http://localhost:28017/을 방문하면 모든 것이 준비되었음을 나타내는

페이지를 볼 수 있습니다.

2. 컴퓨터를 시작할 때마다 dbpath를 설정하지 않으려면 mongo를 서비스 시작으로 설정해야 합니다. 두 단계로 먼저 cmd를 관리자로 열고 mongo bin 디렉터리로 전환합니다.

D:\mongodb\bin>mongod --dbpath=D:\mongodb --logpath=D:\mongodb\log.txt --install

위 경로를 자신의 경로로 바꾼 다음 실행 상자에 services.msc。设置服务的时候要确保mongo在运行状态,不然设置不会成功。

을 입력하여 파일을 열고 Mongo DB를 찾습니다. :

마우스 오른쪽 버튼을 클릭하고 시작을 선택하면 mongo를 시작할 때마다 자동으로 실행됩니다.

3. 더 편리하게 데스크탑에 star.bat 파일을 만들 수 있습니다:

@echo off
start "" "D:\mongodb-win32-i386-2.0.6\bin\mongo.exe"

이렇게 하면 클릭할 때마다 명령 상자로 바로 들어갑니다:

4. 일반적인 명령/기본 작업

보기 db:

show dbs

데이터베이스로 전환:

switched to db dbname
或者:
use dbname

특정 데이터베이스 아래의 컬렉션 보기

show collections

컬렉션 아래의 문서 보기:

db.collections.find()

이 섹션의 초점은 mongo 작동 방법을 소개하는 것이 아니기 때문입니다. cmd에 있으므로 더 이상 세부 정보가 없습니다. 이와 같은 자세한 내용은 일선 코더의 블로그인 Learn mongoDB in 8 days를 참조하세요. 컴퓨터에 sp1이 설치되어 있지 않으면 설치가 완료된 후 공식 웹사이트의 3.0 버전을 실행할 수 없습니다. 2.xx 무설치 버전을 사용할 수 있습니다. 다음으로는 Mongoose의 동작에 대해서 주로 다루겠습니다.

2. Mongoose

1. 설치

npm으로 직접 설치할 수 있습니다:

vs. 프로젝트에서 npm을 마우스 오른쪽 버튼으로 클릭하고 새 npm 패키지 설치를 선택합니다.

처음으로 도구를 다운로드하여 설치하고 설치가 완료된 후 Mongoose를 검색하면 다음 인터페이스가 나타나고 설치합니다.

2. 연결 설정

이 단계에서 드디어 환경이 준비되었습니다. 다음으로 app_server 폴더 아래에 models 디렉터리를 생성하고 새로운 db.js

을 생성하여 db에 추가합니다. .js 견적 몽구스:

var mongoose = require('mongoose');

mongodb不需要在连接它之前创建数据库,当第一次连接的时候,会根据链接自动创建。Mongoose在连接MongoDB的时候会创建一个有五个可重用的连接的连接池,连接数是可以配置的。这么做的原因是因为连接数据库是比较耗时的操作,特别是分布式的数据库。连接字符串的规则如下:

这里用户名、密码、端口都是可以省略的,那么在本地的时候我们的连接字符串就如下:

var dbURI = 'mongodb://localhost/RClub';
mongoose.connect(dbURI);

命名我们的数据库为RClub。Mongoose会基于连接的状态发布不同的事件:

mongoose.connection.on('connected', function () {
    console.log('Mongoose connected to ' + dbURI);
});
mongoose.connection.on('error', function (err) {
    console.log('Mongoose connection error: ' + err);
});
mongoose.connection.on('disconnected', function () {
    console.log('Mongoose disconnected');
});

如此我们可以监听连接的状态。另外应用终止需要监听nodejs的进程的SIGINT事件。而如果是nodemon重启,需要监听的是SIGUSR2事件,以便关闭连接。

// 当应用重启或终止的时候 关闭连接Shutdown = function (msg, callback) {
    mongoose.connection.close(function () {
        console.log('Mongoose disconnected through ' + msg);
        callback();
    });
};// nodemon 重启 process.once('SIGUSR2', function () {
    Shutdown('nodemon restart', function () {
        process.kill(process.pid, 'SIGUSR2');
    });
});// 应用终止process.on('SIGINT', function () {
    Shutdown('app termination', function () {
        process.exit(0);
    });
});

View Code

运行nodemon:

显示连接成功!

3.数据模型

Mongoose封装了mongodb的api使之更便于调用,但作为MongoDB的对象-文档建模器,有着更强大的功能。在mongodb中,每一个条目就是一个document,相当于关系型数据库中的行,而document的集合称为collection,相当于是关系型数据库中的table。在Mongoose中定义一个document的对象称为schema,相当于用EF定义一个Model,而定义schema中每一条数据的规则称为path(约束)。path的规则和jquery.validate.js几乎是一样的。

path支持的数据类型如下:

  • String

  • Number

  • Date

  • Boolean

  • Buffer   二进制,比如图形

  • Mixed  任何类型

  • Array  可以为数组,或者内嵌的 子文档集

  • ObjectId 唯一id

接下来演示下如何用Mongoose建一个数据模型,在models文件夹下创建一个books.js。然后引用Mongoose。如下,更具上一节book对象创建一个bookSchema 。

  {
    id: 0"深入浅出Node.js""朴灵 / 人民邮电出版社 / 2013-12-1 / CNY 69.00"5"https://img3.doubanio.com/mpic/s27269296.jpg""node", "深入浅出"'本书从不同的视角介绍了 Node 内在的特点和结构。.....9787115335500

id不用创建,mongo会为每个document生成一个唯一的id。

var mongoose = require('mongoose');var bookSchema = new mongoose.Schema({
    title: String,
    rating: {
        type: Number,
        required: true,
        min: 0,
        max: 5
    },
    info: String,
    img: String,
    tags: [String],
    brief: String,
    ISBN: String
});

这种语法是不是和jquery.validate.js很像,相信不用解释就能看明白,不满足path的条件时是不能保存或者更改的。每个path还可以设置默认值,比如时间:

 createdOn: {
        type: Date,        default: Date.now
    },

一个Schema可以包含另外的Schema或数组,在关系型数据库中这种需求用的是外键或者是关系映射表,而Mongoose这样看起来直观多了。

var userSchema = new mongoose.Schema({
userName: String,
    email: String,
...});var commentSchema = new mongoose.Schema({
    user: userSchema,
    ...
    content: String
});var topicSchema = new mongoose.Schema({
    ....
    visitedCount: { type: Number, default: 0 },
    ...
    comments: [commentSchema],
    deleted: { type: Boolean, default: false },
    top: { type: Boolean, default: false }, // 置顶帖    ...
});

这个时候的shema 还不具备数据库的操作能力,还需要注册下。 

mongoose.model('Book', bookSchema);
mongoose.model('Topic', topicSchema);

全部模型:

var mongoose = require('mongoose');var bookSchema = new mongoose.Schema({
    title: String,
    rating: {
        type: Number,
        required: true,
        min: 0,
        max: 5
    },
    info: String,
    img: String,
    tags: [String],
    brief: String,
    ISBN: String
});var userSchema = new mongoose.Schema({
    userName: String,
    email: String,
    password: String,
    createdOn: {
        type: Date,        default: Date.now
    },
    img: String,
    ip: String,
    mobile: String
});var commentSchema = new mongoose.Schema({
    user: userSchema,
    createdOn: {
        type: Date,        default: Date.now
    },
    content: String
});var topicSchema = new mongoose.Schema({
    title: String,
    type: String,
    visitedCount: { type: Number, default: 0 },
    commentCount: { type: Number, default: 0 },
    createdOn: {
        type: Date,        default: Date.now
    },
    img: String,
    author: String,
    content: String,
    comments: [commentSchema],
    deleted: { type: Boolean, default: false },
    top: { type: Boolean, default: false }, // 置顶帖
    good: { type: Boolean, default: false }, // 精华帖});
mongoose.model('Book', bookSchema);
mongoose.model('Topic', topicSchema);

View Code

4.操作数据

接下来就是改造controllers文件夹的中的home.js了,首先要引用db.js和Mongoose。

var db = require('../models/db.js');var mongoose = require('mongoose');

 1).初始化数据,查询与新建数据。

 这里把上一节创建的数据books和topics存入数据库中:

module.exports.init = function (req, res) {    mongoose.model('Book').find().exec(function (err, objs) {        if (err) {
            res.render('error', {
                message: err.message,
                error: err
            });            return;
        }        if (objs.length) {            
            for (var i = 0; i < books.length; i++) {                var taget = new Bookmodel(books[i]);//创建一个模型                taget.save(function (err) {//保存。
                    console.log(err);
                });
            }            
            for (var i = 0; i < topics.length; i++) {                var taget = new topicmodel(topics[i]);
                console.log('topic create');
                taget.save(function (err) {
                    console.log(err);
                });
            }
            res.send('初始化完成...');
        }
        res.render('books', { title: 'Books', books: objs });
    });

这段代码里面有查询和新建保存,mongoose.model("Book") 相当于EF中的db.Books。而这里的find()方法并没有立即执行,这里有点像Linq的感觉,可以链式查询:

Book.find({ size: 'small' }).where('createdDate').gt(oneYearAgo).exec(callback);//例子,和上面的book没有关系

这里Book相当于mongoose.model("Book") ,而{ size: 'small' }是一个条件。最终到exec方法时才正在执行。回调函数默认有两个参数,一个是err,一个是结果对象。这里偷了懒只判断了books的查询结果,集合为空的话就加上原来的数据。因为mongoose.model("Book")使用的比较多,所以干脆提出来:

var Bookmodel = mongoose.model('Book');var Topicmodel = mongoose.model('Topic');

find方法是查询一个集合,常用的还有findone:

var query = Person.findOne({ 'name.last': 'Ghost' });// 选择name和occupation 字段query.select('name occupation');// 执行查询query.exec(function (err, person) {  if (err) return handleError(err);
  console.log('%s %s is a %s.', person.name.first, person.name.last, person.occupation) 
})

保存数据,new一个Model,传入初始化的对象,save即可。

 var taget = new Bookmodel(books[i]);
      taget.save(function (err) {
               console.log(err);
          });

配置下路由:

router.get('/init', homeController.init);

运行:

因此数据添加成功!

三、app_api

为方便后面复用,接下来将数据调用换成api的方式。在工程里面新建一个app_api文件夹,并将原来app_server目录下的models文件移过去。并增加controllers和routes文件夹。也就是说,把数据调用分离出来。

1)在app.js中增加以下代码:

var routesApi = require('./app_api/routes/index');...
app.use('/', routes);app.use('/api', routesApi);

也就是说,所有以/api/xx开始的请求将由routes/index.js来路由。

2)在routes文件下新增index.js 文件,用来配置api的路由:

var express = require('express');var router = express.Router();var bookCtrl = require('../controllers/book');var topicCtrl = require('../controllers/topic');
router.get('/books', bookCtrl.books);
router.post('/book', bookCtrl.bookCreate);
router.get('/book/:bookid', bookCtrl.bookReadOne);
router.put('/books/:bookid', bookCtrl.bookUpdateOne);
router.delete('/books/:bookid', bookCtrl.bookDeleteOne);//topicsrouter.get('/topics', topicCtrl.topics);
module.exports = router;

路由覆盖了增删改查,暂时先实现这部分的路由。后面根据需求再增加。

3)controller实现

一个成功的Restful API应该包含返回的数据和http的状态码,因此我们定义了一个公用方法:

var sendJSONresponse = function (res, status, content) {
    res.status(status);
    res.json(content);
};

比如定义一个bookReadOne方法:

module.exports.bookReadOne = function (req, res) {    var bookid = req.params.bookid;    if (!bookid) {
        sendJSONresponse(res, 404, {            "message": "Not found, bookid is required"
        });        return;
    }
    BookModel.findById(bookid).exec(function (err, book) {        if (!book) {
            sendJSONresponse(res, 404, {                "message": "bookid not found"
            });            return;
        } else if (err) {            sendJSONresponse(res, 400, err);            return;
        }
        console.log(book);        sendJSONresponse(res, 200, book);
    });
}

请求成功发送状态码200和结果,请求失败则发送404或者500及错误。

books.js:

var mongoose = require('mongoose');var BookModel = mongoose.model('Book');var sendJSONresponse = function (res, status, content) {
    res.status(status);
    res.json(content);
};
 
module.exports.books = function (req, res) {
    BookModel.find().exec(function (err, books) {        if (err) {
            console.log(err);
            sendJSONresponse(res, 400, err);            return;
        }
        sendJSONresponse(res, 200, books);
    });
}
module.exports.bookCreate = function (req, res) {
    BookModel.create({
        title: req.body.title,
        info: req.body.info,
        img: req.body.img,
        tags: req.body.tags,
        brief: req.body.brief,
        ISBN: req.body.ISBN
    }, function(err, book) {        if (err) {
            console.log(err);
            sendJSONresponse(res, 400, err);
        } else {
            console.log(book);
            sendJSONresponse(res, 201, book);
        }
    });
}
module.exports.bookReadOne = function (req, res) {    var bookid = req.params.bookid;    if (!bookid) {
        sendJSONresponse(res, 404, {            "message": "Not found, bookid is required"
        });        return;
    }
    BookModel.findById(bookid).exec(function (err, book) {        if (!book) {
            sendJSONresponse(res, 404, {                "message": "bookid not found"
            });            return;
        } else if (err) {
            sendJSONresponse(res, 400, err);            return;
        }
        console.log(book);
        sendJSONresponse(res, 200, book);
    });
}
module.exports.bookUpdateOne = function (req, res) {    var bookid = req.params.bookid;    if (!bookid) {
        sendJSONresponse(res, 404, {            "message": "Not found, bookid is required"
        });        return;
    }
    BookModel.findById(bookid).exec(function (err, book) {        if (!book) {
            sendJSONresponse(res, 404, {                "message": "bookid not found"
            });            return;
        } else if (err) {
            sendJSONresponse(res, 400, err);            return;
        }
        book.title = req.body.title;
        book.rating = req.body.rating;
        book.info = req.body.info;
        book.img = req.body.img;
        book.tags = req.body.tags;
        book.brief = req.body.brief;
        book.ISBN = req.body.ISBN;
        book.save(function (err, book) {            if (err) {
                sendJSONresponse(res, 404, err);
            } else {
                sendJSONresponse(res, 200, book);
            }
        });
    });
}
module.exports.bookDeleteOne = function (req, res) {    var bookid = req.params.bookid;    if (bookid) {
        BookModel.findByIdAndRemove(bookid)
            .exec(function (err) {            if (err) {
                console.log(err);
                sendJSONresponse(res, 404, err);                return;
            }
            console.log("book id :" + bookid + "deleted");
            sendJSONresponse(res, 204, null);
        });
    } else {
        sendJSONresponse(res, 404, { message: "No bookid" });
    }
}

View Code

这样注意一点是,find()、findbyid和findByIdAndRemove不是立即执行,是在exec方法中执行,但是create,save是立即执行的。

5)、调用api

接下来就是在app_server下的controller中调用上面定义的api。在这里需要安装一个request模块,request让http请求变的更加简单。

 在home.js中引用request:

var request = require('request');

request的调用如下:

request(options, callback)

包含options和回调两部分,options结构如下,包含url,method,json和qs四部分。

var requestOptions = {
url : "http://yourapi.com/api/path",
method : "GET",
json : {}, //请求体的JavaScript对象qs : {
offset : 20 //查询字符串}
};

而默认的回调格式如下:

function(err, response, body) {if (err) {
console.log(err);
} else if (response.statusCode === 200) {
console.log(body);
} else {
console.log(response.statusCode);
}
}

修改index方法,先定义一个apiOptions,只想默认路径,记得在发布的时候修改为带域名的地址。

var apiOptions = {
    server : "http://localhost:3000"};
module.exports.index = function (req, res) {    var requestOptions, path;
    path = "/api/topics";
    requestOptions= {
        url: apiOptions.server + path,
        method: "GET",
        json:{},
    }
    request(requestOptions, function (err, response, body) {        if (response.statusCode == 200) {
            res.render('index', { title: 'Index', topics: body });
        } else {
            res.render('error', { message: err.message, error: err });
        }
    });
};

这样就进行了分离,home.js不在需要引用Mongoose部分。

home.js:

var request = require('request');var apiOptions = {
    server : "http://localhost:3000"};//if (process.env.NODE_ENV === 'production') {//    apiOptions.server = "https://stoneniqiu-mean.herokuapp.com/ ";//}module.exports.index = function (req, res) {    var requestOptions, path;
    path = "/api/topics";
    requestOptions= {
        url: apiOptions.server + path,
        method: "GET",
        json:{},
    }
    request(requestOptions, function (err, response, body) {        if (response.statusCode == 200) {
            res.render('index', { title: 'Index', topics: body });
        } else {
            res.render('error', { message: err.message, error: err });
        }
    });
};
module.exports.books = function (req, res) {    var requestOptions, path;
    path = "/api/books";
    requestOptions = {
        url: apiOptions.server + path,
        method: "GET",
        json: {},
    }
    request(requestOptions, function (err, response, body) {        if (response.statusCode == 200) {
            res.render('books', { title: 'Books', books: body });
        } else {
            res.render('error', { message: err.message, error: err });
        }
    });
};
module.exports.detail = function (req, res) {    var requestOptions, path;
    path = "/api/book/" + req.params.id;
    requestOptions = {
        url: apiOptions.server+path ,
        method: "GET",
        json: {},
    }
    request(requestOptions, function (err, response, body) {        if (response.statusCode == 200) {
            res.render('detail', { title: body.title, book: body });
        } else {
            res.render('info', err);
        }
    });
   
   };
module.exports.about = function (req, res) {
    res.render('about', { title: 'About' });
};

View Code   

更多查询可以移步:http://mongoosejs.com/docs/queries.html

在首页,需要处理一下时间显示的问题,增加了一个mixin

mixin formatDate(dateString)  -var date = new Date(dateString);  -var d = date.getDate();  -var monthNames = [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12" ];  -var m = monthNames[date.getMonth()];  -var y = date.getFullYear();  -var output = y + '/' + m + '/' + d;  =output

调用:

   span.pull-right           +formatDate(topic.createdOn)

页面如下:

初步改造完成。之前还写了一个基于回调的service方式的controller和service,类似于C#中的分离。后来觉得还是api的方式更好,留在这里可以当一个参考。

home.js:

var bookservice = require('../services/homeService.js');
 
module.exports.index = function (req, res) {
    bookservice.allTopics(function (result) {
        var obj = result.content;
        console.log(obj.status);        if (result.status == 200) {
            res.render('index', { title: 'Index', topics: obj });
        }
        res.render('info', obj);
    });  
};
module.exports.books = function (req, res) {
    bookservice.allBooks(function(result) {
        var obj = result.content;
        console.log(obj.status);        if (result.status == 200) {
            res.render('books', { title: 'Books', books: obj });
        }
        res.render('info', obj);
    });  
};
module.exports.detail = function (req, res) {
    bookservice.bookReadOne(req.params.id, function (result) {
        var obj = result.content;        if (result.status == 200) {
            res.render('detail', { title: obj.title, book: obj });
        } 
        res.render('info', obj);
    });
   };
module.exports.about = function (req, res) {
    res.render('about', { title: 'About' });
};

View Code

homeService.js:

var mongoose = require('mongoose');var db = require('../models/db.js');var Bookmodel = mongoose.model('Book');var Topicmodel = mongoose.model('Topic');var jsonResult = function (status, content) {    return { status: status, content: content };
};
module.exports.bookReadOne = function (id,callback) {
    console.log('Finding book details', id);    if (!id) {
        console.log('No bookid specified');        return jsonResult(404, { "message": "No bookid specified" });
    }
    Bookmodel.findById(id).exec(function (err, book) {        if (err) {
            callback(jsonResult(404, err));            return;
        }        if (!book) {
            callback(jsonResult(404, { "message": "book not found" }));            return;
        }
       callback(jsonResult(200, book));
    });
};
module.exports.allBooks=function(callback) {
    Bookmodel.find().exec(function (err, books) {        if (err) {
            callback(jsonResult(404, err));            return;
        }        if (!books.length) {
            callback(jsonResult(404, { "message": "books not found" }));            return;
        }
        callback(jsonResult(200, books));
    });
}
module.exports.createBook = function (book, callback) {    var t = new Bookmodel(book);
    t.save(function (err) {
        callback(err);
    });
}
module.exports.allTopics=function(callback) {
    Topicmodel.find().exec(function (err, topics) {        if (err) {
            callback(jsonResult(404, err));            return;
        }        if (!topics.length) {
            callback(jsonResult(404, { "message": "topics not found" }));            return;
        }
        callback(jsonResult(200, topics));
    });
}
module.exports.createTopic=function(topic, callback) {    var t = new Topicmodel(topic);
    t.save(function(err) {
        callback(err);
    });
}var books = [
    {
        id: 0,
        title: "深入浅出Node.js",
        info: "朴灵 / 人民邮电出版社 / 2013-12-1 / CNY 69.00",
        rating: 5,
        img: "https://img3.doubanio.com/mpic/s27269296.jpg",
        tags: ["node", "深入浅出"],
        brief: '本书从不同的视角介绍了 Node 内在的特点和结构。由首章Node 介绍为索引,涉及Node 的各个方面,主要内容包含模块机制的揭示、异步I/O 实现原理的展现、异步编程的探讨、内存控制的介绍、二进制数据Buffer 的细节、Node 中的网络编程基础、Node 中的Web 开发、进程间的消息传递、Node 测试以及通过Node 构建产品需要的注意事项。最后的附录介绍了Node 的安装、调试、编码规范和NPM 仓库等事宜。本书适合想深入了解 Node 的人员阅读。'
        ,ISBN: 9787115335500
    },
    {
        id: 1,
        title: "程序员修炼之道 : 从小工到专家",
        info: "Andrew Hunt、David Thomas / 马维达 / 电子工业出版社 / 2005-1 / 48.00元",
        rating: 5,
        img: "https://img3.doubanio.com/mpic/s3957863.jpg",
        tags: ["程序人生", "软件开发"],
        brief: '《程序员修炼之道》由一系列的独立的部分组成,涵盖的主题从个人责任、职业发展,直到用于使代码保持灵活、并且易于改编和复用的各种架构技术。利用许多富有娱乐性的奇闻轶事、有思想性的例子以及有趣的类比,全面阐释了软件开发的许多不同方面的最佳实践和重大陷阱。无论你是初学者,是有经验的程序员,还是软件项目经理,本书都适合你阅读。'
        ,ISBN: 9787505397194
    },
    {
        id: 2,
        title: "Getting MEAN with Mongo, Express, Angular, and Node",
        info: "Simon Holmes / Manning Publications / 2015-11-26 / USD 44.99",
        rating: 4,
        img: "https://img3.doubanio.com/mpic/s27676844.jpg",
        tags: ["node", "web开发", "编程"],
        brief: 'MEAN栈开发,比较详尽的的应用开发书籍'
        , ISBN: 9781617292033
    }
];var topics = [
    {
        title: "书山有路第十一期:程序员修炼之道-第二章-注重实效的途径--第五天",
        type: "读书",
        visitedCount: 80,
        commentCount: 2,
        createdOn: '2016/5/15 21:32',
        author: 'stoneniqiu',
        img: 'http://upload.jianshu.io/users/upload_avatars/133630/d5370e672fd4.png?imageMogr/thumbnail/90x90/quality/100'
    },
    {
        title: "《明朝那些事儿》之闲言散语",
        type: "书评",
        visitedCount: 180,
        commentCount: 20,
        createdOn: '2016/5/15 21:32',
        author: '卡卡卡萨布兰卡 ',
        img: 'http://upload.jianshu.io/users/upload_avatars/1675188/2d0810ccc03d.jpg?imageMogr/thumbnail/90x90/quality/100'
    },
    {
        title: "有《程序员修炼之道》高清版吗?",
        type: "求书",
        visitedCount: 90,
        commentCount: 1,
        createdOn: '2016/5/15 21:32',
        author: '吾不知 ',
        img: 'http://upload.jianshu.io/users/upload_avatars/1125491/3910f3825f73.jpg?imageMogr/thumbnail/90x90/quality/100',
    },
    {
        title: "《国富论》-读书笔记",
        type: "书评",
        visitedCount: 180,
        commentCount: 20,
        createdOn: '2016/5/15 21:32',
        author: '寻海 '
        ,img: 'http://upload.jianshu.io/users/upload_avatars/133630/d5370e672fd4.png?imageMogr/thumbnail/90x90/quality/100'
    },
    {
        title: "《高效人士的七个习惯》读书笔记",
        type: "书评",
        visitedCount: 180,
        commentCount: 20,
        createdOn: '2016/5/15 21:32',
        author: '书虫纪庆 ',
        img: 'http://upload.jianshu.io/users/upload_avatars/1429280/454c495361f9.jpg?imageMogr/thumbnail/90x90/quality/100'
    },
    {
        title: "《css揭秘》这本书如何",
        type: "求索",
        visitedCount: 58,
        commentCount: 3,
        createdOn: '2016/5/15 21:32',
        author: 'Watery_D_Lotus ',
        img: 'http://upload.jianshu.io/users/upload_avatars/1449533/a2d98762484a.jpg?imageMogr/thumbnail/90x90/quality/100'
    }
];//module.exports.bookCreate = function (req, res) {//    var book = {//        title: "test",//        info: "Simon Holmes / Manning Publications / 2015-11-26 / USD 44.99",//        rating: 4,//        img: "https://img3.doubanio.com/mpic/s27676844.jpg",//        tags: ["node", "web开发", "编程"],//        brief: 'MEAN栈开发,比较详尽的的应用开发书籍',//        ISBN: 9781617292033//    };//    var b = new Bookmodel(book);//    b.save(function (err) {//        if (err) {//            console.log(err);//            res.render('error', {//                message: err.message,//                error: err//            });//        }//        res.render('info', { message: "添加成功!", success: true });//    });//};//module.exports.bookDelete = function (req, res) {//    Bookmodel.findOneAndRemove({ title: "test" }, function (err) {//        if (err) {//            console.log(err);//            res.render('error', {//                message: err.message,//                error: err//            });//        }//        res.render('info', { message: "删除成功!", success: true });//    });//};

View Code

至此,这三个页面的数据全部都是通过api从数据库中获取。那么现在我们要发布,本地数据库显然是不行。那怎么办呢?

四、mlab,500M MongoDB免费空间!

 mlab是一个提供部署在云端的mongodb数据库服务平台,可以对每个用户免费提供500M空间。

 1. 先注册一个账号:https://mlab.com/,并验证邮箱:

 2.点击Create new创建数据库:这里选择亚马逊的单用户sanbox会有免费的500M空间。

 输入数据库名称,并创建

3.创建成功之后,给数据库创建一个用户

 4.连接字符串: 

 第一个字符串是用cmd连接,第二个用于我们的程序。修改db.js 连接成功:

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

怎样用nodejs搭建服务器

vue2全家桶是什么,如何使用?

위 내용은 Nodejs는 Mongoose를 사용하여 모델과 API를 만듭니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.