关于Sequelize
在一些较为复杂的应用中,我们可能会需要一个ORM框架来帮助我们管理数据层的代码。
而在 Node.js 社区中,sequelize 是一个广泛使用的 ORM 框架,它支持 MySQL、SQLite 和 MSSQL 、PostgreSQL 等多个数据源。
相关文档
- https://eggjs.org/zh-cn/tutorials/sequelize.html
- https://sequelize.org/
Sequelize 操作 Mysql 数据库
安装 egg-sequelize 以及 mysql2
$ npm i --save egg-sequelize mysql2
在 config/plugin.js 中引入 egg-sequelize 插件
exports.sequelize = {
enable: true,
package: 'egg-sequelize',
};
在 config/config.default.js 中编写 sequelize 配置
config.sequelize = {
dialect: 'mysql',
host: '127.0.0.1',
port: 3306,
database: 'test',
username:"root",
password:"123456"
};
Sequelize 操作 Mysql 实现增删改查
1.在 app/model/ 目录下编写数据库 Model, 以用户表 user 为例
'use strict';
module.exports = app => {
const { STRING, INTEGER, DATE } = app.Sequelize;
const User = app.model.define('user', {
id: { type: INTEGER, primaryKey: true, autoIncrement: true },
name: STRING(255),
age: INTEGER,
created_at: DATE,
updated_at: DATE,
});
return User;
};
或
'use strict';
module.exports = app => {
const { STRING, INTEGER, DATE } = app.Sequelize;
const User = app.model.define('user', {
id: { type: INTEGER, primaryKey: true, autoIncrement: true },
name: STRING(30),
age: INTEGER,
created_at: DATE,
updated_at: DATE,
},{
freezeTableName: true,
tableName: 'user_info', // 指定表名
timestamps: false, // 表示:不自动增加创建时间
});
return User;
};
注意:这里定义的model是user,对应数据库的表名就应该是users 复数的形式,第二种方式是自定义指定表名
2、定义 controller 实现数据库的增删改查
async index() {
const ctx = this.ctx;
// ctx.body = await ctx.model.User.findAll();
ctx.body = await ctx.model.User.findAll({limit: 10, offset: 0, order:[["id","desc"]]});
// 指定返回的字段
//ctx.body = await ctx.model.User.findAll({attributes: ['id', 'name'], limit: 10, order:[["id","desc"]]});
// 查询条件
//ctx.body = await ctx.model.User.findAll({attributes: ['id', 'name'], order:[["id","desc"]], where:{id:1}});
}
async findOne() {
const ctx = this.ctx;
var result = await ctx.model.User.findByPk(1); // 根据主键来查找数据
ctx.body=result || '';
}
async create() {
const ctx = this.ctx;
const user = await ctx.model.User.create({ name:"张三", age:20 });
ctx.status = 201;
ctx.body = user;
}
async update() {
const ctx = this.ctx;
const id = 1;
const user = await ctx.model.User.findByPk(id);
if (!user) {
ctx.status = 404;
return;
}
await user.update({ name:"李四", age:43 });
ctx.body = user;
}
async destroy() {
const ctx = this.ctx;
const id = 3;
const user = await ctx.model.User.findByPk(id);
if (!user) {
ctx.status = 404;
return;
}
await user.destroy();
ctx.status = 200;
ctx.body="删除成功";
}
Sequelize 操作多表关联查询
注:图片托管于github,请确保网络的可访问性
1 对 1 hasOne 或者 belongsTo
文章和文章分类的关系是:一对一的关系,一篇文章对应一个分类,使用 hasOne
, belongsTo
app/model/article.js
'use strict';
module.exports = app => {
const { STRING, INTEGER, DATE } = app.Sequelize;
const Article = app.model.define('article', {
id: { type: INTEGER, primaryKey: true, autoIncrement: true },
title: STRING(255),
description: INTEGER,
cateId:STRING(30),
state: DATE
},{
timestamps: false,
tableName: 'article'
});
Article.associate = function (){
// 1对1
app.model.Article.belongsTo(app.model.ArticleCate, {foreignKey: 'cateId'}); // cateId 是 Article 表的外键
}
return Article;
};
app/controller/article.js
//查询数据 1对1
async index() {
const { ctx } = this;
let result = await ctx.model.Article.findAll({
include: {
model: ctx.model.ArticleCate
}
});
ctx.body = result;
}
一对多 hasMany
文章分类和文章的关系是:一对多的关系,一篇文章对应一个分类,使用 hasMany
app/model/article_cate.js
'use strict';
module.exports = app => {
const { STRING, INTEGER, DATE } = app.Sequelize;
const ArticleCate = app.model.define('article_cate', {
id: { type: INTEGER, primaryKey: true, autoIncrement: true },
title: STRING(255),
state: INTEGER
},{
timestamps: false, //关闭时间戳
tableName: 'article_cate' //配置表名称
});
ArticleCate.associate = function (){
// 如果是 1对1 的话就像是下面这样写
// app.model.ArticleCate.hasOne(app.model.Article, {foreignKey: 'cateId'});
// 文章分类与文章是 1对多,应该这样
app.model.ArticleCate.hasMany(app.model.Article, {foreignKey: 'cateId'});
}
return ArticleCate;
};
app/controller/article.js
//查询数据 1对多
async index() {
const { ctx } = this;
let result = await ctx.model.ArticleCate.findAll({
include: {
model: ctx.model.Article
}
});
ctx.body = result;
}
多对多 belongsToMany
有三张表:其中两张表:课程表和学生表;另外一张关联表:学生课程的关联表
app/model/lesson.js
'use strict';
module.exports = app => {
const { INTEGER, STRING } = app.Sequelize;
const Lesson = app.model.define('lesson', {
id: {
type: INTEGER,
primaryKey: true,
autoIncrement: true
},
name: {
type: STRING,
allowNull: false
}
},{
timestamps: false,
tableName: 'lesson'
});
Lesson.associate = function () {
//一个学生可以选修多门课程
//一门课程可以被多个学生选修
app.model.Lesson.belongsToMany(app.model.Student, {
through: app.model.LessonStudent,
foreignKey: 'lessonId',//注意写法
otherKey: 'studentId'
});
}
return Lesson;
}
app/model/student.js
'use strict';
module.exports = app => {
const { STRING, INTEGER } = app.Sequelize;
const Student = app.model.define('student', {
id: {
type: INTEGER,
autoIncrement: true,
primaryKey: true
},
name: {
type: STRING,
},
number: {
type: STRING,
allowNull: false,
},
password: {
type: STRING(32),
allowNull: false
}
}, {
timestamps: false,
tableName: 'student'
});
Student.associate = function () {
//一个学生可以选修多门课程
app.model.Student.belongsToMany(app.model.Lesson, {
through: app.model.LessonStudent, // through 关联表
foreignKey: 'studentId',// 注意写法 驼峰
otherKey: 'lessonId'
});
}
return Student;
}
app/model/lesson_student.js
'use strict';
module.exports = app => {
const { INTEGER } = app.Sequelize;
const LessonStudent = app.model.define('lesson_student', {
lessonId: {
type: INTEGER,
primaryKey: true
},
studentId: {
type: INTEGER,
primaryKey: true
}
},{
timestamps: false,
tableName: 'lesson_student'
});
// LessonStudent.associate = function(){
// }
return LessonStudent;
}
控制器 app/controller/test.js 查询语句:
async index() {
const { ctx } = this;
// 查询课程有哪些学生选修:
// let result = await ctx.model.Lesson.findAll({
// include: {
// model: ctx.model.Student
// }
// });
// 查询每个学生选修了哪些课程
let result = await ctx.model.Student.findAll({
include: {
model: ctx.model.Lesson
}
});
ctx.body = result;
}
Sequelize 常见的数据类型
Sequelize.STRING | VARCHAR(255) |
Sequelize.STRING(1234) | VARCHAR(1234) |
Sequelize.STRING.BINARY | VARCHAR BINARY |
Sequelize.TEXT | TEXT |
Sequelize.TEXT('tiny') | TINYTEXT |
Sequelize.INTEGER | INTEGER |
Sequelize.BIGINT | BIGINT |
Sequelize.BIGINT(11) | BIGINT(11) |
Sequelize.FLOAT | FLOAT |
Sequelize.FLOAT(11) | FLOAT(11) |
Sequelize.FLOAT(11, 12) | FLOAT(11,12) |
Sequelize.DOUBLE | DOUBLE |
Sequelize.DOUBLE(11) | DOUBLE(11) |
Sequelize.DOUBLE(11, 12) | DOUBLE(11,12) |
Sequelize.DECIMAL | DECIMAL |
Sequelize.DECIMAL(10, 2) | DECIMAL(10,2) |
Sequelize.DATE | DATETIME 针对 mysql / sqlite; TIMESTAMP, WITH TIME ZONE 针对 postgres |
Sequelize.DATE(6) | // DATETIME(6) 针对 mysql 5.6.4+. 小数秒支持多达6位精度 |
Sequelize.DATEONLY | DATE 不带时间 |
Sequelize.BOOLEAN | TINYINT(1) |