Sequelize关联表

本文介绍如何使用Sequelize ORM在Node.js环境中定义和关联数据表,具体包括两张表'system_info'和'user_system'的定义及关联方式,同时提供查询和服务层操作示例,展示如何执行原始SQL防止SQL注入。

关联表

示例:现在要关联两张表:system 跟 user_sytem,

model
'use strict';

module.exports = app => {
  const { STRING, DATE, INTEGER } = app.Sequelize;
  const system = app.model.define('system_info',
    {
      id: { type: INTEGER, primaryKey: true, autoIncrement: true },
      system_id: { type: STRING },
      name: { type: STRING },
      description: { type: STRING },
      token: { type: STRING },
      created_time: { type: DATE },
    },
    {
      freezeTableName: true,
      timestamps: false,
    });
  system.associate = () => { // 建立关联
    system.hasOne(app.model.UserSystem, {
      foreignKey: 'id', // 在 UserSystem 的外键名称
      constraints: false, // 这个属性非常重要,可以用来表示这个关联关系是否采用外键关联。在大多数情况下我们是不需要通过外键来进行数据表的物理关联的,直接通过逻辑进行关联即可;
    });
  };
  return system;
};
'use strict';

module.exports = app => {
  const { STRING, INTEGER } = app.Sequelize;
  const userSystem = app.model.define('user_system',
    {
      uid: { type: STRING, primaryKey: true },
      id: { type: INTEGER, primaryKey: true },
      system_id: { type: STRING, primaryKey: true },
    },
    {
      freezeTableName: true,
      timestamps: false,
    });
  return userSystem;
};

service:

进行查询

const systems = await ctx.model.System.findAndCountAll({
    attributes: [ 'id', 'name', 'description', 'created_time' ],
    limit,
    offset,
    include: [{
        model: ctx.model.UserSystem,
        attributes: [], // 一定需要的,不然select的列会包含进去
        where: { uid },
    }],
});

执行原始SQL,防注入

const sequelize = require('sequelize');
const sql = `select * from user where id = ? and age>?`;
await ctx.model.query(sql,
                     { replacements: [1,18],type: sequelize.QueryTypes.SELECT });
### Sequelize 关联查询的使用方法与示例 Sequelize 是一个功能强大的 ORM 框架,它允许开发者通过操作 JavaScript 对象来代替直接编写 SQL 语句,从而实现对数据库的操作。在实际开发中,关联查询是一种常见的需求,尤其是在处理复杂的数据关系时。以下将详细介绍 Sequelize 中如何进行关联查询,并提供具体的代码示例。 #### 1. 关联关系的定义 在 Sequelize 中,关联关系可以通过 `belongsTo` 和 `hasMany` 等方法来定义。例如,假设我们有两个表:`User` 和 `Post`,其中每个用户可以发布多篇文章(一对多关系)。这种关系可以通过以下方式定义: ```javascript // 定义 User 模型 const User = sequelize.define('User', { name: Sequelize.STRING, }); // 定义 Post 模型 const Post = sequelize.define('Post', { title: Sequelize.STRING, content: Sequelize.TEXT, }); // 建立关联关系 User.hasMany(Post, { foreignKey: 'userId' }); // 一个用户可以有多篇文章 Post.belongsTo(User, { foreignKey: 'userId' }); // 一篇文章属于一个用户 ``` 上述代码中,`hasMany` 表示一个用户可以有多篇文章,而 `belongsTo` 表示一篇文章属于一个用户[^2]。 #### 2. 进行关联查询 定义好关联关系后,可以通过 `include` 选项来进行关联查询。以下是几种常见的查询方式: ##### (1)获取所有文章及其对应的作者 如果需要查询所有文章,并同时获取每篇文章的作者信息,可以使用以下代码: ```javascript Post.findAll({ include: [ { model: User, attributes: ['name'], // 只获取用户的姓名字段 }, ], }).then((posts) => { console.log(JSON.stringify(posts, null, 2)); }); ``` ##### (2)根据作者名称查询相关文章 如果需要根据作者的名称查询相关的文章,可以结合 `where` 条件进行过滤: ```javascript Post.findAll({ include: [ { model: User, where: { name: { [Sequelize.Op.like]: `%${value}%` } }, // 使用模糊查询 attributes: ['name'], }, ], }).then((posts) => { console.log(JSON.stringify(posts, null, 2)); }); ``` ##### (3)获取特定用户的全部文章 如果需要查询某个用户的全部文章,可以使用以下代码: ```javascript User.findOne({ where: { id: userId }, include: [ { model: Post, attributes: ['title', 'content'], // 只获取文章的标题和内容字段 }, ], }).then((user) => { console.log(JSON.stringify(user, null, 2)); }); ``` #### 3. 注意事项 - 在定义关联关系时,确保正确设置外键(`foreignKey`),以保证查询结果的准确性。 - 如果涉及复杂的查询条件,可以使用 Sequelize 提供的 `Op` 操作符来构建动态查询条件[^1]。 - 根据实际需求选择合适的关联类型(如 `belongsTo` 或 `hasMany`),以优化查询性能。 #### 4. 性能优化 在进行关联查询时,需要注意左右连接、内外连接的性能问题。例如,在一对多关系中,通常建议从“一”的一方发起查询,而不是从“多”的一方发起查询,因为这样可以减少不必要的数据加载[^2]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值