NodeJS的sequelize操作数据库(三)

1,405 阅读3分钟

这是我参与11月更文挑战的第17天,活动详情查看:2021最后一次更文挑战

一. 简单建立模型实例

Sequelize提供了incrementdecrement 实例方法

二. 数值的递增和递减整实现

const jane = await User.create({ name: "李华", age: 100 });
const incrementResult = await jane.increment('age', { by: 2 });
// 注意: 如只增加 1, 你可以省略 'by' 参数, 只需执行 `user.increment('age')`

// 在 PostgreSQL 中, 除非设置了 `{returning:false}` 参数(不然它将是 undefined),
// 否则 `incrementResult` 将是更新后的 user.

// 在其它数据库方言中, `incrementResult` 将会是 undefined. 如果你需要更新的实例, 你需要调用 `user.reload()`.
  • 多个字段递增
const jane = await User.create({ name: "Jane", age: 100, cash: 5000 });
await jane.increment({
  'age': 2,
  'cash': 100
});

// 如果值增加相同的数量,则也可以使用以下其他语法:
await jane.increment(['age', 'cash'], { by: 2 });

三. 模型增删改查(CRUD)

创建(create)

1. Model.create()方法是使用 Model.build()构建未保存实例并使用instance.save()保存实例的简写形式.

// 创建一个新用户
const user = await User.create({ firstName: "李华", lastName: "李小龙" });

2. fields参数只影响到该范围内的字段

const user = await User.create({
  username: '李华',
  is_auth: true
}, { fields: ['username'] });
// 假设 isAdmin 的默认值为 false
console.log(user.username); // '李华'
console.log(user.is_auth); // false

查询(select)

// 查询所有用户
const users = await User.findAll(); // 相当于 SELECT * FROM users

1. 查询特定属性

User.findAll({
  attributes: ['username', 'age']
});

2. 嵌套数组重命名字段

User.findAll({
  attributes: ['age', ['username', 'name']]
});

3. 聚合查询的sequelize.fn

  • 使用聚合函数时,必须为它提供一个别名,以便能够从模型中访问它
Model.findAll({
  attributes: [
    'id', 'display', 'margin', 'width', 'height', 'padding', // 我们必须列出所有属性...
    [sequelize.fn('COUNT', sequelize.col('margin')), 'n_margin'] // 添加聚合...
  ]
});

// 这个设计更简单
Model.findAll({
  attributes: {
    include: [
      [sequelize.fn('COUNT', sequelize.col('margin')), 'n_margin']
    ]
  }
});
  • 查询exclude排除某些属性更方便
Model.findAll({
  attributes: { exclude: ['width'] }
});

四. 原始查询

执行原始SQL查询,使用 sequelize.query 方法.

默认情况下,函数将返回两个参数一个结果数组,以及一个包含元数据(例如受影响的行数等)的对象.

const [results, metadata] = await sequelize.query("UPDATE users SET y = 42 WHERE x = 12");
// 结果将是一个空数组,元数据将包含受影响的行数.

在不需要访问元数据的情况下,可以传递一个查询类型来告诉后续如何格式化结果. 例如,对于一个简单的选择查询:

const { QueryTypes } = require('sequelize');
const users = await sequelize.query("SELECT * FROM `users`", { type: QueryTypes.SELECT });
// 不需要在这里分解结果 - 结果会直接返回

第二种选择是模型. 如果传递模型,返回的数据将是该模型的实例.

// Callee 是模型定义. 将查询映射到预定义的模型
const projects = await sequelize.query('SELECT * FROM projects', {
  model: Projects,
  mapToModel: true // 如果有任何映射字段,则在这里传递 true
});
// 现在,`projects` 的每个元素都是 Project 的一个实例

1. 替换

查询中的替换可以通过两种不同的方式完成:

  • 使用命名参数(以:开头)
  • 表示的未命名参数. 替换在options对象中传递.
    • 如果传递一个数组, ? 将按照在数组中出现的顺序被替换
    • 如果传递一个对象, :key 将替换为该对象的键. 如果对象包含在查询中找不到的键,则会抛出异常

2. 绑定参数

绑定参数就像替换. 除非替换被转义并在查询发送到数据库之前通过后续插入到查询中,而将绑定参数发送到SQL查询文本之外的数据库.

查询可以具有绑定参数或替换.绑定参数由 $1, $2, ... (numeric) 或 $key (alpha-numeric) 引用.

  • 如果传递一个数组Arry, $1 被绑定到数组中的第一个元素 (bind[0]).
  • 如果传递一个对象Object, $key 绑定到 object['key']. 每个键必须以非数字字符开始. $1 不是一个有效的键,即使 object['1'] 存在.
  • 在这两种情况下 $$ 可以用来转义一个 $ 字符符号.

数组或对象必须包含所有绑定的值,或者Sequelize将抛出异常,数据库可能有要求. 绑定参数不能是SQL关键字,也不能是表或列名.