목차
1. mongo 설치 후 cmd를 이용해 설치 디렉터리 아래의 bin 디렉터리로 이동합니다. Mongo를 실행하세요. 버전 번호가 나타나면 시작이 성공한 것입니다.
2. 컴퓨터를 시작할 때마다 dbpath를 설정하지 않으려면 mongo를 서비스 시작으로 설정해야 합니다. 두 단계로 먼저 cmd를 관리자로 열고 mongo bin 디렉터리로 전환합니다.
3. 더 편리하게 데스크탑에 star.bat 파일을 만들 수 있습니다:
4. 일반적인 명령/기본 작업
1. 설치
2. 연결 설정
3.数据模型
4.操作数据
웹 프론트엔드 JS 튜토리얼 Nodejs는 Mongoose를 사용하여 모델과 API를 만듭니다.

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

Mar 16, 2018 pm 02:22 PM
javascript nodejs

이번에는 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으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

nodejs와 tomcat의 차이점 nodejs와 tomcat의 차이점 Apr 21, 2024 am 04:16 AM

Node.js와 Tomcat의 주요 차이점은 다음과 같습니다. 런타임: Node.js는 JavaScript 런타임을 기반으로 하는 반면 Tomcat은 Java Servlet 컨테이너입니다. I/O 모델: Node.js는 비동기식 비차단 모델을 사용하는 반면 Tomcat은 동기식 차단 모델을 사용합니다. 동시성 처리: Node.js는 이벤트 루프를 통해 동시성을 처리하는 반면 Tomcat은 스레드 풀을 사용합니다. 애플리케이션 시나리오: Node.js는 실시간, 데이터 집약적, 동시성 애플리케이션에 적합하고 Tomcat은 기존 Java 웹 애플리케이션에 적합합니다.

nodejs와 vuejs의 차이점 nodejs와 vuejs의 차이점 Apr 21, 2024 am 04:17 AM

Node.js는 서버측 JavaScript 런타임인 반면, Vue.js는 대화형 사용자 인터페이스를 생성하기 위한 클라이언트측 JavaScript 프레임워크입니다. Node.js는 백엔드 서비스 API 개발, 데이터 처리 등 서버 측 개발에 사용되고, Vue.js는 단일 페이지 애플리케이션, 반응형 사용자 인터페이스 등 클라이언트 측 개발에 사용됩니다.

nodejs는 백엔드 프레임워크인가요? nodejs는 백엔드 프레임워크인가요? Apr 21, 2024 am 05:09 AM

Node.js는 고성능, 확장성, 크로스 플랫폼 지원, 풍부한 생태계, 개발 용이성 등의 기능을 제공하므로 백엔드 프레임워크로 사용할 수 있습니다.

nodejs를 mysql 데이터베이스에 연결하는 방법 nodejs를 mysql 데이터베이스에 연결하는 방법 Apr 21, 2024 am 06:13 AM

MySQL 데이터베이스에 연결하려면 다음 단계를 따라야 합니다. mysql2 드라이버를 설치합니다. mysql2.createConnection()을 사용하여 호스트 주소, 포트, 사용자 이름, 비밀번호 및 데이터베이스 이름이 포함된 연결 개체를 만듭니다. 쿼리를 수행하려면 Connection.query()를 사용하세요. 마지막으로 Connection.end()를 사용하여 연결을 종료합니다.

nodejs의 전역 변수는 무엇입니까 nodejs의 전역 변수는 무엇입니까 Apr 21, 2024 am 04:54 AM

Node.js에는 다음과 같은 전역 변수가 존재합니다. 전역 개체: 전역 핵심 모듈: 프로세스, 콘솔, 필수 런타임 환경 변수: __dirname, __filename, __line, __column 상수: undefine, null, NaN, Infinity, -Infinity

nodejs와 java 사이에 큰 차이가 있나요? nodejs와 java 사이에 큰 차이가 있나요? Apr 21, 2024 am 06:12 AM

Node.js와 Java의 주요 차이점은 디자인과 기능입니다. 이벤트 중심 대 스레드 중심: Node.js는 이벤트 중심이고 Java는 스레드 중심입니다. 단일 스레드 대 다중 스레드: Node.js는 단일 스레드 이벤트 루프를 사용하고 Java는 다중 스레드 아키텍처를 사용합니다. 런타임 환경: Node.js는 V8 JavaScript 엔진에서 실행되는 반면 Java는 JVM에서 실행됩니다. 구문: Node.js는 JavaScript 구문을 사용하고 Java는 Java 구문을 사용합니다. 목적: Node.js는 I/O 집약적인 작업에 적합한 반면, Java는 대규모 엔터프라이즈 애플리케이션에 적합합니다.

nodejs 설치 디렉토리에 있는 npm과 npm.cmd 파일의 차이점은 무엇입니까? nodejs 설치 디렉토리에 있는 npm과 npm.cmd 파일의 차이점은 무엇입니까? Apr 21, 2024 am 05:18 AM

Node.js 설치 디렉터리에는 npm과 npm.cmd라는 두 가지 npm 관련 파일이 있습니다. 차이점은 다음과 같습니다. 확장자가 다릅니다. npm은 실행 파일이고 npm.cmd는 명령 창 바로 가기입니다. Windows 사용자: npm.cmd는 명령 프롬프트에서 사용할 수 있으며, npm은 명령줄에서만 실행할 수 있습니다. 호환성: npm.cmd는 Windows 시스템에만 해당되며 npm은 크로스 플랫폼에서 사용할 수 있습니다. 사용 권장사항: Windows 사용자는 npm.cmd를 사용하고, 기타 운영 체제는 npm을 사용합니다.

nodejs는 백엔드 개발 언어인가요? nodejs는 백엔드 개발 언어인가요? Apr 21, 2024 am 05:09 AM

예, Node.js는 백엔드 개발 언어입니다. 서버 측 비즈니스 로직 처리, 데이터베이스 연결 관리, API 제공 등 백엔드 개발에 사용됩니다.

See all articles