Express,mysql,ejs搭建簡單電影網站
npm init; npm install express moment mysql:我們使用nodejs的express框架,moment是一個日期處理類庫,mysql資料庫,ejs模板
app.js 中例項化express,設定基本配置,如模板引擎,啟動埠號:
var express = require('express'); var path = require('path'); var port = process.env.PORT || 3000; // 設定啟動埠 var app = express(); app.set('views', path.join(__dirname, 'views'
app.js 設定路由,index.ejs設定dom模板,admin.ejs,list.ejs,detail.ejs
<!DOCTYPE> <html> <head> <meta name="viewport" charset="UTF-8" content="width=device-width, initial-scale=1.0"
// index page app.get('/', function(req, res) { res.render('index', { title: '電影網首頁' }); }); // detail page app.get('/movie/:id', function(req, res) { res.render('detail', { title: '電影網詳情頁'
當前目錄結構,includes是公共的部分footere.js,footer.ejs; options.js代表前端js邏輯
()課程中用了bower管理前端的包,但是我覺得沒有必要現在來增加學習成本,所以我選擇直接引入。安裝好jq和bootstrap後,找到node_modules中這兩個包的dist目錄,把靜態資源css和js複製到根目錄下的src中,需要在nodejs中,指定我們的靜態資源目錄 app.js
app.use('/src', express.static(path.join(__dirname, 'src'))); // 指定靜態資源目錄
/src為虛擬的一個目錄,這樣就可以在ejs模板中使用了,<link rel="stylesheet" href="/src/css/bootstrap.css" >
ejs模板基本語法
- include 引入其他資料夾下的模板
<%- include('../includes/footer') %>
- for迴圈
<% for (var i = 0; i < moive.length; i++) { %><div><%= moive[i].title %></div><% } %>
- 拼湊屬性
<a href="/moive/<%= moive[i]._id %>">
- include 引入其他資料夾下的模板
資料庫 mysql (app.js)
mysql的基本操作都是通過connect.query來實現的,官方文件
連線資料庫,關於什麼時候連線關閉資料庫,我還要研究,文章後面已經新增
var mysql = require('mysql'); var connection = mysql.createConnection({ host: 'localhost', user: 'root', password: '', database: 'moive' }); connection.connect();
查詢資料,修改
app.get('/', function(req, res){})
路由app.get('/', function(req, res) { // 查詢所有資料內容 connection.query('SELECT * FROM moive_data', function(error, results, fields) { if (error) throw error; else { res.render('index', { title: '電影網首頁', moive: results }); } }); });
最開始的時候results可以使用模擬資料
新增一條資料
// 新增一條資料 前端程式碼邏輯 $('#addOption').on('click', function() { $.ajax({ type: "POST", url: "/admin/add", data: { title: $("#inputTitle").val(), doctor: $("#inputDoctor").val(), country: $("#inputCountry").val(), year: $("#inputYear").val(), poster: $("#inputPoster").val(), language: $("#inputLanguage").val(), flash: $("#inputFlash").val(), summary: $("#inputSummary").val(), }, success: function(res) { console.log("Data Saved: " + res); } }); });
- 刪除資料
app.delete('/admin/list', function(req, res) { let id = req.body.id; console.log(id); connection.query(`delete from moive_data where _id = ${id}`, function(error, results, fields) { if (error) { console.log(error); connection.end(); } else { console.log('delete: ', results) } }); }); // 刪除一條資料 前端邏輯程式碼 $('.del').on('click', function() { let del_id = $(this).attr('data-id'); $.ajax({ type: "DELETE", url: "/admin/list", data: { id: del_id }, success: function(res) { console.log("Data Saved: " + res); } }); });
更新修改一條資料
首先只是渲染一介面
app.get('/admin/update/:id', function(req, res) { let id = req.params.id; connection.query(`select * from moive_data where _id = ${id}`, function(error, results, fields) { if (error) { console.log(error); } else { res.render('admin', { title: '電影網列表頁', moive: results }); } }); });
由於修改以及錄入我們使用的是同一個介面admin介面,所以我們也需要做一個判斷,判斷即將執行更新還是新增,更改options.js的前端程式碼
$('#addOption').on('click', function() { let hiddenVal = $('#inputHidden').val(), itype = "PUT"; if (!hiddenVal) { itype = "POST"; } console.log(hiddenVal) // 隱藏域值為null,新增資料 $.ajax({ type: itype, url: "/admin/add", data: { id: hiddenVal, title: $("#inputTitle").val(), doctor: $("#inputDoctor").val(), country: $("#inputCountry").val(), year: $("#inputYear").val(), poster: $("#inputPoster").val(), language: $("#inputLanguage").val(), flash: $("#inputFlash").val(), summary: $("#inputSummary").val(), }, success: function(res) { console.log("Data Saved: " + res); } }); });
新增後端更新介面
app.put('/admin/add', function(req, res) { let id = req.body.id; let [title, doctor, country, year, poster, language, flash, summary] = [req.body.title, req.body.doctor, req.body.country, req.body.year, req.body.poster, req.body.language, req.body.flash, req.body.summary]; connection.query(`update moive_data set title=?,doctor=?,country=?,year=?,poster=?,language=?,flash=?,summary=? where _id = ${id}`, [title, doctor, country, year, poster, language, flash, summary], function(error, results, fields) { if (error) { console.log(error); } else { console.log('update: ' + results); } }); });
因為程式碼太多,只列出關鍵程式碼,詳細程式碼可以檢視github
重點
- 儲存資料庫資料的時候,text,var型別的欄位需要新增引號’${xx}’
關於ajax提交後的跳轉。我才明白,ajax做的是區域性重新整理就是為了不跳轉所以才使用ajax 如果你需要跳轉的那應該使用from表單提交。如果你實在不小心使用了ajax比如我,就應該在後端返回需要跳轉的url,在前端進行跳轉
res.send({ status: 200, msg: "add success", url: "/" }); //前端邏輯 if (res.status === 200) { window.location.href = res.url; }
但是我目前遇到的問題就是,跳轉時而成功時而失敗,失敗的時候出現:比如我當前的路由是/admin/add 跳轉的時候http請求頭卻會顯示referer屬性/admin/add?多了一個問號,操作完成後,瀏覽器不會跳轉到目標頁面而是重新整理當前頁面,瀏覽器會顯示/admin/add?,我目前沒有解決
連線池,mysql是自己支援了連線池,不同資料庫可能不一樣。
-
// 使用連線池連線資料庫 var mysql = require("mysql"); var pool = mysql.createPool({ connectionLimit: 100, host: 'localhost', user: 'root', password: '', database: 'moive' }); var query = function(sql, options, callback) { pool.getConnection(function(err, con) { if (err) { callback(err, null, null); } else { con.query(sql, options, function(err, results, fields) { callback(err, results, fields); }); } con.release(); // 釋放資源 }); } module.exports = query;
使用修改connection.query為query
var query = require('./mysql-pool'); // 使用連線池連線資料庫 app.get('/', function(req, res) { // 查詢所有資料內容 query('select * from moive_data', [], function(error, results, fields) { if (error) { console.log(error); } else { res.render('index', { title: '電影網首頁', moive: results }); } }); });
-
新增錄入插入時間。在建立mysql的時候新增一個欄位 intime 如圖設定
,每次更新也回自動更新時間。獲取資料的事後根據時間排序只需要在sql語句中新增order by + 欄位 ,比如:select * from moive_data order by intime
就可以啦