Node js web開發簡單demo學習筆記
本人於今年1月開始接觸node js,接觸的時間不長,所以技術水平還有待提高,希望這篇簡單的文章能夠對大家學習nodejs有所幫助。
一、專案描述
1、專案概要:
主要是使用nodejs實現一個基本的demo的增刪改查的功能為在nodejs技術上專案的擴充套件開發做準備。開發環境主要使用了webstorm,資料庫使用了mysql,使用nodejs的express。呼叫了nodejs的mysql擴充套件包。呼叫了nodejs的node-uuid擴充套件包,主要用於uuid 的建立上。呼叫了nodejs的async擴充套件包,主要用於對於回撥函式的排序處理。
頁面模版主要使用了ejs,但在具體使用上將字尾名改為了
2、專案結構:
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:用於測試
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 其他:無
二、詳細實現
//引入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){
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><a href="/delete?id=<%= name.id %>">刪除</a></td>//超連結並用get方式傳值
<td><a href="/update?id=<%= name.id %>">修改</a></td>
</tr>
<% }) %>
</table>
<p><a href="/Insert">新增</a></p>
</body>
</html>
11、update.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');