前言
我们在写数据的时候,如果一直使用mysql写有哪些缺点使我们没法忍的?
- sql语句写起来复杂,语句很长,写起来不方便,sql赋值困难
- 如果我们在本地写了数据库,那么发布的时候还要迁移到线上,比较麻烦
- 团队协作能力提升,如果成员A改了数据表结构,那么其他成员还要单独修改这个表结构,难以忍受
1. sequelize是什么?
Sequelize
是一个基于 Node.js 的对象关系映射 (ORM) 库。它为开发者提供了一个简单易用的接口,用于与关系型数据库(如 MySQL、PostgreSQL 和 SQLite)进行交互。
这里我们画一下重点ORM(object relational mapping)即对象关系映射,他是在对象和数据库之间提供了一座桥梁,我们在操作数据库的时候就不需要再去和复杂的 SQL 语句打交道,只需简单的操作实体对象的属性和方法,就可以达到操作数据库的效果。
这不就达到了我们的效果了么,我们根本就不想写那些复杂的SQL
,我们只想简单快速的操作。
2. 为什么要使用sequelize呢?
也就是在前言中说的那些我们在实际开发中没法忍的mysql
的痛
3. 如何使用sequelize
3.1. 创建sequelize实例
1、安装Sequelize
js
npm i --save sequelize
2、以mysql数据库为例,需要安装mysql驱动 mysql2
补充:对于Node.js程序,访问MySQL也是通过网络发送SQL命令给MySQL服务器。这个访问MySQL服务器的软件包通常称为MySQL驱动程序。)
js
npm i --save mysql2
- 创建实例:
js
const c = {
dbname: xxx // 数据库名字
user: xxx // 数据库用户名
password: xxx // 数据库密码
}
const Sequelize = require("sequelize")
const sequelize = new Sequelize(c.dbname, c.user, c.password, {
dialect: 'mysql' // 数据库类型
host: 'localhost' // 链接的主机域名
port: '端口号'
})
- 链接测试
js
sequelize.authenticate()
.then(() => {
console.log('链接成功')
}).catch(() => {
console.log("链接失败")
})
3.2 自动同步模型
这里我们使用sequlize-automate
库
js
npm install -g sequelize-automate
1. 设置sequelize-automate.coinfig.js
js
module.exports = {
dbOptions: {
database: "xxx",
username: "xxxx",
password: "123456",
dialect: "mysql",
host: "localhost",
port: 3306,
logging: false
},
options: {
type: "js",
dir: "models"
}
}
2. 设置package.json的script
js
"scripts": {
"automate": "sequelize-automate -c sequelize-automate.config.js"
},
然后npm run automate
js
const {
DataTypes
} = require('sequelize');
module.exports = sequelize => {
const attributes = {
user_id: {
type: DataTypes.INTEGER(11),
allowNull: false,
defaultValue: null,
primaryKey: true,
autoIncrement: true,
comment: null,
field: "user_id"
},
user_name: {
type: DataTypes.STRING(100),
allowNull: false,
defaultValue: null,
primaryKey: false,
autoIncrement: false,
comment: null,
field: "user_name"
},
email: {
type: DataTypes.STRING(100),
allowNull: false,
defaultValue: null,
primaryKey: false,
autoIncrement: false,
comment: null,
field: "email"
},
password: {
type: DataTypes.STRING(100),
allowNull: false,
defaultValue: null,
primaryKey: false,
autoIncrement: false,
comment: null,
field: "password"
},
create_at: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: null,
primaryKey: false,
autoIncrement: false,
comment: null,
field: "create_at"
}
};
const options = {
tableName: "user",
comment: "",
indexes: [],
};
const UserModel = sequelize.define("user_model", attributes, options);
return UserModel;
};
3. db.ts配置
js
const Sequelize = require('sequelize');
const UserModel = require('../models/user');
// Option 1: Passing parameters separately
const sequelize = new Sequelize('admin', 'root', '123456', {
host: 'localhost',
dialect: 'mysql',
define: {
timestamps: false,
paranoid: true,
underscored: true,
}
});
const User = UserModel(sequelize);
const db = {
User
}
export default db;
3.3 Sequelize 常用增删改查函数
增删改查对应的函数
sql | 函数 |
---|---|
select | findAll, findOne, findByPk(Pk:primary key), findAndCountAll |
update | update |
insert | create |
update | delete |
1,查询
1.1 查询单条数据
js
const user = await ctx.model.User.findOne({
attributes: ['id', 'name'], // 结果过滤,只显示 id,name 字段
// attributes: { exclude: ['role'] } // 不显示 role 字段
where: {
id: id
},
order: [ // 排序
['showCount', 'DESC']
]
});
// 字段重命名:查询属性(字段)可以通过传入一个嵌套数据进行重命名
attributes: ['id', ['name', 'myName']]
将字段name重命名为myName,这样返回的结果里面的字段就是myName
1.2 查询多条数据
js
const user = await ctx.model.User.findAll({
limit: 10, //每页10条
offset: 0*10, //第x页*每页个数
where: {} // 条件
});
1.3 分页查询
js
// 返回列表的总数
const { app, ctx } = this;
const { gt } = app.Sequelize.Op;
const user = await ctx.model.User.findAndCountAll({
limit: 10, //每页10条
offset: 0*10, //第x页*每页个数
where: { // 条件
id: {
[gt]: 6 // id > 6
}
}
});
1.4 通过id查询
js
const user = await ctx.model.User.findByPk(1);
1.5 查询单个数据
js
const user = await ctx.model.User.findOne({
where: {} // 条件
});
1.6 分组查询
分组查询通常要与聚合函数一起使用,聚合函数包括:
聚合函数 | 功能 |
---|---|
COUNT | 用于统计记录条数 |
SUM | 用于计算字段的值的总和 |
AVG | 用于计算字段的值的平均值 |
MAX | 用于查找查询字段的最大值 |
MIX | 用于查找查询字段的最小值 |
js
// 求表中num字段值的和
const { app, ctx } = this;
const { fn, col } = app.Sequelize;
// fn 指的是函数
// col 指的是字段
const user = await ctx.model.User.findOne({
attributes: [[fn('SUM', col('num')), 'all_num']]
where: {} // 条件
});
sql语句:select sum('num') as 'all_count' ...
2,新增
js
// 如果id为自增的主键,那么新增数据时候不需要添加id
const user = await ctx.model.User.create({ name, age });
3,修改
js
// 修改之前先判断这条数据是否存在
const user = await ctx.model.User.findByPk(id);
// 如果数据存在,再修改
await user.update({ name, age }, {
where: {}
});
4,删除
csharp
// 删除之前先判断这条数据是否存在
const user = await ctx.model.User.findByPk(id);
// 如果数据存在,再修改
await user.destroy();
3.4 如何同步数据库
要同步数据库,请使用 sequelize.sync()
方法。它会根据您的模型创建数据库表。如果您希望强制重新创建数据库表,可以使用 { force: true }
选项。
例如:
js
sequelize.sync({ force: true }).then(() => { console.log("数据库同步成功"); });
同步数据库可能会遇到一下问题
arduino
Invalid default value for 'user_name'
当在使用Sequelize
同步模型时遇到 "Invalid default value" 错误,并且错误信息指向 'user_name' 字段时,通常是由于您在模型中对该字段的默认值设置不符合数据库的要求。
这个时候可以把字段的defaultValue
设置为undefined
,或者直接删除掉defaultValue
这个属性