1. 程式人生 > >Node js web開發簡單demo學習筆記

Node js web開發簡單demo學習筆記

本人於今年1月開始接觸node js,接觸的時間不長,所以技術水平還有待提高,希望這篇簡單的文章能夠對大家學習nodejs有所幫助。

一、專案描述

1、專案概要:

主要是使用nodejs實現一個基本的demo的增刪改查的功能為在nodejs技術上專案的擴充套件開發做準備。開發環境主要使用了webstorm,資料庫使用了mysql,使用nodejs的express。呼叫了nodejsmysql擴充套件包。呼叫了nodejsnode-uuid擴充套件包,主要用於uuid 的建立上。呼叫了nodejsasync擴充套件包,主要用於對於回撥函式的排序處理。

頁面模版主要使用了ejs,但在具體使用上將字尾名改為了

html

2、專案結構:

Dao目錄:關於資料庫相關操作的工具集合。

Config.js:資料庫註冊資訊。

Daobase:資料庫基本dqldml操作的工具。

Userdao:對於tb_test_user_表的增刪改查的函式的工具類。

Model目錄:專案資料模型。

User:資料模型。

Node_modules:開發環境新增的專案相關的庫檔案。

Public:(未用到)

Routesnodejsexpress包的控制層,路由選擇器的功能。用於分配訪問路徑。

Index.js:基本的頁面後臺邏輯函式的實現
users.js:(未用到)

Test:自定義測試包

asyncTest.js:用於測試

async元件(測試函式可用但是實際函式有問題,留作以後研究點)

Test.js:對於daobase.js功能的測試。

TestDao.js:用於userdao.js功能的測試。

Viewsejs模版頁面集合

Error.html:用於顯示錯誤資訊

Index.html:登入頁面

Insert.html:新增頁面

Success.html:用於顯示所有資料,功能成功後的跳轉頁面

Update.html:修改頁面

App.js:路由對映表(routes下主要用於跳轉邏輯,此檔案主要用於對映選擇)

Package.json:類似與mavonpom.xml,主要用於依賴包的版本註冊

3、資料庫設計細節

資料庫名:db_test_

表名:tb_test_user_

列名:id 資料型別:varchar 預設長度:50 其他:主鍵

列名:name 資料型別:varchar 預設長度:50 其他:無

列名:password 資料型別:varchar 預設長度:50 其他:無

二、詳細實現

//引入app.js檔案

var app = require('../app');

2Config.js檔案

module.exports={
    host:'localhost',
    user:'root',
    password:'root',
    database:'db_test_',
    ports:3306};

詳解:

Module.exports指將檔案暴露給module空間,而檔案所代表的為當前函式。(此檔案函式為json格式)。 host:為mysqlurluser,password,database,ports分別為:需要用的資料庫的帳號、密碼、資料庫名和埠號。

3、Daobase.js檔案

var config=require('./config.js');//引入配置檔案
var mysql=require('mysql');//引入mysql驅動
var pool=mysql.createPool(config);//建立資料庫連線池
//dql函式(用於查詢的函式)exports.executeQuery=function(sql, data, callback){

//建立連線,並在其回撥函式內設定相關操作(nodejs的相關操作都在回撥函式裡,問題較大,加大了程式碼複雜度
    pool.getConnection(function(err,conn){
        if(err){
            callback(err,null,null);
        }else{

/*與dml的回撥函式引數表不同,其他類似

Qerr:當正確時返回null,錯誤時返回有用值

Vals:用於儲存返回值資訊,返回的為一個物件陣列,需用下表加表的列名取得值,示例如下:vals[0].name

Fields:返回表結構的相關資訊。(本人未如何使用)
  */

          conn.query(sql,data,function(qerr, vals, fields){

//重置資料庫連線
                conn.release();

//用於傳入回撥函式,處理資料
                callback(qerr,vals,fields);
            });
        }
    });
};
//dml函式(用於增加、修改、刪除的函式)exports.executeUpdate function(sql, data, callback) {
    pool.getConnection(function(err, conn) {
        if (err) {
            callback(err, nullnull);
        } else {

//data用於佔位符的資料傳入,一些意外的情況本人還未測試
            conn.query(sql, data, function(qerr, result) {
                //釋放連線conn.release();
                //事件驅動回撥callback(qerr, result);
            });
        }
    });
};

