検索
ホームページウェブフロントエンドjsチュートリアルNodejs は Mongoose を使用してモデルと API を作成します

今回は、Mongoose を使用して Nodejs でモデルと API を作成する方法について説明します。Mongoose を使用して Nodejs でモデルと API を作成する場合の注意点について説明します。

MongoDBは、通常使用されているリレーショナルデータベースとは異なり、BSON形式(jsonバイナリ)で保存される分散型文書保存データベースであり、高いパフォーマンス、簡単な導入、簡単な使用を特徴としています。 (詳細は百科事典を参照してください) JavaScriptの読み書きに対応しているのがMEANスタック開発の最大の特徴であり、データベースを含めたフロントエンドとバックエンドがすべてJavaScriptで記述されています。 Mongoose は EntityFramwork (ORM-オブジェクト リレーショナル マッピング) と比較することができ、その主な機能は開発者がデータベースをより便利に操作できるようにすることです。始める前に、最初に mongodb をインストールすることを忘れないでください。

1. MongoDBの準備

1. mongoをインストールしたら、cmdを使用してインストールディレクトリ下のbinディレクトリに移動します。 mongo を実行します。バージョン番号が表示されたら、起動が成功したことを意味します:

「コンピューターが積極的に拒否」が表示された場合は、指定したデータへのパスである dbpath を設定する必要があります。

mongod --dbpath=c:\mongodb\db

成功したら、http://localhost:28017/ にアクセスすると、次のページが表示されます:

は、すべての準備ができたことを示しています。

2. コンピューターを起動するたびに dbpath を設定する必要がないようにするには、サービスのスタートアップとして mongo を設定する必要があります。 2 つの手順で、まず管理者として 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. 共通コマンド/基本操作

View db:

show dbs

データベースに切り替える:

switched to db dbname
或者:
use dbname

特定のデータベースの下のコレクションを表示する

show collections

コレクションの下のドキュメントを表示する:

db.collections.find()

このセクションの焦点は mongo の操作方法を紹介することではないためcmd 内なので、これ以上は必要ありません。これ以上の詳細はありません。このような詳細については、最前線のプログラマーのブログ「Learn mongoDB in 8 days」を参照してください。コンピューターに sp1 がインストールされていない場合、インストールが成功した後、公式 Web サイトの 3.0 バージョンを実行することはできません。インストール不要の 2.xx バージョンを使用できます。次にMongooseの動作を中心に説明します。

2. Mongoose

1. インストール

npm:

を使用してインストールすることもできます。プロジェクト上で「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 <p style="text-align: left;">这段代码里面有查询和新建保存,mongoose.model("Book") 相当于EF中的db.Books。而这里的find()方法并没有立即执行,这里有点像Linq的感觉,可以链式查询:</p><pre class="brush:php;toolbar:false">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 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
CおよびJavaScript:接続が説明しましたCおよびJavaScript:接続が説明しましたApr 23, 2025 am 12:07 AM

CおよびJavaScriptは、WebAssemblyを介して相互運用性を実現します。 1)CコードはWebAssemblyモジュールにコンパイルされ、JavaScript環境に導入され、コンピューティングパワーが強化されます。 2)ゲーム開発では、Cは物理エンジンとグラフィックスレンダリングを処理し、JavaScriptはゲームロジックとユーザーインターフェイスを担当します。

Webサイトからアプリまで:JavaScriptの多様なアプリケーションWebサイトからアプリまで:JavaScriptの多様なアプリケーションApr 22, 2025 am 12:02 AM

JavaScriptは、Webサイト、モバイルアプリケーション、デスクトップアプリケーション、サーバー側のプログラミングで広く使用されています。 1)Webサイト開発では、JavaScriptはHTMLおよびCSSと一緒にDOMを運用して、JQueryやReactなどのフレームワークをサポートします。 2)ReactNativeおよびIonicを通じて、JavaScriptはクロスプラットフォームモバイルアプリケーションを開発するために使用されます。 3)電子フレームワークにより、JavaScriptはデスクトップアプリケーションを構築できます。 4)node.jsを使用すると、JavaScriptがサーバー側で実行され、高い並行リクエストをサポートします。

