准备工作
sequelize文章涉及多部分信息,具体细节参考右边目录。
为了演示 sequelize 的多表间关联关系,首先我先准备两个实体:user 、role。
1. 初始化 sequelize 连接
const { Sequelize, DataTypes } = require('sequelize');
const sequelize = new Sequelize({
host: '127.0.0.1',
port: 3306,
username: 'root',
password: 'mypassword',
database: 'sequelize-db',
dialect: 'mysql',
logging: console.log,
});
2. 定义实体
const User = sequelize.define(
'user',
{
name: DataTypes.STRING,
},
{
tableName: 'user_t',
timestamps: false,
},
);
const Role = sequelize.define(
'role',
{
name: DataTypes.STRING,
},
{
tableName: 'role_t',
timestamps: false,
// 不想要 createdAt
createdAt: false,
// 想要 updatedAt 但是希望名称叫做 updateTimestamp
updatedAt: 'updateTimestamp',
},
);
// 如果表不存在,则创建该表
sequelize.sync();
关联关系
一对一
一对一
说明一个 user 只拥有一个 role, 从数据库的角度看,只需要在 role 表中存储 user 的主键就可以形成关联了。
// 1. 基本版
User.hasOne(Role);
Role.belongsTo(User);
// 2. 自定义关联外键
User.hasOne(Role, {
foreignKey: 'user_id'
});
Role.belongsTo(User);
// 3. 自定义关联外键
User.hasOne(Role);
Role.belongsTo(User,{
foreignKey:{
name: 'user_id',
type: DataTypes.UUID
}
});
一对多
一对多
与一对一
的设置有些类似,只要了解怎么去设置外键,修改对应 Api 即可。
// 1. 基本版
User.hasMany(Role);
Role.belongsTo(User);
// 2. 自定义关联外键
User.hasMany(Role, {
foreignKey: 'user_id'
});
Role.belongsTo(User);
// 3. 自定义关联外键
User.hasMany(Role);
Role.belongsTo(User,{
foreignKey:{
name: 'user_id',
type: DataTypes.UUID
}
});
可以从 ER图中看出,一对一,一对多 的表结构基本一致。
多对多
1. 基础版
User.belongsToMany(Role, { through: 'User_Role' });
Role.belongsToMany(User, { through: 'User_Role' });
2. 自定义关联外键
const UserRole = sequelize.define('UserRole', {
userId: {
type: DataTypes.INTEGER,
references: {
model: User, // 'User' 也可以使用
key: 'id',
},
},
roleId: {
type: DataTypes.INTEGER,
references: {
model: Role, // 'Role' 也可以使用
key: 'id',
},
},
});
Role.belongsToMany(User, { through: 'UserRole' });
User.belongsToMany(Role, { through: 'UserRole' });
关联查询
预先加载
await User.findOne({ include: Role });
延迟加载
//1. 先查询 user
let user = await User.findOne({ where: 1 });
// 2. 再关联查询 role
let role = await user.getRole();
参考文档:sequelize中文文档