Skip to main content
0
DatabaseLibrary / FrameworkNode.js

Node JS กับ Sequelize 101

สวัสดีครับเพื่อน ๆ วันนี้ผมจะพาไปรู้จักกับเครื่องมือตัวนึงที่จะทำให้เราต่อและจัดการกับ Relational Database ใน Node JS Project ได้อย่างง่ายดายซึ่งเครื่องมือนั้นก็คือ Sequelize นั่นเอง

เรามาเริ่มกันที่ Relational Database  มันคือ ระบบฐานข้อมูลเชิงสัมพันธ์ อันนี้เข้าใจยากไป เอาง่าย ๆ มันก็ คือโครงสร้างฐานข้อมูลที่สามารถกำหนด​ความสัมพันธ์ของแต่ละ Table ใน Database ขึ้นมาได้ ข้างในเก็บข้อมูลในรูปของตาราง (Table) ในแต่ละตารางแบ่งออกเป็นแถว ๆ และในแต่ละแถวจะแบ่งเป็นแอตทริบิวต์ (Attribute) หรืออีกชื่อที่เข้าใจง่าย ๆ ก็คือ คอลัมน์ (Column) ซึ่งในการเชื่อมโยงกันระหว่างข้อมูลในตารางต่าง ๆ จะเชื่อมโยงโดยใช้การอ้างอิงจากข้อมูลในคอลัมน์ที่กำหนดไว้นั่นเอง

Sequelize คืออะไร? 

Sequelize คืออะไร?  มันคือ Object Relational Mapping (ORM) ตัวหนึ่งที่ใช้กับ Database ที่เป็น Relational Database อย่างเช่น Postgres, MySQL, MariaDB, SQLite และ Microsoft SQL Server

Concept การทำงานของมัน คือ แปลง Object ไปเป็น Database หรือแปลงจาก Database กลับมาเป็น Object โดยอ้างอิงจาก Schema ที่เราสร้างเอาไว้เดี๋ยวทำก็จะเข้าในมากขึ้นอย่างเพิ่งงงกันก่อนล่ะ

ส่วนนี่ก็คือ Database ของนักฟุตบอลแบบง่าย ๆ ที่เราจะใช้กันวันนี้โดยมี Schema ดังนี้

CREATE TABLE `Team`
(
   `tid`    int NOT NULL AUTO_INCREMENT,
   `name`   varchar(45) NOT NULL ,
   `league` varchar(45) NOT NULL ,
   PRIMARY KEY (`tid`)
);

CREATE TABLE `Player`
(
   `pid`      int NOT NULL AUTO_INCREMENT,
   `tid`      int NOT NULL ,
   `name`     varchar(45) NOT NULL ,
   `age`      int NOT NULL ,
   `position` varchar(45) NOT NULL ,
   PRIMARY KEY (`pid`),
   KEY `fkIdx_112` (`tid`),
   CONSTRAINT `FK_110` FOREIGN KEY `fkIdx_112` (`tid`) REFERENCES `Team` (`tid`)
);

วันนี้ที่เราจะมาลองสร้างกันเป็นการทำ RESTfull API ที่ใช้สำหรับจัดการ Database ของนักฟุตบอลด้านบนกันนะครับ เริ่มกันที่ Install กันก่อนเลยย

npm init
npm i express sequelize mysql2

พอเรา Install เสร็จสิ้น ก็สร้าง index.js ตาม code ด้านล่างเลยยแล้วลองเข้า Browser หรือ Postman เช็คกันเลยว่า Server ของเราติดไหม

const express = require("express");
const app = express();
app.use(express.json());

app.get('/, async (req, res) => {
   res.sendStatus(200);
});

app.listen(3000, () =>{
   console.log("sever run on port " + 3000);
});

เมื่อเรา Server เราใช้งานได้ก็ไปที่ขั้นทัดไปที่เป็นพระเองของวันนี้กันเลยยเจ้า Sequelize นั้นเอง
เริ่มกันที่ผมจะสร้าง Folder ชื่อ DB มาใหม่เพื่อเก็บข้อมูลและการตั้งค่าต่างๆ ของ Sequelize เอาไว้นั่นเองใน DB และผมจะสร้าง Folder ชื่อว่า Model เพิ่มนะครับเอาไว้ใช้เก็บ Model ของแต่ละ Table โดยผมจะแยก 1 Table ให้มัน File เป็นของตัวเองนะครับ ในแต่ละ Line ผมจะ Comment เอาไว้นะครับว่าคืออะไร

/db/model/player.js

