本人於今年1月開始接觸node js,接觸的時間不長,所以技術水平還有待提高,希望這篇簡單的文章能夠對大家學習nodejs有所協助。
一、項目描述
1、項目概要:
主要是使用nodejs實現一個基本的demo的增刪改查的功能為在nodejs技術上項目的擴充開發做準備。開發環境主要使用了webstorm,資料庫使用了mysql,使用nodejs的express。調用了nodejs的mysql擴充包。調用了nodejs的node-uuid擴充包,主要用於uuid 的建立上。調用了nodejs的async擴充包,主要用於對於回呼函數的排序處理。
頁面模版主要使用了ejs,但在具體使用上將尾碼名改為了html。
2、項目結構:
Bin目錄:www.js檔案。建立項目時開發環境自動建立,可以用來修改預設訪問地址。
Dao目錄:關於資料庫相關操作的工具集合。
Config.js:資料庫註冊資訊。
Daobase:資料庫基本dql和dml操作的工具。
Userdao:對於tb_test_user_表的增刪改查的函數的工具類。
Model目錄:項目資料模型。
User:資料模型。
Node_modules:開發環境添加的項目相關的庫檔案。
Public:(未用到)
Routes:nodejs中express包的控制層,路由選取器的功能。用於分配訪問路徑。
Index.js:基本的頁面後台邏輯函數的實現
users.js:(未用到)
Test:自訂測試包
asyncTest.js:用於測試async組件(測試函數可用但是實際函數有問題,留作以後研究點)
Test.js:對於daobase.js功能的測試。
TestDao.js:用於userdao.js功能的測試。
Views:ejs模版頁面集合
Error.html:用於顯示錯誤資訊
Index.html:登入頁面
Insert.html:添加頁面
Success.html:用於顯示所有資料,功能成功後的跳轉頁面
Update.html:修改頁面
App.js:路由映射表(routes下主要用於跳轉邏輯,此檔案主要用於映射選擇)
Package.json:類似與mavon的pom.xml,主要用於依賴包的版本註冊
3、資料庫設計細節
資料庫名:db_test_
表名:tb_test_user_
列名:id 資料類型:varchar 預設長度:50 其他:主鍵
列名:name 資料類型:varchar 預設長度:50 其他:無
列名:password 資料類型:varchar 預設長度:50 其他:無
二、詳細實現
1、www.js檔案
//引入app.js檔案
var app = require('../app');
2、Config.js檔案
module.exports={
host:'localhost',
user:'root',
password:'root',
database:'db_test_',
ports:3306
};
詳解:
Module.exports指將檔案暴露給module空間,而檔案所代表的為當前函數。(此檔案函數為json格式)。 host:為mysql的url,user,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, null, null);
} 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';
}
6、index.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){
&n