Python vs. JavaScript:ユースケースとアプリケーションと比較されますPython vs. JavaScript:ユースケースとアプリケーションと比較されますApr 21, 2025 am 12:01 AM

Pythonはデータサイエンスと自動化により適していますが、JavaScriptはフロントエンドとフルスタックの開発により適しています。 1. Pythonは、データ処理とモデリングのためにNumpyやPandasなどのライブラリを使用して、データサイエンスと機械学習でうまく機能します。 2。Pythonは、自動化とスクリプトにおいて簡潔で効率的です。 3. JavaScriptはフロントエンド開発に不可欠であり、動的なWebページと単一ページアプリケーションの構築に使用されます。 4. JavaScriptは、node.jsを通じてバックエンド開発において役割を果たし、フルスタック開発をサポートします。

JavaScript通訳者とコンパイラにおけるC/Cの役割JavaScript通訳者とコンパイラにおけるC/Cの役割Apr 20, 2025 am 12:01 AM

CとCは、主に通訳者とJITコンパイラを実装するために使用されるJavaScriptエンジンで重要な役割を果たします。 1)cは、JavaScriptソースコードを解析し、抽象的な構文ツリーを生成するために使用されます。 2)Cは、Bytecodeの生成と実行を担当します。 3)Cは、JITコンパイラを実装し、実行時にホットスポットコードを最適化およびコンパイルし、JavaScriptの実行効率を大幅に改善します。

JavaScript in Action:実際の例とプロジェクトJavaScript in Action:実際の例とプロジェクトApr 19, 2025 am 12:13 AM

現実世界でのJavaScriptのアプリケーションには、フロントエンドとバックエンドの開発が含まれます。 1)DOM操作とイベント処理を含むTODOリストアプリケーションを構築して、フロントエンドアプリケーションを表示します。 2)node.jsを介してRestfulapiを構築し、バックエンドアプリケーションをデモンストレーションします。

JavaScriptとWeb:コア機能とユースケースJavaScriptとWeb:コア機能とユースケースApr 18, 2025 am 12:19 AM

Web開発におけるJavaScriptの主な用途には、クライアントの相互作用、フォーム検証、非同期通信が含まれます。 1)DOM操作による動的なコンテンツの更新とユーザーインタラクション。 2)ユーザーエクスペリエンスを改善するためにデータを提出する前に、クライアントの検証が実行されます。 3)サーバーとのリフレッシュレス通信は、AJAXテクノロジーを通じて達成されます。

JavaScriptエンジンの理解:実装の詳細JavaScriptエンジンの理解:実装の詳細Apr 17, 2025 am 12:05 AM

JavaScriptエンジンが内部的にどのように機能するかを理解することは、開発者にとってより効率的なコードの作成とパフォーマンスのボトルネックと最適化戦略の理解に役立つためです。 1)エンジンのワークフローには、3つの段階が含まれます。解析、コンパイル、実行。 2)実行プロセス中、エンジンはインラインキャッシュや非表示クラスなどの動的最適化を実行します。 3)ベストプラクティスには、グローバル変数の避け、ループの最適化、constとletsの使用、閉鎖の過度の使用の回避が含まれます。

Python vs. JavaScript:学習曲線と使いやすさPython vs. JavaScript:学習曲線と使いやすさApr 16, 2025 am 12:12 AM

Pythonは、スムーズな学習曲線と簡潔な構文を備えた初心者により適しています。 JavaScriptは、急な学習曲線と柔軟な構文を備えたフロントエンド開発に適しています。 1。Python構文は直感的で、データサイエンスやバックエンド開発に適しています。 2。JavaScriptは柔軟で、フロントエンドおよびサーバー側のプログラミングで広く使用されています。

See all articles

ホット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衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強力な PHP 統合開発環境

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

DVWA

DVWA

Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

VSCode Windows 64 ビットのダウンロード

VSCode Windows 64 ビットのダウンロード

Microsoft によって発売された無料で強力な IDE エディター

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)