外键,hasMany关联,对应 sql语句的 foreign key 进行表关联
hasOne
belongsTo
hasMany
belongsToMany
const A = sequelize.define('A', {});
const B = sequelize.define('B', {});
A.hasOne(B); // A 有一个 B,外键在目标模型(B)中定义 B foreignKey
A.belongsTo(B); // A 属于 B,外键在目标模型(A)中定义;A forgienKey
A.hasMany(B); // A 有多个 B 外键在目标模型(B)中定义
A.belongsToMany(B, { through: 'C' }); // A 属于多个 B , 通过联结表 C
一对一关系
hasOne 和 belongsTo 关联一起使用
有两个模型 Foo 和 Bar 拥有关联关系
Foo.hasOne(Bar)
Foo.belongsTo(Bar)
fooInstance.getBar()
fooInstance.setBar()
fooInstance.createBar()
一对多关系
hasMany he belongsTo 关联一起使用
Foo.hasMany(Bar)
Foo.belongsToMany(Bar, { through: Baz })
fooInstance.getBars()
fooInstance.countBars()
fooInstance.hasBar()
fooInstance.hasBars()
fooInstance.setBars()
fooInstance.addBar()
fooInstance.addBars()
fooInstance.removeBar()
fooInstance.removeBars()
fooInstance.createBar()
多对多关系
两个 belongsToMany 调用一起使用
超级多对多
m:n关系
https://www.sequelize.com.cn/advanced-association-concepts/advanced-many-to-many
多对多代码流程
- 创建表Foo,Bar ,设置为多对多,中间表为FooBar
- sequelize.sync();同步到数据库,就是说如果模型对应的表不存在就创建,插入数据 foo, bar
- foo.addBar(bar)
- foo 关联了一个bar,反映到数据库上面,
- 则是中间表Foo_Bar插入一条数据 INSERT INTO Foo_Bar (FooId,BarId) VALUES(1,1)
- Foo.findOne({ include: Bar })
- 数据查询,根据模型,查出Foo表的第一条数据,并带上关联表数据,
- 字段是Bars(因为是多对多,所以这里是复数形式,每一条bar包含中间表的数据字段是 FooBar ```jsx const Foo = sequelize.define(‘Foo’, { name: DataTypes.TEXT }); const Bar = sequelize.define(‘Bar’, { name: DataTypes.TEXT }); Foo.belongsToMany(Bar, { through: ‘Foo_Bar’ }); Bar.belongsToMany(Foo, { through: ‘Foo_Bar’ });
await sequelize.sync(); const foo = await Foo.create({ name: ‘foo’ }); const bar = await Bar.create({ name: ‘bar’ }); await foo.addBar(bar);// foo这条数据关联了一条bar,反映到表上则是在中间表Foo_Bar上插入一条数据 const fetchedFoo =await Foo.findOne({ include: Bar }); console.log(JSON.stringify(fetchedFoo, null, 2));
输出json
```jsx
{
"id": 1,
"name": "foo",
"Bars": [
{
"id": 1,
"name": "bar",
"Foo_Bar": {
"FooId": 1,
"BarId": 1
}
}
]
}
include
include 参数完成预先加载,翻译成sql其实就是 通过join关联子句
UserModel
数据建模,User用户模型
app/model/user.js
module.exports = app => {
const { STRING, INTEGER } = app.Sequelize;
const User = app.model.define('user', {
id: {
type: INTEGER,
autoIncrement: true,
primaryKey: true
},
name: {
type: STRING,
allowNull: false
},
password: {
type: STRING(32),
allowNull: false
}
});
// 表关联的字段
User.associate = function() {
// 一对多
app.model.User.hasMany(app.model.Diary, { foreignKey: 'user_id', targetKey: 'id'})
}
return User;
}
app/model/diary.js
module.exports = app => {
const { STRING, INTEGER } = app.Sequelize;
const Diary = app.model.define('diary', {
id: {
type: INTEGER,
autoIncrement: true,
primaryKey: true
},
title: {
type: STRING,
allowNull: false
},
content: {
type: STRING,
allowNull: false
}
});
// 表关联的字段
Diary.associate = function() {
app.model.Diary.belongsTo(app.model.User, { foreignKey: 'user_id', targetKey: 'id'})
}
return Diary;
}
controller 中调用 model
app/controller/home.js
'use strict';
const Controller = require('egg').Controller;
class HomeController extends Controller {
async index() {
const { ctx } = this;
ctx.body = 'hi, egg';
}
// 添加日志
async add() {
const { ctx } = this;
// 从前端获取post请求发来的数据
const param = ctx.request.body;
const result = await ctx.model.Diary.create({
title: param.title,
content: param.content,
user_id: 2
});
console.log('add方法', result);
if(result){
ctx.body = '创建成功';
}else{
ctx.body = '创建失败';
}
}
// 登录判断
async loginCheck() {
const { ctx } = this;
// 关联查询
// const data = await ctx.model.User.findAll({
// include: {
// model: ctx.model.Diary
// }
// });
// ctx.body = data;
// post请求传来的参数
const { name, password } = ctx.request.body;
let message = '', data = {};
// 判断数据库里面是否存在该用户
const user = await ctx.model.User.findOne({
where: {
name: name
}
});
if(!user){
message = '用户不存在';
}else if(password !== user.password){
message = '密码错误';
}else{
message = '登录成功';
data = { id: user.id };
}
ctx.body = {
message,
data
};
}
}
module.exports = HomeController;
Field ‘id’ doesn’t have a default value 解决
设置 id 为自动递增,autoIncrement