1. 程式人生 > >將js進行到底:node學習8

將js進行到底:node學習8

json 存儲格式 服務啟動 兩件 定位 mmu php程序 實戰 end

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}
}));

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

技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片

將js進行到底:node學習8