最近在學習node.js,作了一個練手項目,使用node.js+express框架,配合mysql數據庫和前端vue框架開發一個多人文檔編輯系統。css
node.js環境下express+mysql的服務端項目示例前端
首先是環境搭建:vue
node環境下node
$ npm install -g express-generator
$ express -e project
複製代碼
進入項目文件根目錄安裝依賴模塊mysql
$ npm install
$ DEBUG=node-blog:* npm start
複製代碼
看看項目目錄都有什麼git
看看生成的工程目錄裏面都有什麼,github
bin:存放可執行文件sql
node_modules:存放 package.json 中安裝的模塊,當你在 package.json 添加依賴的模塊並安裝後,存放在這個文件夾下數據庫
public:存放 image、css、js 等前端資源文件express
routes:存放路由文件
views:存放視圖文件或者說模版文件
app.js:啓動文件,或者說入口文件
package.json:存儲着工程的信息及模塊依賴,當在 dependencies 中添加依賴的模塊時,運行npm install ,npm 會檢查當前目錄下的
package.json,並自動安裝全部指定的模塊
下面開始安裝數據庫,這裏我選擇的是mysql。
npm install mysql --save-dev
複製代碼
安裝完畢以後,開始配置數據庫。
//mysql配置文件
mysql = {
host: "xx.xxx.xx.xxx", //這是數據庫的地址
user: "xxx", //須要用戶的名字
password: "xxx", //用戶密碼 ,若是你沒有密碼,直接雙引號就是
database: "xxx" //數據庫名字
} //好了,這樣咱們就能鏈接數據庫了
module.exports = mysql; //用module.exports暴露出這個接口,
複製代碼
mysql鏈接池配置:
//mysql鏈接池配置文件
var mysql = require('mysql');
var $dbConfig = require('../config/mysql');//注意改爲本身項目中mysql配置文件的路徑
// 使用鏈接池,避免開太多的線程,提高性能
var pool = mysql.createPool($dbConfig);
/**
* 對query執行的結果自定義返回JSON結果
*/
function responseDoReturn(res, result, resultJSON) {
if (typeof result === 'undefined') {
res.json({
code: '201',
msg: 'failed to do'
});
} else {
res.json(result);
}
};
/**
* 封裝query之sql帶不佔位符func
*/
function query(sql, callback) {
pool.getConnection(function(err, connection) {
connection.query(sql, function(err, rows) {
callback(err, rows);
//釋放連接
connection.release();
});
});
}
/**
* 封裝query之sql帶佔位符func
*/
function queryArgs(sql, args, callback) {
pool.getConnection(function(err, connection) {
connection.query(sql, args, function(err, rows) {
callback(err, rows);
//釋放連接
connection.release();
});
});
}
//exports
module.exports = {
query: query,
queryArgs: queryArgs,
doReturn: responseDoReturn
}
複製代碼
操做數據庫的過程比較靈活,我是使用模塊化的思想,將一張數據表封裝成一個模塊暴露出去,經過該模塊獲取這張表的增刪改查SQL語句。下面貼上示例代碼:
let express = require('express');
let mysql = require('../common/basicConnection');
let qibu_task = {
index: '',
value: '',
list: `SELECT * from qibu_task;`, //列表查詢
insert(args) {
qibu_task.index = '';
qibu_task.value = '';
args = filter(['id', 'task', 'name', 'created_at'], args)
for (let key in args) {
qibu_task.index = `${qibu_task.index}${key},`
let re = /^[0-9]+.?[0-9]*/;
if (re.test(args[key])) {
qibu_task.value = `${qibu_task.value}${args[key]},`
} else {
qibu_task.value = `${qibu_task.value}'${args[key]}',`
}
}
qibu_task.index = qibu_task.index.substr(0, qibu_task.index.length - 1);
qibu_task.value = qibu_task.value.substr(0, qibu_task.value.length - 1);
return `INSERT INTO qibu_task (${qibu_task.index}) VALUES(${qibu_task.value})`;
}, //按需增長
select(index, value) {
return `SELECT * from qibu_task where ${index}=${value};` //按需查詢
},
delete(index, value) {
return `DELETE from qibu_task where ${index}=${value};` //按需刪除
},
update(index, args) { //提交修改
if (index in args) {
qibu_task.value = '';
args = filter(['id', 'task', 'name', 'created_at'], args)
for (let key in args) {
let re = /^[0-9]+.?[0-9]*/;
if (re.test(args[key])) {
qibu_task.value = `${qibu_task.value}${key}=${args[key]},`
} else {
qibu_task.value = `${qibu_task.value}${key}='${args[key]}',`
}
}
qibu_task.value = qibu_task.value.substr(0, qibu_task.value.length - 1)
return `UPDATE qibu_task SET ${qibu_task.value} WHERE ${index}=${args[index]};`
}
},
};
//參數過濾
function filter(arguments, obj) {
let newObj = {}
arguments.forEach(every => {
if (every in obj) {
newObj[every] = obj[every]
}
});
return newObj;
};
module.exports = qibu_task;
複製代碼
而後就能夠在路由返回時進行數據庫操做啦。具體代碼就不貼啦。路由能夠識別get、post方法,修改和刪除經過傳遞參數模擬。
項目中以爲對每張數據表單獨寫增刪改查語句效率過低,因此對數據表SQL語句生成的過程進行了一些修改,經過構造函數構造出DBSQL類來生成想要的數據表的SQL語句,在路由中new一個DBSQL實例便可,具體代碼已經上傳github。