ORM 與 Sequelize


Posted by ericcch24 on 2021-05-16

什麼是 ORM? Object Relational Mapping

  • 用程式裡面的物件對應到資料庫的資料,就不需要用到 SQL 指令,用 ORM 的指令就可以直接對資料庫的資料做 CRUD。

Sequelize 實際示範

更多 query 使用方法參考:sequelize 官方文件

const Sequelize  = require('sequelize');

// 與資料庫連線
const sequelize = new Sequelize('ericcch24', 'ericcch24', 'zxc124040219', {
  host: 'localhost',
  dialect: 'mysql'
})

// Model Definition 建立資料格式
const User = sequelize.define('User', {
  firstName: {
    type: Sequelize.STRING,
    allowNull: false
  },
  lastName: {
    type: Sequelize.STRING
  }
}, {
});


// Model synchronization 與資料庫同步
// You can use sequelize.sync() to 
// automatically synchronize all models.

sequelize.sync().then(() => {
  User.findAll().then(users => {
    console.log(users[0].id, users[0].firstName)
  }) // 查詢資料
})



// 建立資料
sequelize.sync().then(() => {
  User.create({
    firstName: 'bbbbb',
    lastName: 'bbbb'
  }).then(() => {
    console.log('created!')
  })
})

資料庫關聯 Association

// 建立另一個 model,這邊是留言內容
const Comment = sequelize.define('commentsql', {
  content: {
    type: Sequelize.STRING,
    allowNull: false
  }
});

// 建立關聯
User.hasMany(Comment) 
// 一個 User 可以有很多個 Comment,這邊會在 Comment 加上一欄 userId, 
// ORM 會用這欄 userId 來對兩個 table 做關聯
// userId 也可以改成想要的名稱,查文件
Comment.belongsTo(User)
// 因為 hasMany 只有單向關係,所以 comment 要關聯回去 user 還要用 belongsTo


// 從 user 找到對應的 comment
sequelize.sync().then(() => {
  Comment.create({ 
  // 在 comment 新增內容,可以對應到 User 的 ID
    UserId: 3, 
    content: 'yyyoyoo'
  }).then(() => {
    console.log('done')
  })
  User.findOne({
    where: {
      firstName: 'John'
    },
    include: Comment 
    // 把 user 底下加上 comment include,
    // 就可以拿對應到的資料
  }).then(user => {
    console.log(JSON.stringify(user.commentsqls, null, 4)) 
    // 可以拿到該 user 所對應到的 commentsql 的資料
  })
})


// 從 comment 找到對應的 user
sequelize.sync().then(() => {
  Comment.findOne({
    where: {
      content: 'hello'
    },
    include: User  
    //把 comment 底下加上 user include,
    //就可以拿對應到的資料
  }).then(comment => {
    console.log(JSON.stringify(comment.User.firstName, null, 4)) 
    // 可以從 comment 拿到對應的 user
  })
})

Sequelize CLI

參考資料:migrations

  • 方便管理用,讓程式碼更有結構
  1. config.json: 資料庫的連線設定
  2. model:generate 來建立 model 與 migration 檔案(以下指令擇一使用):
    • 指令 1:npx sequelize-cli model:generate --name User --attributes firstName:string,lastName:string,email:string
    • 指令 2:./node_modules/.bin/sequelize model:generate --name User --attributes firstName:string,lastName:string,email:string
      User 是 model 名稱,習慣用大寫,會在 model 資料夾建立 user.js 檔案。
  3. migration 資料夾會有負責紀錄資料庫的改動紀錄的檔案,執行npx sequelize-cli db:migrate指令後才會真正建立資料庫。
  4. 在剛剛建立的 models 的檔案建立關聯
    'use strict';
    const {
    Model
    } = require('sequelize');
    module.exports = (sequelize, DataTypes) => {
    class User extends Model {
     /**
      * Helper method for defining associations.
      * This method is not a part of Sequelize lifecycle.
      * The `models/index` file will call this method automatically.
      */
     static associate(models) {
       User.hasMany(models.Comment) // 這邊寫關聯的部分
     }
    };
    User.init({
     firstName: DataTypes.STRING,
     lastName: DataTypes.STRING,
     email: DataTypes.STRING
    }, {
     sequelize,
     modelName: 'User',
    });
    return User;
    };
    
    5.最後就可以從外部的 index.js 來引入 model,可以直接操作資料庫
    ```javascript=
    const db = require('./models')
    const User = db.User
    const Comment = db.Comment

User.create({
firstName: 'poop',
lastName: 'Stan'
}).then(() => {
console.log('good')
})


* 所以不需要用前面的 sync() 來控制資料庫,可以用 migration。

---

## W17 檢討範例 async await
[還有其他部分參考:第十七週檢討範例](https://github.com/Lidemy/mentor-program-4th/tree/master/examples/week17)

在用 Promise 的時候你通常都是在一個 function 裡面,所以這樣寫是沒有用的:
```javascript=
function handle(req, res) {
  User.findBy({
    id: 1
  }).then(user => {
    if(!user) {
      res.redirect('/')
      return
    }
  }).then(user => {
    // 這邊還是會執行到
    User.create()
  })
}

因為 promise chaining 的特性,所以最後的那個 .then 還是會執行到,你寫的 return 是你傳進去 then 的那個 function 的 return,不是 handle 的 return。

這邊建議大家改用 async await,程式碼簡單好懂:

async function handle(req, res) {
  const user = await User.findBy({
    id: 1
  })

  if(!user) {
    res.redirect('/')
    return
  }

  User.create()
}
tags: Week17

#week17







Related Posts

什麼是 Pure Function?在 React 當中的重要性是什麼?

什麼是 Pure Function?在 React 當中的重要性是什麼?

swap用法

swap用法

比較 innerText, textContent, innerHTML

比較 innerText, textContent, innerHTML


Comments