什么是Sequelize?
Sequelize是一個基于Promise的NodeJS ORM模塊
什么是ORM?
ORM(Object-Relational-Mapping)是對象關系映射
對象關系映射可以把JS中的類和對象,和數據庫中的表和數據進行關系映射。映射之后我們就可以直接通過類和對象來操作數據表和數據了, 就不用編寫SQL語句了,ORM有效的解決了直接在NodeJS中編寫SQL不夠直觀, 不夠高效, 容易出錯等問題。
如何映射?
- 在Sequelize中JS中的一個類(一個模型)就對應數據庫中的一張表
- 在Sequelize中JS中的一個對象就對應表中的一條數據(一條記錄)
- 在Sequelize中JS中的一個對象的屬性就對應一條數據的一個字段
|---------------------------|
| id | name | age |
| 1 | zs | 18 |
| 2 | ls | 19 |
|---------------------------|
// 1.創建一張表
cosnt 模型名稱 = Sequelize.define('表名', {id: int,name: varchar(255),age: int
})
// 2.創建一條記錄
let zs = 模型名稱.build({id: 1,name: zs,age: 18
})// 3.操作表和數據
只要是通過Sequelize定義的模型(類), 那么Sequelize就會自動給這個模型添加很多操作表和數據的方法,以后我們就可以直接通過模型操作表, 通過模型創建出來的對象操作數據。
sequelize連接數據庫
// 1.導入Sequelize
const Sequelize = require('sequelize');
// 2.配置連接信息
/*
第一個參數: 要操作的數據庫名稱
第二個參數: 數據庫用戶名
第三個參數: 數據庫密碼
第四個參數: 其它的配置信息
* */
const sequelize = new Sequelize('demo', 'root', 'root', {host: '127.0.0.1', // MySQL服務器地址port: 3306, // MySQL服務器端口號// 注意點: Sequelize不僅僅能操作MySQL還能夠操作其它類型的數據庫dialect: 'mysql', // 告訴Sequelize當前要操作的數據庫類型pool: {max: 5, // 最多有多少個連接min: 0, // 最少有多少個連接idle: 10000, // 當前連接多久沒有操作就斷開acquire: 30000, // 多久沒有獲取到連接就斷開}
});// 3.測試配置是否正確
sequelize.authenticate()
.then(()=>{console.log('ok');
})
.catch((err)=>{console.log(err);
});
什么是數據庫連接池?
默認情況下有一個人要使用數據庫,那么就必須創建一個連接,默認情況下有一個人不用數據庫了, 為了不占用資源, 那么就必須銷毀一個連接。但是頻繁的創建和銷毀連接是非常消耗服務器性能的, 所以為了提升服務器性能就有了連接池。
數據庫連接池是負責分配、管理和釋放數據庫連接,它允許應用程序重復使用一個現有的數據庫連接,而不是再重新建立一個。
sequelize創建表
- 字段說明常用屬性
- type: 字段類型
- primaryKey: 是否是主鍵
- autoIncrement: 是否自動增長
- allowNull: 是否允許為空
- unique: 是否必須唯一
- defaultValue: 默認值
- 額外配置常用屬性
- timestamps: 是否自動添加createdAt/updateAt字段
- freezeTableName: 是否禁止自動將表名修改為復用
- tableName: 是否自定義表名,一般不用
- indexes:
[ // 指定索引{name: '', // 索引名稱fields: [''], // 索引字段名稱} ]
實例:
/*
sequelize.define();
第一個參數: 用于指定表的名稱
第二個參數: 用于指定表中有哪些字段
第三個參數: 用于配置表的一些額外信息
* */
/*
注意點:
1.sequelize在根據模型創建表的時候, 會自動將我們指定的表的名稱變成復數
2.sequelize在根據模型創建表的時候, 會自動增加兩個字段 createAt/updateAt
* */
let User = sequelize.define('user', {id: {type: Sequelize.INTEGER,primaryKey: true,autoIncrement: true},name: {type: Sequelize.STRING, // varchar(255)allowNull: false,unique: true},age: {type: Sequelize.TINYINT,defaultValue: 66},gender: {type: Sequelize.ENUM(['男', '女', '妖']),defaultValue: '妖'}
}, {freezeTableName: true, // 告訴sequelize不需要自動將表名變成復數// tableName: 'student', // 自定義表名,一般不用timestamps: false, // 不需要自動創建createAt/updateAt這兩個字段indexes: [ // 指定索引{name: 'idx_age', // 索引名稱fields: ['age'], // 索引字段名稱}]
});// 注意點: 默認定義好一個模型之后并不會自動創建對應的表,我們需要通過調用連接對象的sync方法來執行同步,只有同步之后才會自動根據模型創建對應的表
sequelize.sync();
crud
增
// 下面這段代碼 = 創建對象 + save();let u = await User.create({name: 'ww',age: 18,gender: '女'});console.log(u.dataValues);
查
在sequelize中,模型就代表著表,從表中查詢數據,即從模型中查詢數據:
let u = await User.findByPk(2);console.log(u);
改
User.update({name: 'zs'
},{where: {id: 2}
})
刪
User.destroy({where: {id: 3}
});
條件查詢
let us = await User.findAll({where: {// id: 1// age: {// [Sequelize.Op.gte] : 33// },// id: 7// ------上面逗號分隔是并且關系,下面是或者關系[Sequelize.Op.or]: {age: 33,id: 7}}
});
console.log(us.map(u => u.dataValues));
分頁查詢和排序
// 分頁
let us = await User.findAll({offset: 2 // 跳過多少條數據});console.log(us.map(u => u.dataValues));let us = await User.findAll({limit: 2 // 取多少條數據});console.log(us.map(u => u.dataValues));let us = await User.findAll({offset: 2, // 跳過多少條數據limit: 2 // 取多少條數據});console.log(us.map(u => u.dataValues));// 排序let us = await User.findAll({order: [// ['id', 'desc']['age', 'desc'],['id', 'desc']]});console.log(us.map(u => u.dataValues));
Sequelize關聯查詢:
一對一
注意點:
- 只要建立了人和書的關系, 那么在查詢人的時候, 就可以把擁有的那本書也查詢出來
- 只要建立了書和人的關系, 那么在查詢書的時候, 就可以把書屬于哪個人也查詢出來
- 如果沒有建立相關的關系, 那么就不能查詢出相關的內容
User.hasOne(Book, { // hasOne 誰擁有一個誰/ 一個人擁有一本書foreignKey: 'uId',sourceKey: 'id'});Book.belongsTo(User, { // belongsTo 誰屬于一個誰 / 一本書屬于一個人foreignKey: 'uId',sourceKey: 'id'});
let u = await User.findOne({where: {id: 1},// 注意點: 只要建立了表與表之間的關系, 那么在查詢人的時候,就可以把這個人擁有的那本書也查詢出來了include: {model: Book}
});
console.log(u.dataValues.book.dataValues);let b = await Book.findOne({where: {id: 1},// 注意點: 只要建立了表與表之間的關系, 那么在查詢書的時候,就可以把這本書屬于哪一個人也查詢出來了include: {model: User}
});
console.log(b.dataValues.user.dataValues);
一對多
User.hasMany(Book, { // 一個人擁有多本書foreignKey: 'uId',sourceKey: 'id'
});
Book.belongsTo(User, { // 一本書屬于一個人foreignKey: 'uId',sourceKey: 'id'
})
// 關聯查詢
let u = await User.findOne({where: {id: 1},include: {model: Book}
});
console.log(u.dataValues.books.map(b=>b.dataValues));let b = await Book.findOne({where: {id: 3},include: {model: User}
});
console.log(b.dataValues.user.dataValues);
多對多
// 創建模型
let Student = sequelize.define('student', {id: {type: Sequelize.INTEGER,primaryKey: true,autoIncrement: true},name: {type: Sequelize.STRING, // varchar(255)allowNull: false,unique: true}
}, {freezeTableName: true, // 告訴sequelize不需要自動將表名變成復數// tableName: 'student', // 自定義表名timestamps: false // 不需要自動創建createAt/updateAt這兩個字段
});let Teacher = sequelize.define('teacher', {id: {type: Sequelize.INTEGER,primaryKey: true,autoIncrement: true},name: {type: Sequelize.STRING, // varchar(255)allowNull: false,unique: true}
}, {freezeTableName: true, // 告訴sequelize不需要自動將表名變成復數// tableName: 'student', // 自定義表名timestamps: false // 不需要自動創建createAt/updateAt這兩個字段
});let Relation = sequelize.define('relation', {studentId: {type: Sequelize.INTEGER,allowNull: false,references: {model: Student,key: 'id'}},teacherId: {type: Sequelize.INTEGER,allowNull: false,references: {model: Student,key: 'id'}}
}, {freezeTableName: true, // 告訴sequelize不需要自動將表名變成復數// tableName: 'student', // 自定義表名timestamps: false // 不需要自動創建createAt/updateAt這兩個字段
});
// 建立查詢關系
Student.belongsToMany(Teacher, { // 一個學生屬于多個老師through: Relation
});
Teacher.belongsToMany(Student, { // 一個老師屬于多個學生through: Relation
});sequelize.sync();
// 關聯查詢
/*
let s = await Student.findOne({where: {id: 1},include: {model: Teacher}
});
console.log(s.dataValues.teachers.map(t=>t.dataValues));*/
let t = await Teacher.findOne({where: {id: 1},include: {model: Student}
});
console.log(t);
Sequelize-Cli
什么是Sequelize-CLI?
- 在編程開發中為了能夠更好的管理代碼, 我們可以使用Git來管理我們的代碼,
實現對代碼變更的追蹤, 實現在各個不同版本之間切換 - 在數據庫開發中為了能夠更好的管理數據庫, 我們也可以使用數據庫遷移工具來管理我們的數據庫,
實現對數據庫變更的追蹤, 實現在各個不同版本之間切換 - Sequelize-CLI就是一款數據庫遷移工具, 能夠讓我們追蹤數據庫的變更, 在各個不同版本之間隨意切換