4、userdao.js檔案

var DaoBase = require('./DaoBase');//引入dbutil
var UUID = require('node-uuid');//引入uuid模組
var user_DB = require('../model/User');//引入模型模組
var userDB new user_DB();//例項化模型模組
//新增使用者exports.InsertUser=function(params, callback){
    var data=[];//寫差了,應該用例項化後的模型,但是不影響使用
    var sql='INSERT INTO tb_test_user_ (id,NAME,PASSWORD) VALUES(?,?,?)';
    var id=UUID.v4();
    data.push(id);//按佔位符順序加入陣列
    data.push(params.name);
    data.push(params.password);
    DaoBase.executeUpdate(sql,data,callback);
};
//修改使用者exports.UpdateUser=function(params,id, callback){
    var sql='UPDATE  tb_test_user_ SET NAME=?,PASSWORD=? WHERE id=?';
    var data=[];
    data.push(params.name);
    data.push(params.password);
    data.push(id);
    DaoBase.executeUpdate(sql,data,callback);
};
//刪除使用者exports.DeleteUser=function(id,callback){
    var sql='delete from tb_test_user_  where id=?';
    var data=[];
    data.push(id);
    DaoBase.executeUpdate(sql,data,callback);
};
//查詢所有使用者exports.FindAll=function(callback){
    var sql='select * from tb_test_user_';
    DaoBase.executeQuery(sql,callback);
};
//根據id查詢exports.FindById=function(id,callback){
    var sql='select * from tb_test_user_ where id=? ';
    var data=[];
    data.push(id);
    DaoBase.executeQuery(sql,data,callback);
};
//登陸驗證exports.UserLogin=function(params,callback){
    var sql='select * from tb_test_user_ where name=? and password=?';
    var data=[];
    data.push(params.name);
    data.push(params.password);
    DaoBase.executeQuery(sql,data,callback);
}

5、user.js檔案

module.exports=User;
function User(){
    this.tableName='tb_test_user_';
    this.id='id';
    this.name='name';
    this.password='password';
}

6index.js檔案

var express = require('express');//引入express包
var userDao=require('../dao/UserDao.js');//引入userdao檔案
var user_DB = require('../model/User');//引入user實體