module.exports = ( sequelize , Sequelize ) => {
   const player = sequelize.define(
      'player',
      {

         // ด้านล่างเป็นการตั้งค่า attribute ของ table นะครับ
         // ชื่อตัวแปรที่เราใช้เรียกแทน: { type: Sequelize.STRING(50), allowNull: false, field: 'ชื่อของ attribute' } 
         // สามารถใส่ option เพิ่มเติมได้นะครับเช่น primaryKey: true อะไรแบบนี้ 
         // แล้วก็อันนี้สำคัญ ** ไม่จำเป็นต้องสร้าง attribute ที่เป็น FK จาก table อื่นนะครับ เพราะเราจะไปกำหนด relation กันใน file index
         pid: { type: Sequelize.INTEGER(11), primaryKey: true, autoIncrement: true, field: 'pid' },
         name: { type: Sequelize.STRING(50), allowNull: false, field: 'name' },
         age: { type: Sequelize.INTEGER(11), allowNull: false, field: 'age' },
         position: { type: Sequelize.STRING(50), allowNull: false, field: 'position' },
      },
      {
         tableName: 'player' 
      }
   );
  
   return player;
}

/db/model/team.js

module.exports = ( sequelize , Sequelize ) => {
   const team = sequelize.define(
      'team',
      {
         tid: { type: Sequelize.INTEGER(11), primaryKey: true, autoIncrement: true, field: 'tid' },
         name: { type: Sequelize.STRING(50), allowNull: false, field: 'name' },
         league: { type: Sequelize.STRING(50), allowNull: false, field: 'league' },
      },
      {
         tableName: 'team'
      }
   );

   return team;
}

เมื่อเราสร้าง Model ของแต่ล่ะ Table เสร็จแล้วก็มาที่ index.js กันต่อเลย
/db/index.js

const { Sequelize } = require('sequelize');

//อันนี้เป็นส่วนที่ใช้ในการบอก Sequelize ว่าเราจะ connect ไปที่ไหน
const sequelize = new Sequelize(
   'football',  // นี่เป็นชื่อ DB ของเรานะครับ
   'root',      // user ที่ใช้สรการเข้าไปยัง db
   '',          // password 
   {
      host: 'localhost',    // host ของ db ที่เราสร้างเอาไว้
      dialect: 'mysql',     // 'mysql' | 'mariadb' | 'postgres' | 'mssql'   พวกนี้ใช่ก็ใช้ได้นะจ๊ะ
      define: {
         timestamps: false  //ส่วนตรงนี้ก็เป็นการตั้งค่าเพิ่มเติม
      }
   }
);

const db = {};

db.Sequelize = Sequelize;
db.sequelize = sequelize;

//ส่วนนี้เป็นการ import model ของ table ใน database เข้ามาเพื่อตั้งต่า relation นะครับ
db.player = require("./model/player")( sequelize , Sequelize );
db.team = require("./model/team")( sequelize , Sequelize );

//ส่วนนี้เป็นการตั้งต่า relation นะครับ โดยเป็นการบอกว่าใน 1 team มีได้หลาย player ง่ายๆ ก็คือ relation แบบ 1:M 
db.team.hasMany(
   db.player,
   {
      foreignKey: { name: 'tid', field: 'tid' },  //name ตรงสำคัญพยายามตั่งให้เป็นชื่อเดียวกับ FK ใน table ที่นำไปใช้นะครับ
    }
  );

//ส่วนนี้เป็นการตั้ง relation แบบกลับกันกับด้านบน จริงแล้วเราไม่ตั้งก็ได้นะครับแต่ผมแนะนำให้ตั้งเอาไว้ เพราะเวลาที่เราไม่ได้ใส่ 
//line นี้จะทำให้เราสามารถใช้  team ในการหา player ได้อย่างเดียวและไม่สามารถใช้ player หา team ได้
db.player.belongsTo(db.team, { foreignKey: 'tid' });

module.exports = db;

เอาล่ะ!! เราจัดการส่วนของ Sequelize เสร็จแล้วก็กลับไปที่ Index ของเราแล้วลองใช้กันดีกว่า
/index.js ในที่นี้ผมจะทำแค่ CRUD ง่ายๆ ก่อนนะครับแล้วให้ถ้าใครอยากทำเป็น Router แยกไปก็ได้เช่นกัน

const express = require("express");
const app = express();
app.use(express.json());

const db = require('./db/index.js');
const { player, team } = db
db.sequelize.sync();

app.get('/playerInfo', async (req, res) => {
   info =  await player.findAll();
   res.json(info);
});

