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开发用户注册登陆界面,具体需求:

  1. 用户进入登陆界面登陆
  2. 用户注册用户
  3. 用户登陆成功进入个人主页

需要用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} //注意secure必须是false,否则session无法存储
})); 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匹配账号密码

特别注意:在login.js中我们使用了session,这是在引入了express-session模块后用户每次请求的request对象都会带有session元素,但是记得如果是http请求(非https)必须在server.js设置关闭cookie的secure(笔者一开始没在意这个配置,发现保存不了session以为是node.js有毛病呢),并记得在设置session的同时设置cookie的时间长度,避免丢失。

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进行写入操作

下面介绍以下mongodb模块连接和操作mongodb的基本套路:

  • require进来mongodb模块,并获得MongoClient对象
  • 使用connect方法按照套接字连接(默认套接字是mongodb://localhost:27017)
  • 回调函数中第二个参数使用db方法选择数据库
  • 数据库对象选择相应的collection(集合,也就相当于关系型数据库中的表)
  • 使用insertMany数组插入多行数据
  • 使用find方法匹配数据,这里并没有用到主键这种东西

代码不全部列出,jade文件代码不是重点,故不一一列出,样例完整代码下载地址:

http://download.csdn.net/download/u014466109/10251935

将js进行到底:node学习8的更多相关文章

  1. 【特别推荐】Node.js 入门教程和学习资源汇总

    这篇文章与大家分享一批很有用的 Node.js 入门教程和学习资源.Node 是一个服务器端的 JavaScript 解释器,它将改变服务器应该如何工作的概念.它的目标是帮助程序员构建高度可伸缩的应用 ...

  2. Node.js 入门教程和学习资源汇总

    这篇文章与大家分享一批很有用的 Node.js 入门教程和学习资源.Node 是一个服务器端的 JavaScript 解释器,它将改变服务器应该如何工作的概念.它的目标是帮助程序员构建高度可伸缩的应用 ...

  3. Node.js环境搭建和学习(windwos环境)

    Node.js环境搭建和学习 一.环境搭建 1.下载安装文件 下载地址http://nodejs-org.qiniudn.com/下载Node.js环境安装包,根据操作系统下载对应的安装包 下载地址 ...

  4. node 学习笔记 - Modules 模块加载系统 (1)

    本文同步自我的个人博客:http://www.52cik.com/2015/12/11/learn-node-modules-path.html 用了这么久的 require,但却没有系统的学习过 n ...

  5. [学姿势]实验室搬砖+node学习

    这周开始进行收尾工作,我当然没有进行核心技术的开发,主要负责的是对web端进行展示上的修修补补,主要包括添加VLC播放器.rtsp视频流以及一些js细节. 1.VLC 全称为Video Lan Cli ...

  6. 2015第40周二Node学习

    node历史 今天看cnode开源项目用了io.js,在查这个项目时发现这篇文章node历史,node.js和io.js关系谈到Node.js的由来,不可避免要聊到它的创始人Ryan Dahl.在20 ...

  7. 2015第40周一Node学习

    node学习尝试 早上看了张丹大牛博客文章nodeJS学习路线图和node从零入门系列,感觉获益匪浅,尝试了里面几项内容,对node有了更深入的认识. npm npm是一个node包管理和分发工具,已 ...

  8. Node学习——开篇

    前言:自从下决心转学前端以来,我的专业课java基本荒废了,所以对于后台开发的逻辑也已基本忘干净了.但是作为一名准前端程序猿,我认为还是有必要了解后端开发的,虽不必深入学习,但是能够了解项目从前端到后 ...

  9. node 学习资料

    Node 学习资料: 资料名称 网址 Node.js 中文API文档 http://nodejs.cn/api/ Node 菜鸟教程 http://www.runoob.com/nodejs/node ...

  10. Node学习HTTP模块(HTTP 服务器与客户端)

    Node学习HTTP模块(HTTP 服务器与客户端) Node.js 标准库提供了 http 模块,其中封装了一个高效的 HTTP 服务器和一个简易的HTTP 客户端.http.Server 是一个基 ...

随机推荐

  1. Ackermann函数

    Ackermann函数定义如下: 若m=0,返回n+1. 若m>0且n=0,返回Ackermann(m-1,1). 若m>0且n>0,返回Ackermann(m-1,Ackerman ...

  2. Fractal Dimension|Relative Complexity|CG含量|重复序列|

    生物信息学-序列拼接方法 物理学方法 Fractal Dimension of Exon and Intron Sequences --------------CGCGGCGTGTGTTATA --- ...

  3. B-树与B+树 两者的区别

    一个m阶的B树具有如下几个特征: 根结点至少有两个子女. 每个中间节点都包含k-1个元素和k个孩子,其中 m/2 <= k <= m 每一个叶子节点都包含k-1个元素,其中 m/2 < ...

  4. CodeForces 993B Open Communication(STL 模拟)

    https://codeforces.com/problemset/problem/993/b 这题不难,暴力就能过,主要是题意太难懂了 题意: 现在有两个人,每个人手中有一对数,第一个人手中的数是n ...

  5. anaconda学习笔记

    anaconda介绍 Anaconda指的是一个开源的Python发行版本,其包含了conda.Python等180多个科学包及其依赖项. Conda是一个开源的包.环境管理器,可以用于在同一个机器上 ...

  6. 19)PHP,数组知识

    (1)数组的基础 在PHP中,数组的下标可以是数字,也可以是字符串 在PHP中,数组元素的顺序不是由下标决定的,而是由其加入的的顺序决定 (2)数组定义: array(1,5,11,'abs',tru ...

  7. Java中的堆、栈、方法区

    堆区: 1.存储的全部是对象,每个对象都包含一个与之对应的class的信息.(class的目的是得到操作指令) 2.jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对 ...

  8. tensorflow(四)

    tensorflow数据处理方法, 1.输入数据集 小数据集,可一次性加载到内存处理. 大数据集,一般由大量数据文件组成,因为数据集的规模太大,无法一次性加载到内存,只能每一步训练时加载数据,可以采用 ...

  9. SwaggerConfig

    package me.zhengjie.common.swagger2; import com.google.common.base.Predicates; import org.springfram ...

  10. EmailService

    package me.zhengjie.tools.service; import me.zhengjie.tools.domain.EmailConfig; import me.zhengjie.t ...