--- lang: zh tags: backend,sequelize --- # Sequelize 初學 [官方文件](https://sequelize.org/v5/manual/getting-started.html) [別人翻譯的中文](https://itbilu.com/nodejs/npm/sequelize-docs-v5.html) :::info 搭配 Express 架設後端 Server 請看: [Express 網頁後端建立](https://hackmd.io/4Sx0rDgETyCDepeh2fmL1g) ::: ## 安裝 先安裝 sequelize ``` $ npm install --save sequelize ``` 然後根據資料庫使用不同的依賴 ``` $ npm install --save pg pg-hstore # Postgres $ npm install --save mysql2 $ npm install --save mariadb $ npm install --save sqlite3 $ npm install --save tedious # Microsoft SQL Server ``` ## 操作 ### 基本連線 ```javascript const Sequelize = require('sequelize'); const config = require('../config/database'); const sequelize = new Sequelize(config.database, config.username, config.password, { logging: console.log, host: config.host, port: config.port, dialect: 'mysql', pool: { max: 10, min: 0, idle: 30000, }, }); sequelize .authenticate() .then(() => { console.log('Connection has been established successfully.'); }) .catch((err) => { console.error('Unable to connect to the database: ', err); }); ``` + logging: 指定紀錄 log 的方式,可以指定一個 callback ### 建立 Model 想成是用 js 在寫資料庫的 scheme,寫越詳細越好 ```javascript class UserModel extends Sequelize.Model {} UserModel.init( { id: { type: Sequelize.INTEGER, primaryKey: true , autoIncrement: true }, name: { type: Sequelize.STRING, allowNull: false, defaultValue: '' }, gender:{ type: Sequelize.ENUM('male', 'female'), allowNull: false, defaultValue: 'male'}, account:{ type: Sequelize.STRING, allowNull: false } }, { sequelize: db, modelName: 'user', timestamps: false, freezeTableName: true, indexes:[{ unique: true, fields: ['account'] }] } ); ``` 第一個 Object 參數是定義欄位名稱跟型態,第二個 Object 則是一些額外參數 + sequelize: Sequelize 的 Instance,也就是連線的資料庫 + modelName: 來源 table + timestamps(default: true): 預設會加上 createdAt 跟 updatedAt 這兩個欄位 + freezeTableName(default: false): 預設會把單數欄位名稱改為複數 `user=>users` + indexes: 加入索引設定 ### 建立 Model 關聯 ```javascript MemberModel.belongsTo(MemberTypeModel, { foreignKey: "member_type_id", targetKey: "id" }); MemberModel.belongsTo(MemberDepModel, { foreignKey: "member_dep_id", targetKey: "id" }); MemberModel.belongsTo(MemberCollegeModel, { foreignKey: "member_college_id", targetKey: "id" }); ``` ※還有其他關連方法尚未深入研究 ### 同步 Model ```javascript UserModel.sync(); ``` 若是連線資料庫中沒有這張表,便會自動建立,也有一些參數可以使用,[參考官方](https://sequelize.org/master/manual/model-basics.html#model-synchronization)。 ### 取得資料 ```javascript UserModel.findAll({attributes:[...], where: {...}}); UserModel.findOne({attributes:[...], where: {...}}); UserModel.findByPk(pkValue); ``` [詳細 where 方法見官方](https://sequelize.org/v5/manual/models-usage.html#-code-findall--code----search-for-multiple-elements-in-the-database)。 + attributes: 就是 SELECT 的欄位 #### JOIN ```javascript UserModel.findAll({include: [{model:UserTypeModel, attributes:[...]}]}); ``` #### where after join ```javascript UserModel.findAll({ include: [ {model:UserTypeModel, attributes:[...]} ], where: { "$user_type.id$": 1 } }); ``` ### Model Instance [官方文件](https://sequelize.org/master/manual/model-instances.html) [Sequelize 資料寫入](https://dwatow.github.io/2018/09-24-sequelize/sequelize-CUD-of-CRUD/) ```javascript const jane = User.build({ name: "Jane" }); ``` + build: 建立 Model 實例,可以利用這個實例做到`新增,更新,刪除`,沒設定的欄位會給予預設值 + 對於 Instance 的操作是真的會反映在資料庫上的 #### Instance 新增 ```javascript await jane.save(); ``` 或是直接 ```javascript const jane = await User.create({name:"Jane"}); // 等同於 build 之後 save ``` #### Instance 更新 ```javascript jane.name = "jaja" jane.save(); ``` 若要放棄更改可以 ```javascript jane.reload(); // 可以重回最後一次 save 的狀態,事實上應該是回資料庫抓資料 ``` #### Instance 刪除 ```javascript jane.destroy(); ``` ### 批次新增 ```javascript UserModel.bulkCreate([ {name:"jane"}, {name:"jaja"}, ... ]) ``` ### 更新特定資料 ```javascript let updateDataRows = UserModel.update({name:"jane"},{where:{...}}) // 回傳被影響到的資料筆數 ``` ### 刪除特定資料 ```javascript UserModel.destroy({where:{...}}); ``` ### Migration [Sequelize Migration](https://dwatow.github.io/2018/09-24-sequelize/sequelize-migration/) ※沒太多時間研究 ### Cache ※沒太多時間研究