Tạo Web CURD đơn giản với Nodejs + Mysql + EJS

Mở đầu Trong bài viết này mình sẽ tạo web CRUD đơn giản bằng Nodejs sử dụng Mysql , Express, Ejs. Chuẩn bị Các bạn hãy xem bài viết này để tạo cơ sở dữ liệu cũng như tạo một dự án nodejs + express. Mình sẽ không nhắc lại để tránh mất thời gian

Mở đầu

Trong bài viết này mình sẽ tạo web CRUD đơn giản bằng Nodejs sử dụng Mysql , Express, Ejs.

Chuẩn bị

Các bạn hãy xem bài viết này để tạo cơ sở dữ liệu cũng như tạo một dự án nodejs + express. Mình sẽ không nhắc lại để tránh mất thời gian của các bạn.

Cấu trúc thư mục

image.png

Tạo Model

Trong file bangDia.model.js ta sẽ tạo 2 class BangDiaQLBD.

"use strict";const sql =require("../conf/db");classBangDia{constructor(bangDia){this.tenBangDia = bangDia?.tenBangDia;this.theLoai = bangDia?.theLoai;this.nhaSX = bangDia?.nhaSX;this.noiDung = bangDia?.noiDung;this.gia = bangDia?.gia;}}classQLBD{staticinsert(bangDia, callback){
    sql.query("INSERT INTO bangdia SET ?", bangDia,(err, res)=>{if(err){
        console.log("err", err);callback(err,null);return;}
      console.log("inserted:",{ id: res.insertId });callback(null,{
        id: res.insertId,...bangDia,});});}staticgetById(id, callback){
    sql.query(`SELECT * FROM bangdia WHERE id = ${id}`,(err, res)=>{if(err){
        console.log("err", err);callback(err,null);return;}if(res.length){
        console.log("found: ", res[0]);callback(null, res[0]);return;}// not found with the idcallback({ kind:"not_found"},null);});}staticgetAll(tenBangDia, callback){let query ="SELECT * FROM bangdia";if(tenBangDia){
      query +=` WHERE tenBangDia LIKE '%${tenBangDia}%'`;}// nếu có truyền vào tên băng đĩa thì sẽ tìm kiếm theo tên

    sql.query(query,(err, res)=>{if(err){
        console.log("error: ", err);callback(null, err);return;}
      console.log("bangDia: ", res);callback(null, res);});}staticupdate(id, bangDia, callback){
    sql.query("UPDATE bangdia SET ? WHERE id = ?",[bangDia, id],(err, res)=>{if(err){
          console.log("error: ", err);callback(null, err);return;}if(res.affectedRows ==0){// not found  with the idcallback({ kind:"not_found"},null);return;}
        console.log("updated : ",{ id: id,...bangDia });callback(null,{ id: id,...bangDia });});}staticdelete(id, callback){
    sql.query("DELETE FROM bangdia WHERE id = ?", id,(err, res)=>{if(err){
        console.log("error: ", err);callback(null, err);return;}if(res.affectedRows ==0){// not found with the idcallback({ kind:"not_found"},null);return;}
      console.log("deleted with id: ", id);callback(null, res);});}}

module.exports ={ BangDia,QLBD};

Tạo Controller

Trong file bangDia.controller.js tạo class BangDiaCtrl.

"use strict";const{ BangDia,QLBD}=require("../models/bangDia.model");classBangDiaCtrl{index(req, res){
    res.locals.deleted = req.query.deleted;const tenBangDia = req.query.tenBangDia;QLBD.getAll(tenBangDia,(err, data)=>{if(err) res.redirect("/500");else res.render("bangDia/index",{ bangDias: data });});}showFormCreate(req, res){
    res.locals.status = req.query.status;
    res.render("bangDia/create");}create(req, res){if(!req.body){
      res.redirect("bangDia/create?status=error");}const newBangDia =newBangDia(req.body);QLBD.insert(newBangDia,(err, result)=>{if(err) res.redirect("/bangDia/create?status=error");else{
        console.log(result);
        res.redirect("/bangDia");}});}showFormEdit(req, res){
    res.locals.status = req.query.status;QLBD.getById(req.params.id,(err, result)=>{if(err){if(err.kind ==="not_found"){
          res.redirect("/404");}else{
          res.redirect("/500");}}else res.render("bangDia/edit",{ bangDia: result });});}update(req, res){const newBangDia =newBangDia(req.body);QLBD.update(req.params.id, newBangDia,(err, result)=>{if(err){if(err.kind ==="not_found"){
          res.redirect("/404");}else{
          res.redirect("/500");}}else{
        res.redirect("/bangDia");}});}delete(req, res){QLBD.delete(req.params.id,(err, result)=>{if(err){if(err.kind ==="not_found"){
          res.redirect("/404");}else{
          res.redirect("/500");}}else res.redirect("/bangDia?deleted=true");});}}

module.exports =newBangDiaCtrl();

Tạo Router

Tạo file **bangDia.router.js ** .

const router =require("express").Router();const bangDiaCtrl =require("../controllers/bangDia.controller");

module.exports=(app)=>{
  router.get("/", bangDiaCtrl.index);
  router.get("/create", bangDiaCtrl.showFormCreate);
  router.post("/", bangDiaCtrl.create);
  router.get("/delete/:id", bangDiaCtrl.delete);
  router.put("/:id", bangDiaCtrl.update);
  router.get("/edit/:id",bangDiaCtrl.showFormEdit);

  app.use("/bangDia", router);};

Tạo View

Tạo View index.ejs để hiển thị tất cả băng đĩa.

<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"/><metahttp-equiv="X-UA-Compatible"content="IE=edge"/><metaname="viewport"content="width=device-width, initial-scale=1.0"/><linkrel="stylesheet"href="/css/index.css"/><title>BangDia</title></head><body><h1>Get All BangDia</h1>
    <% if (typeof deleted !=='undefined' ) { %> <%if (deleted=='true' ) { %>
    <divstyle="color: green">Deleted Successfully</div>
    <% } %>
    <br/>
    <% } %>
    <formaction="/bangDia"method="get"><inputtype="text"name="tenBangDia"placeholder="Enter tenBangDia"/><buttontype="submit">Search</button></form><br/><ahref="/bangDia/create">insert</a><br/><tableborder="1"cellpadding="0"cellspacing="0"><tr><th>ID</th><th>tenBangDia</th><th>theLoai</th><th>nhaSX</th><th>noiDung</th><th>gia</th><th>Action</th></tr>
      <% bangDias.forEach((item)=> { %>
      <tr><td><%= item.id %></td><td><%= item.tenBangDia %></td><td><%= item.theLoai %></td><td><%= item.nhaSX %></td><td><%= item.noiDung %></td><td><%= item.gia %></td><td><ahref="/bangDia/edit/<%= item.id %>">Edit</a><br/><ahref="/bangDia/delete/<%= item.id %>">Delete</a></td></tr>
      <% }) %>
    </table><br/><ahref="/">back</a><br/></body></html>

Tạo view create.ejs để thêm mới băng đĩa.

<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"/><metahttp-equiv="X-UA-Compatible"content="IE=edge"/><metaname="viewport"content="width=device-width, initial-scale=1.0"/><linkrel="stylesheet"href="/css/index.css"/><title>Create BangDia</title></head><body><h2>Create new BangDia</h2><formaction="/bangDia"method="post"><labelfor="tenBangDia">tenBangDia</label><inputtype="text"id="tenBangDia"name="tenBangDia"/><br/><br/><labelfor="theLoai">theLoai</label><inputtype="text"name="theLoai"id="theLoai"/><br/><br/><labelfor="nhaSX">nhaSX</label><inputtype="text"name="nhaSX"id="nhaSX"/><br/><br/><labelfor="noiDung">noiDung</label><inputtype="text"name="noiDung"id="noiDung"/><br/><br/><labelfor="gia">gia</label><inputtype="number"name="gia"id="gia"/><br/><br/><buttontype="submit">Save</button></form><br/><ahref="/bangDia">back</a><br/></body></html>

Tạo view edit.ejs để sửa thông tin băng đĩa.

<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"/><metahttp-equiv="X-UA-Compatible"content="IE=edge"/><metaname="viewport"content="width=device-width, initial-scale=1.0"/><linkrel="stylesheet"href="/css/index.css"/><title>Edit BangDia - <%= bangDia.tenBangDia %></title></head><body><h2>Edit BangDia</h2><formaction="/bangDia/<%= bangDia.id %>"method="post"><inputname="_method"type="hidden"value="put"/><labelfor="title">tenBangDia</label><inputtype="text"id="tenBangDia"name="tenBangDia"value="<%= bangDia.tenBangDia %>"/><br/><br/><labelfor="theLoai">theLoai</label><inputtype="text"name="theLoai"id="theLoai"value="<%= bangDia.theLoai %>"/><br/><br/><labelfor="nhaSX">nhaSX</label><inputtype="text"name="nhaSX"id="nhaSX"value="<%= bangDia.nhaSX %>"/><br/><br/><br/><labelfor="noiDung">noiDung</label><inputtype="text"name="noiDung"id="noiDung"value="<%= bangDia.noiDung %>"/><br/><br/><br/><labelfor="gia">gia</label><inputtype="number"name="gia"id="gia"value="<%= bangDia.gia %>"/><br/><br/><buttontype="submit">Update</button></form><br/><ahref="/bangDia">back</a><br/></body></html>

Kết luận

Mình đã hướng dẫn xây dựng web crud đơn giản bằng nodejs các bạn có thể tham khảo sroure code tại đây.

Nguồn: viblo.asia

Bài viết liên quan

9 Mẹo lập trình Web “ẩn mình” giúp tiết kiệm hàng giờ đồng hồ

Hầu hết các lập trình viên (kể cả những người giỏi) đều tốn thời gian x

Can GPT-4o Generate Images? All You Need to Know about GPT-4o-image

OpenAI‘s GPT-4o, introduced on March 25, 2025, has revolutionized the way we create visual con

Khi nào nên dùng main, section, article, header, footer, và aside trong HTML5

HTML5 đã giới thiệu các thẻ ngữ nghĩa giúp cấu trúc nội dung web một cách có

So sánh Webhook và API: Khi nào nên sử dụng?

Trong lĩnh vực công nghệ thông tin và phát triển phần mềm, Webhook và API là hai th