如何在Sequelize中实现同一模型的多对多自关联
在Sequelize中实现Category表的自关联
要实现分类的自关联(比如"女装""男装"关联到"服饰"),你需要给category表添加父级外键字段,再通过Sequelize的关联方法建立双向关系,具体步骤如下:
1. 调整表结构:新增父级ID字段
首先给category表添加parentId字段,作为外键指向自身的Id字段。顶级分类(如"服饰")的parentId设为null,子分类(如"女装")的parentId设为对应父分类的Id。
2. 定义Sequelize模型并配置自关联
创建Category模型时,先初始化字段,再通过belongsTo和hasMany建立双向自关联:
const { Model, DataTypes } = require('sequelize'); const sequelize = require('../path/to/your/db/connection'); // 替换为你的数据库连接实例 class Category extends Model {} Category.init({ Id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true }, name: { type: DataTypes.STRING, allowNull: false }, image: { type: DataTypes.STRING, allowNull: true }, parentId: { type: DataTypes.INTEGER, references: { model: 'category', // 关联的数据库表名 key: 'Id' }, allowNull: true, // 顶级分类无父级,允许为null onUpdate: 'CASCADE', onDelete: 'SET NULL' // 父分类删除时,子分类的parentId自动设为null } }, { sequelize, modelName: 'Category', tableName: 'category', // 指定对应数据库表名 timestamps: false // 不需要默认时间戳字段可关闭 }); // 子分类属于一个父分类 Category.belongsTo(Category, { as: 'parent', // 查询时的别名,用于区分父分类数据 foreignKey: 'parentId' }); // 父分类拥有多个子分类 Category.hasMany(Category, { as: 'children', // 查询时的别名,用于区分子分类列表 foreignKey: 'parentId' }); module.exports = Category;
3. 关联查询示例
配置好关联后,可按需查询包含父/子分类的数据:
- 查询所有分类并附带父分类信息:
const categoriesWithParent = await Category.findAll({ include: [{ model: Category, as: 'parent' }] });
- 查询所有顶级分类,并附带它们的子分类:
const topLevelCategories = await Category.findAll({ where: { parentId: null }, include: [{ model: Category, as: 'children' }] });
4. 已有表的迁移操作(可选)
如果category表已存在,可通过Sequelize迁移添加parentId字段:
'use strict'; module.exports = { up: async (queryInterface, Sequelize) => { await queryInterface.addColumn('category', 'parentId', { type: Sequelize.INTEGER, references: { model: 'category', key: 'Id' }, onUpdate: 'CASCADE', onDelete: 'SET NULL', allowNull: true }); }, down: async (queryInterface, Sequelize) => { await queryInterface.removeColumn('category', 'parentId'); } };
内容的提问来源于stack exchange,提问作者Flutter Dev
相关产品推荐
相关产品推荐