app.get('/playerInfo/:id', async (req, res) => {
   id =  req.params.id;
   info =  await player.findOne({
      //attributes: ['name', ['tid','team'] , 'age'], สามารถเลือกเฉพาะ attributes ที่ต้องการได้ และ ['tid','team'] เขียนเป็น sql ก็จะได้ แบบนี้ครับ tid AS team
      where: { pid: id }
   });

   if(!info){
      res.sendStatus(500);
   } else{
      res.json(info);
   }
});

app.post('/playerInfo', async (req, res) => {
   data  =  req.body.data;
   info =  await player.create({
      name: data.name,
      age: data.age,
      position: data.position,
      tid: data.tid,
   });

   if(!info){
      res.sendStatus(500);
   } else{
      res.status(200).json(info);
   }
});

app.put('/playerInfo/:id', async (req, res) => {
   id =  req.params.id;
   info =  await player.update({ position: 'ST' },{
      where: { pid: id }
   });

   if(!info){
      res.sendStatus(500);
   } else{
      res.sendStatus(200);
   }
});

app.delete('/playerInfo/:id', async (req, res) => {
   id =  req.params.id;
   info =  await player.destroy({
      where: { pid: id }
   });

   if(!info){
      res.sendStatus(500);
   } else{
      res.sendStatus(200);
   }
});


app.use((_req, res) => {
   res.sendStatus(501);
});

app.listen(3000, () =>{
   console.log("sever run on port " + 3000);
});

เรามาลองกันไปทีละอย่างเลยเริ่มที่ Read Data จาก Database (ผมแอบใส่ข้อมูลไว้บ้างแล้วนะครับ)

ต่อไปเป็นการ Create สร้าง Player คนใหม่เข้าไปใน DB นะครับ

ต่อไปเป็นการ Update Data  โดยใน Code จะเปลี่ยน Position ของ Player เป็น ST

แล้วต่อไปก็จะเป็นการ Delete ข้อมูลนั้นเอง มีตัวอย่างการใช้งานดังนี้

เป็นยังไงกับบ้างครับเพื่อนๆ หวังว่าเพื่อนจะได้รู้จักกับ Sequelize กันพอหอมปากหอมคอ เครื่องมือที่จะทำให้เราไม่ต้องเขียน SQL ยาว ๆ อีกต่อไป แต่มันยังไม่หมดเพียงเท่านี้เพื่อนสามารถไปอ่านเพิ่มเติมได้ที่ Document ของ Sequelize ได้เลยลิ้งอยู่ด้านล่างวันนี้ขอตัวลาไปก่อนสวัสดีครับบบบบ

อ่าน Document Sequelize

thapanon

Author thapanon

More posts by thapanon

เราใช้คุกกี้เพื่อพัฒนาประสิทธิภาพ และประสบการณ์ที่ดีในการใช้เว็บไซต์ของคุณ คุณสามารถศึกษารายละเอียดได้ที่ นโยบายความเป็นส่วนตัว และสามารถจัดการความเป็นส่วนตัวเองได้ของคุณได้เองโดยคลิกที่ ตั้งค่า

ตั้งค่าความเป็นส่วนตัว

คุณสามารถเลือกการตั้งค่าคุกกี้โดยเปิด/ปิด คุกกี้ในแต่ละประเภทได้ตามความต้องการ ยกเว้น คุกกี้ที่จำเป็น

ยอมรับทั้งหมด
จัดการความเป็นส่วนตัว
  • คุกกี้ที่จำเป็น
    เปิดใช้งานตลอด

    ประเภทของคุกกี้มีความจำเป็นสำหรับการทำงานของเว็บไซต์ เพื่อให้คุณสามารถใช้ได้อย่างเป็นปกติ และเข้าชมเว็บไซต์ คุณไม่สามารถปิดการทำงานของคุกกี้นี้ในระบบเว็บไซต์ของเราได้
    รายละเอียดคุกกี้

  • คุกกี้สำหรับการติดตามทางการตลาด

    ประเภทของคุกกี้ที่มีความจำเป็นในการใช้งานเพื่อการวิเคราะห์ และ นำเสนอโปรโมชัน สินค้า รวมถึงหลักสูตรฟรี และ สิทธิพิเศษต่าง ๆ คุณสามารถเลือกปิดคุกกี้ประเภทนี้ได้โดยไม่ส่งผลต่อการทำงานหลัก เว้นแต่การนำเสนอโปรโมชันที่อาจไม่ตรงกับความต้องการ
    รายละเอียดคุกกี้

บันทึกการตั้งค่า