什么是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就是一款数据库迁移工具, 能够让我们追踪数据库的变更, 在各个不同版本之间随意切换