Node.js 与数据库之 MongoDB
废话: 现代 web 开发可以说完全是数据库驱动的, 而对于我这样的 PHP 程序员来说, 对 Mysql 向来十分钟情, MongoDB 的兴起让我不能再对 Mysql 孤注一掷, 了不起的 node.js 一书中首推的数据库就是 MongoDB, 也许其性能和功能并没有 Mysql 那么强大, 靠山也没有 oracle 这样的大公司, 但是为什么我觉得值得去研究和使用, 在这之前, 我们先来说说 MongoDB 好处都有啥!
MongoDB
首先, MongoDB 非常的年轻, 生于 2012 年, 然后他是一个基于分布式文件存储的数据库他非常适合 Node.js 应用
MongoDB 的定位介于关系型数据库和非关系型数据库, 支持的数据结构松散, 类似于 json
和 Mysql 最大的区别是: mysql 需要按照固定的表结构存储数据, 而 mongo 可以将任意类型的文档数据存储在集合中
当 MongoDB 与 Node.js 强强联手时, 基本存储格式都是 json, 因此数据库后端前端的数据格式可以得到较好统一, 这是最骚的! 我觉得 json 真的是我最爱的 web 数据传输格式
最后, MongoDB 虽然不是完整的关系型数据库, 但依然强于 NoSQL 类型数据库, 因为他并非简单的键值对存储, 而是可以多层次(就是类似 json), 对象下还可以存储对象, 这就使得他可以存储较为复杂的数据结构和关系, 所以这真的就牛逼了
至于性能, 自行研究, 参考: https://www.cnblogs.com/web-fusheng/p/6884759.html
Windows 下安装 MongoDB
别说安装一步到位, 我在 windows 下安装还真遇到一些小坑
首先官方下载地址: https://www.mongodb.com/download-center#community
我下载的是社区版本, 一般个人就使用社区版就行了, 之前 oracle 学习我也使用社区版的
安装选择 custom 模式, 安装目录下有个 bin 目录, 将其添加到环境变量中
打开 cmd, 安装 mongoDB 服务, 注意这一点很关键, 直接启动 Mongo 是不行的, 另外尽量用管理员身份运行 cmd 去做以下操作
mongod--dbpath D: \Programs\MongoDB\Server\3.6\db--logpath D: \Programs\MongoDB\Server\3.6\log\mongodb.log--install--serviceName "mongo"
这段命令做了两件事, 一件事是设置了数据文件目录和日志文件(oracle 会在安装时选择好), 另一件就是把 Mongo 的服务加入到 windows 的 net 服务中去
接下来:
net start mongo
看到服务启动成功即可, 如果不成功, 切换为管理员权限
连接 MongoDB:
mongo
Node.js 连接 MongoDB
任何一门语言需要连接到数据库, 就需要数据库的 API, 以此提供驱动库, 使用前导入驱动库即可调用 API, 数据库驱动的作用就是使得语言理解数据库连接协议, 负责解码编码与数据库交换的数据, 保证连接的稳定性等
在 Node.js 中使用 mongo 需要 mongodb 模块支持
- package.json {
- "name": "user-login-example",
- "description": "a user login,register example by using mongoDB",
- "version": "0.0.1",
- "dependencies": {
- "express": "latest",
- "mongodb": "latest",
- "jade": "latest",
- "express-session": "latest"
- }
- }
连接插入测试:
- var mongo = require("mongodb").MongoClient;
- // 连接到 mongo 服务
- mongo.connect(mongodb://localhost:27017,function(err,client){
- if(err) throw err;
- console.log("Connected mongo");
- // 选择 test 库
- db = client.db("test");
- // 从 test 中选择 documents 这个集合
- var collection = db.collection(documents);
- var data = [{a:1},{a:2},{a:3}];
- // 插入多条数据
- collection.insertMany(data,function(err,res){
- if(err) throw err;
- else console.log("3 documents inserted");
- client.close();
- });
- });
- node server
运行之后使用 mongo compass 查看数据库里多的数据
可以看到三条数据已经插入其中
注意: 在使用 MongoDB API 连接后, 不存在的数据库会在操作前创建, 不存在集合 (collection) 会在操作前创建, mango 不必担心数据库是否存在的问题 collection 类似于 mysql 下的一张表
这个 API 可以使用 insertMany 一次插入多条数据, 让我觉得十分惊奇!
实战开发登陆注册样例
下面进入简单的实践环节, 使用 node.js 和 mongoDB 开发用户注册登陆界面, 具体需求:
用户进入登陆界面登陆
用户注册用户
用户登陆成功进入个人主页
需要用 jade 模块构建视图模型, express 的 session 中间件, mongo 数据库存储用户注册信息
除此以外, 是时候介绍以下模块化思想了:
在 web 开发中, 不可能把所有请求和控制器处理都放在同一个 js 文件中, 应该要为每一个 view 提供一个 controller, 这是 MVC 模式的一种思想, 也就是不同页面处理应当有单独的文件管理, 便于后期维护, 减少 server.js 文件代码量, 不管怎么说专门的分类看着都让人爽呐
需要利用当初学习 node 第一章时的 exports 对象, 将模块 API 暴露给其他模块使用, 实现模块划分
项目文件
views 目录
项目文件构建基本思想是将视图和控制器分离, 控制器模块化, 每一个模块对应一个视图文件 Jade, 构建思想来源于我之前 PHP MVC 开发经验
- server.js
- var app = require("express")();
- var bodyParser = require(body-parser);
- var cookieParser = require(cookie-parser);
- var session = require("express-session");
- // 引入控制器
- var index = require("./index"),
- login = require("./login"),
- register = require("./register");
- app.use(bodyParser.json()); // for parsing application/json
- app.use(cookieParser("devilyouwei"));
- app.use(bodyParser.urlencoded({ extended: true })); // 对 post 请求表单提交的数据编码, 否则服务器端无法获得
- // 使用 session 中间件
- app.use(session({
- secret: devilyouwei,
- resave: false,
- saveUninitialized: true,
- cookie: { secure: false ,maxAge:3600000}
- }));
- app.set("view engine","jade");
- app.set("views",__dirname+"/views");
- app.get("/",index);
- app.get("/login",login);
- app.get("/register",register);
- app.get("/logout",index.logout);
- // 表单提交请求
- app.post("/login",login);
- app.post("/register",register);
- app.listen(3000);
这是主模块, 提供 http 服务, 并将请求分配到不同的 js 控制器上
- index.js module.exports = index;
- function index(req, res, next) {
- console.log(req.session);
- if (req.session.user) res.render("index", {
- authenticated: true,
- username: req.session.user
- });
- else res.render("index");
- }
- index.logout = function(req, res, next) {
- req.session.user = null;
- res.redirect("/");
- }
主页控制, 需检查 session
- login.js module.exports = login;
- var mongo = require("mongodb").MongoClient;
- function login(req, res, next) {
- if (req.method == "GET") res.render("login");
- else if (req.method == "POST") {
- auth(req.body,
- function(flag) {
- // 通过验证, 账号密码正确
- if (flag) {
- req.session.user = flag.email;
- req.session.cookie.expires = new Date(Date.now() + 3600000);
- req.session.cookie.maxAge = 3600000;
- console.log(req.session);
- res.redirect("/");
- } else {
- // 账号密码错误
- res.send("账号密码错误!")
- }
- });
- } else {
- res.send(404);
- }
- }
- function auth(data, fn) {
- mongo.connect(mongodb: //localhost:27017,function(err,client){
- if (err) throw err; db = client.db("test");
- var collection = db.collection(users); collection.find(data).toArray(function(err, docs) {
- if (err) throw err;
- client.close();
- // 如果没找到, 数组长度为 0, 返回 false, 表示账号密码有错误
- if (docs.length == 0) fn(false);
- else fn(docs[0]);
- });
- })
- }
登陆模块, auth 方法查询 mangodb 匹配账号密码
- register.js module.exports = register
- var mongo = require("mongodb").MongoClient;
- function register(req, res, next) {
- if (req.method == "GET") res.render("register");
- else if (req.method == "POST") {
- // 此处需要做安全验证, 略
- save(req.body,
- function() {
- res.redirect("/login");
- });
- } else {
- res.send(404);
- }
- }
- // 保存用户注册信息
- function save(data, fn) {
- mongo.connect(mongodb: //localhost:27017,function(err,client){
- if (err) throw err; console.log("Connected mongo"); db = client.db("test");
- var collection = db.collection(users); collection.insertMany([data],
- function(err, res) {
- if (err) throw err;
- else console.log("1 user inserted");
- client.close();
- fn();
- });
- })
- }
注册模块, save 方法对 mongodb 进行写入操作
代码不全部列出, jade 文件代码不是重点, 故不一一列出, 样例完整代码下载地址:
http://download.csdn.net/download/u014466109/10251935
来源: http://www.bubuko.com/infodetail-2498665.html