//修改初始化exports.update=function(req,res){
  var id=req.query.id;//nodejs 的get獲取傳參辦法使用req.query.引數名
  console.log(id);
  userDao.FindById(id,function(qerr, vals,fields){
    if(!(qerr==null)){

//選擇渲染ejs模版並跳轉傳參
      res.render('error',{
        message:'尋找修改元素失敗'});
    }

//獲得資料庫裡面的資訊並傳到頁面(請注意這裡用到了多重回調函式巢狀)var username=vals[0].name;
    var password=vals[0].password;
    var id=vals[0].id;
    res.render('update',{
      title:'修改資料',
      username:username,
      password:password,
      id:id});
  });
};
//修改(對於修改頁面的初始化工作)exports.doUpdate=function(req,res){
  var id=req.body.id;//post傳值的接收方式req.Body.引數名(post傳值需要)
  var name=req.body.username;
  var password=req.body.password;
  var user=new user_DB();
  user.name=name;
  user.password=password;
  userDao.UpdateUser(user,id,function(qerr, result){
    if(!(qerr==null)){
      res.render('error',{
        message:'修改失敗'});
    }

//用影響行數去判定dml操作是否成功(請注意即使影響行數為0,函式依然不返回錯誤)
    if(result.affectedRows>0){
      console.log('success');
      userDao.FindAll(function(qerr,vals,fields){
        var result=vals;
        res.render('success',{
          title:'修改成功',
          result:result});
      });
    }
  });
};
//刪除exports.delete=function(req,res){
  var id=req.query.id;
  userDao.DeleteUser(id,function(qerr, result){
    if(!(qerr==null)){
      console.log('error');
      res.render('error',{
        message:'刪除失敗'});
    }
    if(result.affectedRows>0){
      console.log('success');
      userDao.FindAll(function(qerr,vals,fields){
        var result=vals;
        res.render('success',{
          title:'刪除成功',
          result:result});
      });
    }
  });
};
//新增初始化exports.insert=function(req,res){
  res.render('Insert',{
    title:'新增資料'});
};
//新增exports.doInsert=function(req,res){
  var username=req.body.username;//我覺得這裡寫的有點重複,可以直接將值賦給實體
  var password=req.body.password;
  var user=new user_DB();
  user.name=username;
  user.password=password;
  userDao.InsertUser(user,function(qerr, result){
    if(!(qerr==null)){
      res.render('error',{
        message:'新增失敗'});
    }
    if(result.affectedRows>0){
      userDao.FindAll(function(qerr,vals,fields){
        var result=vals;//直接將結果集封裝到json裡傳給頁面,由頁面去解封處理
        res.render('success',{
          title:'新增成功',
          result:result});
      });
    }
  });
};
//登入初始化exports.login=function(req,res){
  res.render('index',{
    title:'你好'});
};
//登入驗證exports.doLogin=function(req,res){
  var username=req.body.username;
  var password=req.body.password;
  var user=new user_DB();
  user.name=username;
  user.password=password;
  userDao.UserLogin(user,function(qerr, vals,fields){
    if((!(qerr==null))||(vals.length<1)){
      res.render('error',{
        message:'登入失敗'});
    }else{
      userDao.FindAll(function(qerr,vals,fields){
        var result=vals;
        res.render('success',{
          title:'你好',
          result:result});
      });
    }
  });
};

7、 Error.html

<h1><%= message %></h1>//只用於顯示結果

8、 Index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title><%= title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <h1><%= title %></h1>
    <p>Welcome to <%= title %></p>
    <form method="post" > //表單可不命名(多表單的頁面需要進一步嘗試),由於get用於初始化了,所以只能用post提交(node js 有use、get、post三個函式用於處理請求,這只是我所知的,如果有其他方式應可以解決只能post提交問題,當然如果使用中介軟體應該也可以,我剛剛接觸對於中介軟體還不是很熟悉,當然對於進階中介軟體還是很重要的)
    <input type="text"  name="username" > //name屬性用於伺服器端接收
    <input type="password" name="password" > //
    <input type="submit" value="submit">
    </form>
  </body>
</html>

9、 Insert.html //與登入功能相似所以不再贅述

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title><%= title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
    <h1><%= title %></h1>
    <form method="post">
        <p>賬號名:<input type="text" name="username"></p>
        <p>密碼:<input type="text" name="password"></p>
        <p><input type="submit" value="submit"></p>
    </form>
</body>
</html>

10、 Success.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title><%= title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <h1><%= title %></h1>

    <table>

      <% result.forEach(function(name){ %>//迭代遍歷取出後臺傳過來的result值,

函式中的name為result中依次各個元素的別名,用name取出每個資料庫中列名的值
      <tr>

        <td><%= name.name %></td>
        <td><%= name.password %></td>
        <td></td>
        <td><href="/delete?id=<%= name.id %>">刪除</a></td>//超連結並用get方式傳值
        <td><href="/update?id=<%= name.id %>">修改</a></td>
      </tr>
      <% }) %>
    </table>
  <p><href="/Insert">新增</a></p>

  </body>
</html>

11update.html //只是學習用的示例所以修改頁面寫的有些簡略

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title><%= title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<h1><%= title %></h1>
<form method="post">
    <p><%= id %></p>
    <p><input type="text" name="id" value="<%= id %>">  </p>//用於向後臺傳id,應當設為不可見
    <p><%= username %></p>
    <p>賬號名:<input type="text" name="username" value="<%= username %>" ></p>
    <p><%= password %></p>
    <p>密碼:<input type="text" name="password" value="<%= password %>"></p>
    <p><input type="submit" value="submit"></p>
</form>
</body>
</html>

12、App.js(以下只展示需要改和自己寫的模組)

var routes = require('./routes/index');