zoukankan      html  css  js  c++  java
  • 将js进行到底:node学习8

    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:ProgramsMongoDBServer3.6db --logpath D:ProgramsMongoDBServer3.6logmongodb.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

    这里写图片描述

    这里写图片描述

    这里写图片描述

    这里写图片描述

  • 相关阅读:
    cocos2d-x类型转换(CCstring int string char UTF-8互转)
    cocos2d-x 实心圆
    CCLabelTTF的多行显示(仅限中文)
    cocos2d-x 弹窗
    cocos2d-x 画线
    cocos2d-x 利用CCLabelTTF制作文字描边与阴影效果的实现方法
    cocos2d-x 背景色修改
    cocos2d-x 中文乱码问题
    HelloWorld.exe 中的 0x0f9265f6 (libcocos2d.dll) 处有未经处理的异常: 0xC0000005: 读取位置 0x00000038 时发生访问冲突
    error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
  • 原文地址:https://www.cnblogs.com/devilyouwei/p/8448944.html
Copyright © 2011-2022 走看看