如何通过Nodejs Sequelize手册从快速入门到实际应用?

2026-04-02 08:441阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计5496个文字,预计阅读时间需要22分钟。

如何通过Nodejs Sequelize手册从快速入门到实际应用?

目录

1.连接数据库(js/ts)

2.数据库模型

1. 模型定义 2. 时间戳(timestamps) 3. 生成模型 4. 定义数据库操作符 4. 增删改查(CRUD) 1. 增加 - Tips:对应原生SQL语句讲解 - findOrCreate 2. 查询 - 可选

目录
  • 1.连接数据库(js/ts)
  • 2.数据库模型
    • 1.模型定义
      • 时间戳(timestamps)
    • 2.生成模型
    • 3.对应数据库操作符的定义
      • 4. 增删改查(CRUD)
        • 1. 增加
          • Tips:对应原生sql语句讲解
          • findOrCreate
        • 2. 查询
          • 可选查询参数
          • 简单查询
          • 关联查询
          • 关联类型
          • 子查询
        • 3. 更新 update
          • 4. 删除destroy
          • 5. 托管事务(transaction)

            1.连接数据库(js/ts)

            // config.js exports const config = { database: { database: 'management', host: 'localhost', port: 3306, user: 'root', password: '12345678' } }

            // db.js const Sequelize = require('sequelize'); import { config } from './config'; const { database, host, port, user, password } = config; const sequelize = new Sequelize(database, user, password, { dialect: 'mysql', host, port, logging: true, // logging: true, 打印sql到控制台 timezone: '+08:00', //时间上的统一,这里是东八区,默认为0时区 define: { //全局的定义,会通过连接实例传递 // timestamps: false, //默认情况下,Sequelize 使用数据类型 DataTypes.DATE 自动向每个模 型添加 createdAt 和 updatedAt 字段. 这些字段会自动进行管理 - 每当 你使用Sequelize 创建或更新内容时,这些字段都会被自动设置. createdAt 字段将包含代表创建时刻的时间戳,而 updatedAt 字段将包含 最新更新的时间戳. //对于带有timestamps: false 参数的模型,可以禁用此行为 // createdAt: 'created_at', //自定义时间戳 // updatedAt: 'updated_at', // paranoid: true, // deletedAt: 'deleted_at', //paranoid表示在被告之要删除记录时并不会真正的物理上删除,而 是添加一个存有删除请求时间戳deletedAt的特殊字段。传递 paranoid: true参数给模型定义中。paranoid要求必须启用时间戳, 即必须传timestamps: true // 把驼峰命名转换为下划线 //underscored: false, pool: { // 使用连接池 max: 5, // 连接池中最大连接数量 min: 0, // 连接池中最小连接数量 acquire: 30000, idle: 10000 // 如果一个线程 10 秒钟内没有被使用过的话,那么就释放线程 }, } }) // 测试数据库链接 sequelize .authenticate() .then(() => { console.log('数据库连接成功'); }) .catch((err: any) => { // 数据库连接失败时打印输出 console.error(err); throw err; }); export default sequelize; // 将连接对象暴露出去

            2.数据库模型

            1.模型定义

            调用sequelize.define(modelName, attributes, options)

            const User = sequelize.define('User', { // 在这里定义模型属性 id: { type: DataTypes.INTEGER, autoIncrement: true, //允许自增 primaryKey: true } firstName: { type: DataTypes.STRING, allowNull: false }, lastName: { type: DataTypes.STRING // allowNull 默认为 true } }, { // 这是其他模型参数 sequelize, // 我们需要传递连接实例 //局部的定义 modelName: 'User' // 我们需要选择模型名称 // 不要忘记启用时间戳! timestamps: true, // 不想要 createdAt createdAt: false, // 想要 updatedAt 但是希望名称叫做 updateTimestamp updatedAt: 'updateTimestamp' }); // `sequelize.define` 会返回模型 console.log(User === sequelize.models.User); // true

            时间戳(timestamps)

            默认情况下,Sequelize 使用数据类型 DataTypes.DATE 自动向每个模型添加 createdAtupdatedAt 字段. 这些字段会自动进行管理 - 每当你使用Sequelize 创建或更新内容时,这些字段都会被自动设置. createdAt 字段将包含代表创建时刻的时间戳,而 updatedAt 字段将包含最新更新的时间戳.

            对于带有 timestamps: false 参数的模型,可以禁用此行为,要启用createdAt,updatedAt必须要 timestamps: true

            sequelize.define('User', { // ... (属性) }, { timestamps: false });

            也可以只启用 createdAt/updatedAt 之一,并为这些列提供自定义名称:

            class Foo extends Model {} Foo.init({ /* 属性 */ }, { sequelize, // 不要忘记启用时间戳! timestamps: true, // 不想要 createdAt createdAt: false, // 想要 updatedAt 但是希望名称叫做 updateTimestamp updatedAt: 'updateTimestamp' });

            2.生成模型

            1.全局安装sequelize-automysql2

            npm install -g mysql2 npm install -g sequelize-auto

            2. 运行以下命令

            利用sequelize-auto对照数据库自动生成相应的models,sequelize-auto官方文档地址:github.com/sequelize/s…

            //sequelize-auto -h "数据库地址" -d "数据库名" -u "用户名" -x "密码" -p "端口号" --dialect mysql sequelize-auto -o "./model" -d test -h 127.0.0.1 -u root -p 3306 -x 123456 -e mysql Options: --help Show help [boolean] --version Show version number [boolean] -h, --host IP/Hostname for the database. [string] -d, --database Database name. [string] -u, --user Username for database. [string] -x, --pass Password for database. If specified without providing a password, it will be requested interactively from the terminal. -p, --port Port number for database (not for sqlite). Ex: MySQL/MariaDB: 3306, Postgres: 5432, MSSQL: 1433 [number] -c, --config Path to JSON file for Sequelize-Auto options and Sequelize's constructor "options" flag object as defined here: sequelize.org/master/class/lib/sequelize.js~Sequelize.html#instance-constructor-constructor [string] -o, --output What directory to place the models. [string] -e, --dialect The dialect/engine that you're using: postgres, mysql, sqlite, mssql [string] -a, --additional Path to JSON file containing model options (for all tables). See the options: sequelize.org/master/class/lib/model.js~Model.html#static-method- init [string] --indentation Number of spaces to indent [number] -t, --tables Space-separated names of tables to import [array] -T, --skipTables Space-separated names of tables to skip [array] --caseModel, --cm Set case of model names: c|l|o|p|u c = camelCase l = lower_case o = original (default) p = PascalCase u = UPPER_CASE --caseProp, --cp Set case of property names: c|l|o|p|u --caseFile, --cf Set case of file names: c|l|o|p|u|k k = kebab-case --noAlias Avoid creating alias `as` property in relations [boolean] --noInitModels Prevent writing the init-models file [boolean] -n, --noWrite Prevent writing the models to disk [boolean] -s, --schema Database schema from which to retrieve tables[string] -v, --views Include database views in generated models [boolean] -l, --lang Language for Model output: es5|es6|esm|ts es5 = ES5 CJS modules (default) es6 = ES6 CJS modules esm = ES6 ESM modules ts = TypeScript [string] --useDefine Use `sequelize.define` instead of `init` for es6|esm|ts --singularize, --sg Singularize model and file names from plural table names [boolean]

            3.对应数据库操作符的定义

            const { Op } = sequelize; [Op.and]: {a: 5} // 且 (a = 5) [Op.or]: [{a: 5}, {a: 6}] // (a = 5 或 a = 6) [Op.gt]: 6, // id > 6 [Op.gte]: 6, // id >= 6 [Op.lt]: 10, // id < 10 [Op.lte]: 10, // id <= 10 [Op.ne]: 20, // id != 20 [Op.eq]: 3, // = 3 [Op.not]: true, // 不是 TRUE [Op.between]: [6, 10], // 在 6 和 10 之间 [Op.notBetween]: [11, 15], // 不在 11 和 15 之间 [Op.in]: [1, 2], // 在 [1, 2] 之中 [Op.notIn]: [1, 2], // 不在 [1, 2] 之中 [Op.like]: '%hat', // 包含 '%hat' [Op.notLike]: '%hat' // 不包含 '%hat' [Op.iLike]: '%hat' // 包含 '%hat' (不区分大小写) (仅限 PG) [Op.notILike]: '%hat' // 不包含 '%hat' (仅限 PG) [Op.regexp]: '^[h|a|t]' // 匹配正则表达式/~ '^[h|a|t]' (仅限 MySQL/PG) [Op.notRegexp]: '^[h|a|t]' // 不匹配正则表达式/!~ '^[h|a|t]' (仅限 MySQL/PG) [Op.iRegexp]: '^[h|a|t]' // ~* '^[h|a|t]' (仅限 PG) [Op.notIRegexp]: '^[h|a|t]' // !~* '^[h|a|t]' (仅限 PG) [Op.like]: { [Op.any]: ['cat', 'hat']} // 包含任何数组['cat', 'hat'] - 同样适用于 iLike 和 notLike [Op.overlap]: [1, 2] // && [1, 2] (PG数组重叠运算符) [Op.contains]: [1, 2] // @> [1, 2] (PG数组包含运算符) [Op.contained]: [1, 2] // <@ [1, 2] (PG数组包含于运算符) [Op.any]: [2,3] // 任何数组[2, 3]::INTEGER (仅限PG) [Op.col]: 'user.organization_id' // = 'user'.'organization_id', 使用数据库语言特定的列标识符, 本例使用

            $and: {a: 5} // AND (a = 5) $or: [{a: 5}, {a: 6}] // (a = 5 OR a = 6) $gt: 6, // > 6 $gte: 6, // >= 6 $lt: 10, // < 10 $lte: 10, // <= 10 $ne: 20, // != 20 $not: true, // IS NOT TRUE $between: [6, 10], // BETWEEN 6 AND 10 $notBetween: [11, 15], // NOT BETWEEN 11 AND 15 $in: [1, 2], // IN [1, 2] $notIn: [1, 2], // NOT IN [1, 2] $like: '%hat', // LIKE '%hat' $notLike: '%hat' // NOT LIKE '%hat' $iLike: '%hat' // ILIKE '%hat' (case insensitive) (PG only) $notILike: '%hat' // NOT ILIKE '%hat' (PG only) $like: { $any: ['cat', 'hat']} // LIKE ANY ARRAY['cat', 'hat'] - also works for iLike and notLike $overlap: [1, 2] // && [1, 2] (PG array overlap operator) $contains: [1, 2] // @> [1, 2] (PG array contains operator) $contained: [1, 2] // <@ [1, 2] (PG array contained by operator) $any: [2,3] // ANY ARRAY[2, 3]::INTEGER (PG only) $col: 'user.organization_id' // = "user"."organization_id", with dialect specific column identifiers, PG in this example

            //or操作符的两种使用 order_status=0 or order_status=1 params['$or'] = [{ order_status: 0 }, { order_status: 1 }]; params['order_status'] = { $or: [ { $eq: 0 }, { $eq: 1 } ] }

            4. 增删改查(CRUD)

            1. 增加

            create

            向数据库中添加单条记录。

            const User = sequelize.import('./model/user'); //导入模型 const user = await User.create({ username: 'alice123', isAdmin: true });

            bulkCreate

            批量创建,通过接收数组对象而不是单个对象。

            await User.bulkCreate([ { username: 'foo', pwd:"123"}, { username: 'bar', pwd:"345"} ], { updateOnDuplicate: true, fields: ['username','pwd','address'] });

            updateOnDuplicate: 如果行键已存在是否更新。数据库表中现有的记录的唯一索引或者主键如果已经存在,执行更新操作(true表示更新,false表示不更新。 默认为更新)

            fields: 要定义字段的数组(其余字段将被忽略),用来限制实际插入的列。

            Tips:对应原生sql语句讲解

            在MySQL数据库中,如果在insert语句后面带上ON DUPLICATE KEY UPDATE 子句。

            • 要插入的行与表中现有记录的惟一索引或主键中产生重复值,那么就会发生旧行的更新;
            • 如果插入的行数据与现有表中记录的唯一索引或者主键不重复,则执行新纪录插入操作。

            findOrCreate

            除非找到一个满足查询参数的结果,否则方法 findOrCreate 将在表中创建一个条目. 在这两种情况下,它将返回一个实例(找到的实例或创建的实例)和一个布尔值,指示该实例是已创建还是已经存在.

            使用 where 参数来查找条目,而使用 defaults 参数来定义必须创建的内容. 如果 defaults 不包含每一列的值,则 Sequelize 将采用 where 的值(如果存在).

            const [user, created] = await User.findOrCreate({ where: { username: '123' }, defaults: { job: 'Technical Lead JavaScript' } }); console.log(user.username); // 'sdepold' console.log(user.job); // 这可能是也可能不是 'Technical Lead JavaScript' console.log(created); // 指示此实例是否刚刚创建的布尔值 if (created) { console.log(user.job); // 这里肯定是 'Technical Lead JavaScript' }

            2. 查询

            可选查询参数

            const result = await Goods.findAll({ attributes: [ 'goodsId', [sequelize.fn('SUM', sequelize.col('order_count')), 'order_count'], [sequelize.fn('SUM', sequelize.col('total_price_sum')), 'total_price_sum'], [sequelize.fn('SUM', sequelize.col('goods_cost')), 'goods_cost'], [sequelize.fn('COUNT', sequelize.col('goodsId')), 'goods_count'] ], where: params, limit: 10, offset:0, raw: true, group: [sequelize.col('goodsId')], })

            1. attributes

            如果只需要查询模型的部分属性,可以在通过在查询选项中指定attributes实现,如[colName1,colName2,colName3......]

            当需要查询所有字段并对某一字段使用聚合查询时,而只需要以对象的形式传入attributes并添加include子属性即可。

            // 指定全查询字段比较麻烦 Model.findAll({ attributes: ['id', 'foo', 'bar', 'baz', 'quz', [sequelize.fn('COUNT', sequelize.col('hats')), 'hats_count']] }); // 这样会比较简短,且在你添加/删除属性后不会出错 Model.findAll({ attributes: { include: [[sequelize.fn('COUNT', sequelize.col('hats')), 'hats_count']] } });

            全部查询时,可以通过exclude子属性来排除不需要查询的字段:

            Model.findAll({ attributes: { exclude: ['baz'] } });

            为列取一个别名:

            attributes数组里面添加一项 [ oldColName , newColName ] 或者 [ sequelize.col('oldColName') , newColName ]

            通过sequelize.fn方法可以进行聚合查询:

            如常用的SUMCOUNT等。

            2. where

            在模型的 findOne/finAllupdate/destroy 操作中,可以指定一个where选项以指定筛选条件,where是一个包含属性/值对对象,sequelize会根据此对象生产查询语句的筛选条件。

            where:{ //查询 username='admin' pwd ='123456' user_status=0 or user_status=1 username: 'admin', pwd:"123456", user_status:{ [Op.or]: [ { $eq: 0 }, { $eq: 1 } ] } }

            可以配合符操作来做复杂的筛选条件。

            3. limitoffset

            查询进,我们可以使用limit限制返回结果条数,并可以通过offset来设置查询偏移(跳过)量,通过这两个属性我们可以实现分页查询的功能:

            Model.findAll({ limit: 10 }) // 获取 10 条数据(实例) Model.findAll({ offset: 8 }) // 跳过 8 条数据(实例) Model.findAll({ offset: 5, limit: 5 }) // 跳过 5 条数据并获取其后的 5 条数据(实例) //使用场景,分页请求数据 const page = parseInt(params.page || 1); const limit = parseInt(params.limit || 10); const currentPage = (page - 1) * limit; Model.findAll({ limit, offset: currentPage, })

            4. raw

            { raw: true }作为参数传递给 finder时,可以对查询的结果集禁用包装。

            5. order

            order 参数采用一系列 项 来让 sequelize 方法对查询进行排序. 这些 项 本身是 [column, direction] 形式的数组. 该列将被正确转义,并且将在有效方向列表中进行验证(例如 ASC, DESC, NULLS FIRST 等).

            Model.findAll({ order: [ //sequelize.col('date') 有时候可以使用sequelize.col()指定列,防止在子查询或者关联查询时找不到列名 [sequelize.col('date'), 'DESC'], ['date', 'DESC'], // 将转义 title 并针对有效方向列表进行降序排列 ['title', 'DESC'], // 将按最大年龄进行升序排序 sequelize.fn('max', sequelize.col('age')), // 将按最大年龄进行降序排序 [sequelize.fn('max', sequelize.col('age')), 'DESC'], // 将按 otherfunction(`col1`, 12, 'lalala') 进行降序排序 [sequelize.fn('otherfunction', sequelize.col('col1'), 12, 'lalala'), 'DESC'], // 将使用模型名称作为关联名称按关联模型的 createdAt 排序. [Task, 'createdAt', 'DESC'], // 将使用模型名称作为关联名称通过关联模型的 createdAt 排序. [Task, Project, 'createdAt', 'DESC'], // 将使用关联名称按关联模型的 createdAt 排序. ['Task', 'createdAt', 'DESC'], // 将使用关联的名称按嵌套的关联模型的 createdAt 排序. ['Task', 'Project', 'createdAt', 'DESC'], // 将使用关联对象按关联模型的 createdAt 排序. (首选方法) [Subtask.associations.Task, 'createdAt', 'DESC'], // 将使用关联对象按嵌套关联模型的 createdAt 排序. (首选方法) [Subtask.associations.Task, Task.associations.Project, 'createdAt', 'DESC'], // 将使用简单的关联对象按关联模型的 createdAt 排序. [{model: Task, as: 'Task'}, 'createdAt', 'DESC'], // 将由嵌套关联模型的 createdAt 简单关联对象排序. [{model: Task, as: 'Task'}, {model: Project, as: 'Project'}, 'createdAt', 'DESC'] ], // 将按最大年龄降序排列 order: sequelize.literal('max(age) DESC'), // 如果忽略方向,则默认升序,将按最大年龄升序排序 order: sequelize.fn('max', sequelize.col('age')), // 如果省略方向,则默认升序, 将按年龄升序排列 order: sequelize.col('age'), // 将根据方言随机排序(但不是 fn('RAND') 或 fn('RANDOM')) order: sequelize.random() }); Model.findOne({ order: [ // 将返回 `name` ['name'], // 将返回 `username` DESC ['username', 'DESC'], // 将返回 max(`age`) sequelize.fn('max', sequelize.col('age')), // 将返回 max(`age`) DESC [sequelize.fn('max', sequelize.col('age')), 'DESC'], // 将返回 otherfunction(`col1`, 12, 'lalala') DESC [sequelize.fn('otherfunction', sequelize.col('col1'), 12, 'lalala'), 'DESC'], // 将返回 otherfunction(awesomefunction(`col`)) DESC, 这种嵌套可能是无限的! [sequelize.fn('otherfunction', sequelize.fn('awesomefunction', sequelize.col('col'))), 'DESC'] ] });

            order 数组的元素可以如下:

            一个字符串 (它将被自动引用)

            一个数组, 其第一个元素将被引用,第二个将被逐字追加

            一个具有raw字段的对象:

            • raw 内容将不加引用地逐字添加
            • 其他所有内容都将被忽略,如果未设置 raw,查询将失败

            调用 Sequelize.fn (这将在 SQL 中生成一个函数调用)

            调用 Sequelize.col (这将引用列名)

            6. group

            分组和排序的语法相同,只是分组不接受方向作为数组的最后一个参数(不存在 ASC, DESC, NULLS FIRST 等).

            还可以将字符串直接传递给 group,该字符串将直接(普通)包含在生成的 SQL 中.

            Model.findAll({ group: 'name' }); Model.findAll({ group: [sequelize.col('date'),sequelize.col('id')] //可以指定多个列进行分组 }); // 生成 'GROUP BY name'

            Tips:在做分组和排序的时候可以使用sequelize.col()指定列,防止在子查询或者关联查询时找不到列名

            7. include

            include关键字表示关联查询

            简单查询

            1. findOne

            findOne 方法获得它找到的第一个条目(它可以满足提供的可选查询参数).

            &nbsp;const user = await User.findOne({ where: { username: 'admin' } });

            2.findAll

            该查询将从表中检索所有条目(除非受到 where 子句的限制).

            const user = await User.findAll({ where: { username: 'admin' },raw:true });

            3.findAndCountAll,findAndCount

            findAndCountAll 方法是结合了 findAllcount 的便捷方法. 在处理与分页有关的查询时非常有用,在分页中,你想检索带有 limitoffset 的数据,但又需要知道与查询匹配的记录总数.

            当没有提供 group 时, findAndCountAll 方法返回一个具有两个属性的对象:

            • count : 一个整数 - 与查询匹配的记录总数
            • rows :一个数组对象 - 获得的记录

            当提供了 group 时, findAndCountAll 方法返回一个具有两个属性的对象:

            • count - 一个数组对象 - 包含每组中的合计和预设属性
            • rows - 一个数组对象 - 获得的记录

            const { count, rows } = await User.findAndCountAll({ where: { username: { [Op.like]: '%foo%' } }, offset: 10, //查询偏移(跳过)量 limit: 2 //限制返回结果条数 });

            关联查询

            let result = await Goods.findAndCount({ include: [ { attributes: [[sequelize.col('title'), 'goods_name']], association: Goods.belongsTo(tbGoods, { targetKey: 'goodsId', foreignKey: 'goodsId' , as:'goods_name_info'}), model: Goods, required: false, where: params2, } ], where: params, limit, offset: currentPage, raw: true, order: [ [sequelize.col('date'), 'DESC'], ] })

            关联类型

            A.hasOne(B, { /* 参数 */ }); // A 有一个 B A.belongsTo(B, { /* 参数 */ }); // A 属于 B A.hasMany(B, { /* 参数 */ }); // A 有多个 B A.belongsToMany(B, { through: 'C', /* 参数 */ }); // A 属于多个 B , 通过联结表 C

            association

            as指定连接的别名

            where

            关联中也支持where子句。

            required

            如何通过Nodejs Sequelize手册从快速入门到实际应用?

            false,表示左外连接(LEFT OUTER JOIN),左表全部出现在结果集中,若右表无对应记录,则相应字段为NULL

            true,表示内连接(INNER JOIN),满足条件的记录才会出现在结果集中。

            子查询

            Tips:由于 sequelize.literal 会插入任意内容而不进行转义

            //根据goodsId 去匹配 goods_order对应的 goods_name let result = await goods_roi.findAll({ attributes: [ 'goodsId', [sequelize.fn('SUM', sequelize.col('order_count')), 'order_count'], [sequelize.fn('SUM', sequelize.col('total_price_sum')), 'total_price_sum'], [sequelize.fn('SUM', sequelize.col('goods_cost')), 'goods_cost'], [ sequelize.literal(`( SELECT item_title FROM goods_order AS goods_order WHERE goods_order.item_id = goods_roi.goodsId limit 1 )`), 'goods_name' ] ], where: params, raw: true, group: [sequelize.col('goodsId')] })

            实用方法 countmaxminsumincrement, decrement

            count 方法仅计算数据库中元素出现的次数

            const amount = await Model.count({ where: { id: { [Op.gt]: 25 } } }); console.log(`这有 ${amount} 个记录 id 大于 25`);

            max, minsum

            假设我们有三个用户,分别是10、5和40岁

            await User.max('age'); // 40 await User.max('age', { where: { age: { [Op.lt]: 20 } } }); // 10 await User.min('age'); // 5 await User.min('age', { where: { age: { [Op.gt]: 5 } } }); // 10 await User.sum('age'); // 55 await User.sum('age', { where: { age: { [Op.gt]: 5 } } }); // 50

            increment自增, decrement自减

            await User.increment({age: 5}, { where: { id: 1 } }) // 将年龄增加到15岁 await User.increment({age: -5}, { where: { id: 1 } }) // 将年龄降至5岁

            3. 更新 update

            update查询也接受 where 参数

            *// 将所有没有姓氏的人更改为 "Doe"* await User.update({ lastName: "Doe" }, { where: { lastName: null } });

            4. 删除destroy

            destroy查询也接受 where 参数

            *// 删除所有名为 "Jane" 的人* await User.destroy({ where: { firstName: "Jane" } });

            5. 托管事务(transaction)

            Sequelize 支持两种使用事务的方式:

            • 托管事务: 如果引发任何错误,Sequelize 将自动回滚事务,否则将提交事务. 另外,如果启用了CLS(连续本地存储),则事务回调中的所有查询将自动接收事务对象.
            • 非托管事务: 提交和回滚事务应由用户手动完成(通过调用适当的 Sequelize 方法).

            托管事务会自动处理提交或回滚事务. 通过将回调传递给 sequelize.transaction 来启动托管事务. 这个回调可以是 async(通常是)的.

            在这种情况下,将发生以下情况:

            • Sequelize 将自动开始事务并获得事务对象 t
            • 然后,Sequelize 将执行你提供的回调,并在其中传递 t
            • 如果你的回调抛出错误,Sequelize 将自动回滚事务
            • 如果你的回调成功,Sequelize 将自动提交事务

            只有这样,sequelize.transaction调用才会解决:

            • 解决你的回调的决议
            • 或者,如果你的回调引发错误,则拒绝并抛出错误

            try { const result = await sequelize.transaction(async (t) => { const user = await User.create({ firstName: 'Abraham', lastName: 'Lincoln' }, { transaction: t }); //{transaction: t} 必须作为第二个对象里的参数传递 return user; }); // 如果执行到此行,则表示事务已成功提交,`result`是事务返回的结果 // `result` 就是从事务回调中返回的结果(在这种情况下为 `user`) } catch (error) { // 如果执行到此,则发生错误. // 该事务已由 Sequelize 自动回滚! }

            注意:t.commit()t.rollback() 没有被直接调用.

            自动将事务传递给所有查询:在上面的示例中,仍然通过传递 { transaction: t } 作为第二个参数来手动传递事务.

            以上为js版本,部分不适用于ts,ts要根据具体的官方文档使用。

            以上就是Nodejs Sequelize手册学习快速入门到应用的详细内容,更多关于Nodejs Sequelize入门手册的资料请关注自由互联其它相关文章!

            本文共计5496个文字,预计阅读时间需要22分钟。

            如何通过Nodejs Sequelize手册从快速入门到实际应用?

            目录

            1.连接数据库(js/ts)

            2.数据库模型

            1. 模型定义 2. 时间戳(timestamps) 3. 生成模型 4. 定义数据库操作符 4. 增删改查(CRUD) 1. 增加 - Tips:对应原生SQL语句讲解 - findOrCreate 2. 查询 - 可选

            目录
            • 1.连接数据库(js/ts)
            • 2.数据库模型
              • 1.模型定义
                • 时间戳(timestamps)
              • 2.生成模型
              • 3.对应数据库操作符的定义
                • 4. 增删改查(CRUD)
                  • 1. 增加
                    • Tips:对应原生sql语句讲解
                    • findOrCreate
                  • 2. 查询
                    • 可选查询参数
                    • 简单查询
                    • 关联查询
                    • 关联类型
                    • 子查询
                  • 3. 更新 update
                    • 4. 删除destroy
                    • 5. 托管事务(transaction)

                      1.连接数据库(js/ts)

                      // config.js exports const config = { database: { database: 'management', host: 'localhost', port: 3306, user: 'root', password: '12345678' } }

                      // db.js const Sequelize = require('sequelize'); import { config } from './config'; const { database, host, port, user, password } = config; const sequelize = new Sequelize(database, user, password, { dialect: 'mysql', host, port, logging: true, // logging: true, 打印sql到控制台 timezone: '+08:00', //时间上的统一,这里是东八区,默认为0时区 define: { //全局的定义,会通过连接实例传递 // timestamps: false, //默认情况下,Sequelize 使用数据类型 DataTypes.DATE 自动向每个模 型添加 createdAt 和 updatedAt 字段. 这些字段会自动进行管理 - 每当 你使用Sequelize 创建或更新内容时,这些字段都会被自动设置. createdAt 字段将包含代表创建时刻的时间戳,而 updatedAt 字段将包含 最新更新的时间戳. //对于带有timestamps: false 参数的模型,可以禁用此行为 // createdAt: 'created_at', //自定义时间戳 // updatedAt: 'updated_at', // paranoid: true, // deletedAt: 'deleted_at', //paranoid表示在被告之要删除记录时并不会真正的物理上删除,而 是添加一个存有删除请求时间戳deletedAt的特殊字段。传递 paranoid: true参数给模型定义中。paranoid要求必须启用时间戳, 即必须传timestamps: true // 把驼峰命名转换为下划线 //underscored: false, pool: { // 使用连接池 max: 5, // 连接池中最大连接数量 min: 0, // 连接池中最小连接数量 acquire: 30000, idle: 10000 // 如果一个线程 10 秒钟内没有被使用过的话,那么就释放线程 }, } }) // 测试数据库链接 sequelize .authenticate() .then(() => { console.log('数据库连接成功'); }) .catch((err: any) => { // 数据库连接失败时打印输出 console.error(err); throw err; }); export default sequelize; // 将连接对象暴露出去

                      2.数据库模型

                      1.模型定义

                      调用sequelize.define(modelName, attributes, options)

                      const User = sequelize.define('User', { // 在这里定义模型属性 id: { type: DataTypes.INTEGER, autoIncrement: true, //允许自增 primaryKey: true } firstName: { type: DataTypes.STRING, allowNull: false }, lastName: { type: DataTypes.STRING // allowNull 默认为 true } }, { // 这是其他模型参数 sequelize, // 我们需要传递连接实例 //局部的定义 modelName: 'User' // 我们需要选择模型名称 // 不要忘记启用时间戳! timestamps: true, // 不想要 createdAt createdAt: false, // 想要 updatedAt 但是希望名称叫做 updateTimestamp updatedAt: 'updateTimestamp' }); // `sequelize.define` 会返回模型 console.log(User === sequelize.models.User); // true

                      时间戳(timestamps)

                      默认情况下,Sequelize 使用数据类型 DataTypes.DATE 自动向每个模型添加 createdAtupdatedAt 字段. 这些字段会自动进行管理 - 每当你使用Sequelize 创建或更新内容时,这些字段都会被自动设置. createdAt 字段将包含代表创建时刻的时间戳,而 updatedAt 字段将包含最新更新的时间戳.

                      对于带有 timestamps: false 参数的模型,可以禁用此行为,要启用createdAt,updatedAt必须要 timestamps: true

                      sequelize.define('User', { // ... (属性) }, { timestamps: false });

                      也可以只启用 createdAt/updatedAt 之一,并为这些列提供自定义名称:

                      class Foo extends Model {} Foo.init({ /* 属性 */ }, { sequelize, // 不要忘记启用时间戳! timestamps: true, // 不想要 createdAt createdAt: false, // 想要 updatedAt 但是希望名称叫做 updateTimestamp updatedAt: 'updateTimestamp' });

                      2.生成模型

                      1.全局安装sequelize-automysql2

                      npm install -g mysql2 npm install -g sequelize-auto

                      2. 运行以下命令

                      利用sequelize-auto对照数据库自动生成相应的models,sequelize-auto官方文档地址:github.com/sequelize/s…

                      //sequelize-auto -h "数据库地址" -d "数据库名" -u "用户名" -x "密码" -p "端口号" --dialect mysql sequelize-auto -o "./model" -d test -h 127.0.0.1 -u root -p 3306 -x 123456 -e mysql Options: --help Show help [boolean] --version Show version number [boolean] -h, --host IP/Hostname for the database. [string] -d, --database Database name. [string] -u, --user Username for database. [string] -x, --pass Password for database. If specified without providing a password, it will be requested interactively from the terminal. -p, --port Port number for database (not for sqlite). Ex: MySQL/MariaDB: 3306, Postgres: 5432, MSSQL: 1433 [number] -c, --config Path to JSON file for Sequelize-Auto options and Sequelize's constructor "options" flag object as defined here: sequelize.org/master/class/lib/sequelize.js~Sequelize.html#instance-constructor-constructor [string] -o, --output What directory to place the models. [string] -e, --dialect The dialect/engine that you're using: postgres, mysql, sqlite, mssql [string] -a, --additional Path to JSON file containing model options (for all tables). See the options: sequelize.org/master/class/lib/model.js~Model.html#static-method- init [string] --indentation Number of spaces to indent [number] -t, --tables Space-separated names of tables to import [array] -T, --skipTables Space-separated names of tables to skip [array] --caseModel, --cm Set case of model names: c|l|o|p|u c = camelCase l = lower_case o = original (default) p = PascalCase u = UPPER_CASE --caseProp, --cp Set case of property names: c|l|o|p|u --caseFile, --cf Set case of file names: c|l|o|p|u|k k = kebab-case --noAlias Avoid creating alias `as` property in relations [boolean] --noInitModels Prevent writing the init-models file [boolean] -n, --noWrite Prevent writing the models to disk [boolean] -s, --schema Database schema from which to retrieve tables[string] -v, --views Include database views in generated models [boolean] -l, --lang Language for Model output: es5|es6|esm|ts es5 = ES5 CJS modules (default) es6 = ES6 CJS modules esm = ES6 ESM modules ts = TypeScript [string] --useDefine Use `sequelize.define` instead of `init` for es6|esm|ts --singularize, --sg Singularize model and file names from plural table names [boolean]

                      3.对应数据库操作符的定义

                      const { Op } = sequelize; [Op.and]: {a: 5} // 且 (a = 5) [Op.or]: [{a: 5}, {a: 6}] // (a = 5 或 a = 6) [Op.gt]: 6, // id > 6 [Op.gte]: 6, // id >= 6 [Op.lt]: 10, // id < 10 [Op.lte]: 10, // id <= 10 [Op.ne]: 20, // id != 20 [Op.eq]: 3, // = 3 [Op.not]: true, // 不是 TRUE [Op.between]: [6, 10], // 在 6 和 10 之间 [Op.notBetween]: [11, 15], // 不在 11 和 15 之间 [Op.in]: [1, 2], // 在 [1, 2] 之中 [Op.notIn]: [1, 2], // 不在 [1, 2] 之中 [Op.like]: '%hat', // 包含 '%hat' [Op.notLike]: '%hat' // 不包含 '%hat' [Op.iLike]: '%hat' // 包含 '%hat' (不区分大小写) (仅限 PG) [Op.notILike]: '%hat' // 不包含 '%hat' (仅限 PG) [Op.regexp]: '^[h|a|t]' // 匹配正则表达式/~ '^[h|a|t]' (仅限 MySQL/PG) [Op.notRegexp]: '^[h|a|t]' // 不匹配正则表达式/!~ '^[h|a|t]' (仅限 MySQL/PG) [Op.iRegexp]: '^[h|a|t]' // ~* '^[h|a|t]' (仅限 PG) [Op.notIRegexp]: '^[h|a|t]' // !~* '^[h|a|t]' (仅限 PG) [Op.like]: { [Op.any]: ['cat', 'hat']} // 包含任何数组['cat', 'hat'] - 同样适用于 iLike 和 notLike [Op.overlap]: [1, 2] // && [1, 2] (PG数组重叠运算符) [Op.contains]: [1, 2] // @> [1, 2] (PG数组包含运算符) [Op.contained]: [1, 2] // <@ [1, 2] (PG数组包含于运算符) [Op.any]: [2,3] // 任何数组[2, 3]::INTEGER (仅限PG) [Op.col]: 'user.organization_id' // = 'user'.'organization_id', 使用数据库语言特定的列标识符, 本例使用

                      $and: {a: 5} // AND (a = 5) $or: [{a: 5}, {a: 6}] // (a = 5 OR a = 6) $gt: 6, // > 6 $gte: 6, // >= 6 $lt: 10, // < 10 $lte: 10, // <= 10 $ne: 20, // != 20 $not: true, // IS NOT TRUE $between: [6, 10], // BETWEEN 6 AND 10 $notBetween: [11, 15], // NOT BETWEEN 11 AND 15 $in: [1, 2], // IN [1, 2] $notIn: [1, 2], // NOT IN [1, 2] $like: '%hat', // LIKE '%hat' $notLike: '%hat' // NOT LIKE '%hat' $iLike: '%hat' // ILIKE '%hat' (case insensitive) (PG only) $notILike: '%hat' // NOT ILIKE '%hat' (PG only) $like: { $any: ['cat', 'hat']} // LIKE ANY ARRAY['cat', 'hat'] - also works for iLike and notLike $overlap: [1, 2] // && [1, 2] (PG array overlap operator) $contains: [1, 2] // @> [1, 2] (PG array contains operator) $contained: [1, 2] // <@ [1, 2] (PG array contained by operator) $any: [2,3] // ANY ARRAY[2, 3]::INTEGER (PG only) $col: 'user.organization_id' // = "user"."organization_id", with dialect specific column identifiers, PG in this example

                      //or操作符的两种使用 order_status=0 or order_status=1 params['$or'] = [{ order_status: 0 }, { order_status: 1 }]; params['order_status'] = { $or: [ { $eq: 0 }, { $eq: 1 } ] }

                      4. 增删改查(CRUD)

                      1. 增加

                      create

                      向数据库中添加单条记录。

                      const User = sequelize.import('./model/user'); //导入模型 const user = await User.create({ username: 'alice123', isAdmin: true });

                      bulkCreate

                      批量创建,通过接收数组对象而不是单个对象。

                      await User.bulkCreate([ { username: 'foo', pwd:"123"}, { username: 'bar', pwd:"345"} ], { updateOnDuplicate: true, fields: ['username','pwd','address'] });

                      updateOnDuplicate: 如果行键已存在是否更新。数据库表中现有的记录的唯一索引或者主键如果已经存在,执行更新操作(true表示更新,false表示不更新。 默认为更新)

                      fields: 要定义字段的数组(其余字段将被忽略),用来限制实际插入的列。

                      Tips:对应原生sql语句讲解

                      在MySQL数据库中,如果在insert语句后面带上ON DUPLICATE KEY UPDATE 子句。

                      • 要插入的行与表中现有记录的惟一索引或主键中产生重复值,那么就会发生旧行的更新;
                      • 如果插入的行数据与现有表中记录的唯一索引或者主键不重复,则执行新纪录插入操作。

                      findOrCreate

                      除非找到一个满足查询参数的结果,否则方法 findOrCreate 将在表中创建一个条目. 在这两种情况下,它将返回一个实例(找到的实例或创建的实例)和一个布尔值,指示该实例是已创建还是已经存在.

                      使用 where 参数来查找条目,而使用 defaults 参数来定义必须创建的内容. 如果 defaults 不包含每一列的值,则 Sequelize 将采用 where 的值(如果存在).

                      const [user, created] = await User.findOrCreate({ where: { username: '123' }, defaults: { job: 'Technical Lead JavaScript' } }); console.log(user.username); // 'sdepold' console.log(user.job); // 这可能是也可能不是 'Technical Lead JavaScript' console.log(created); // 指示此实例是否刚刚创建的布尔值 if (created) { console.log(user.job); // 这里肯定是 'Technical Lead JavaScript' }

                      2. 查询

                      可选查询参数

                      const result = await Goods.findAll({ attributes: [ 'goodsId', [sequelize.fn('SUM', sequelize.col('order_count')), 'order_count'], [sequelize.fn('SUM', sequelize.col('total_price_sum')), 'total_price_sum'], [sequelize.fn('SUM', sequelize.col('goods_cost')), 'goods_cost'], [sequelize.fn('COUNT', sequelize.col('goodsId')), 'goods_count'] ], where: params, limit: 10, offset:0, raw: true, group: [sequelize.col('goodsId')], })

                      1. attributes

                      如果只需要查询模型的部分属性,可以在通过在查询选项中指定attributes实现,如[colName1,colName2,colName3......]

                      当需要查询所有字段并对某一字段使用聚合查询时,而只需要以对象的形式传入attributes并添加include子属性即可。

                      // 指定全查询字段比较麻烦 Model.findAll({ attributes: ['id', 'foo', 'bar', 'baz', 'quz', [sequelize.fn('COUNT', sequelize.col('hats')), 'hats_count']] }); // 这样会比较简短,且在你添加/删除属性后不会出错 Model.findAll({ attributes: { include: [[sequelize.fn('COUNT', sequelize.col('hats')), 'hats_count']] } });

                      全部查询时,可以通过exclude子属性来排除不需要查询的字段:

                      Model.findAll({ attributes: { exclude: ['baz'] } });

                      为列取一个别名:

                      attributes数组里面添加一项 [ oldColName , newColName ] 或者 [ sequelize.col('oldColName') , newColName ]

                      通过sequelize.fn方法可以进行聚合查询:

                      如常用的SUMCOUNT等。

                      2. where

                      在模型的 findOne/finAllupdate/destroy 操作中,可以指定一个where选项以指定筛选条件,where是一个包含属性/值对对象,sequelize会根据此对象生产查询语句的筛选条件。

                      where:{ //查询 username='admin' pwd ='123456' user_status=0 or user_status=1 username: 'admin', pwd:"123456", user_status:{ [Op.or]: [ { $eq: 0 }, { $eq: 1 } ] } }

                      可以配合符操作来做复杂的筛选条件。

                      3. limitoffset

                      查询进,我们可以使用limit限制返回结果条数,并可以通过offset来设置查询偏移(跳过)量,通过这两个属性我们可以实现分页查询的功能:

                      Model.findAll({ limit: 10 }) // 获取 10 条数据(实例) Model.findAll({ offset: 8 }) // 跳过 8 条数据(实例) Model.findAll({ offset: 5, limit: 5 }) // 跳过 5 条数据并获取其后的 5 条数据(实例) //使用场景,分页请求数据 const page = parseInt(params.page || 1); const limit = parseInt(params.limit || 10); const currentPage = (page - 1) * limit; Model.findAll({ limit, offset: currentPage, })

                      4. raw

                      { raw: true }作为参数传递给 finder时,可以对查询的结果集禁用包装。

                      5. order

                      order 参数采用一系列 项 来让 sequelize 方法对查询进行排序. 这些 项 本身是 [column, direction] 形式的数组. 该列将被正确转义,并且将在有效方向列表中进行验证(例如 ASC, DESC, NULLS FIRST 等).

                      Model.findAll({ order: [ //sequelize.col('date') 有时候可以使用sequelize.col()指定列,防止在子查询或者关联查询时找不到列名 [sequelize.col('date'), 'DESC'], ['date', 'DESC'], // 将转义 title 并针对有效方向列表进行降序排列 ['title', 'DESC'], // 将按最大年龄进行升序排序 sequelize.fn('max', sequelize.col('age')), // 将按最大年龄进行降序排序 [sequelize.fn('max', sequelize.col('age')), 'DESC'], // 将按 otherfunction(`col1`, 12, 'lalala') 进行降序排序 [sequelize.fn('otherfunction', sequelize.col('col1'), 12, 'lalala'), 'DESC'], // 将使用模型名称作为关联名称按关联模型的 createdAt 排序. [Task, 'createdAt', 'DESC'], // 将使用模型名称作为关联名称通过关联模型的 createdAt 排序. [Task, Project, 'createdAt', 'DESC'], // 将使用关联名称按关联模型的 createdAt 排序. ['Task', 'createdAt', 'DESC'], // 将使用关联的名称按嵌套的关联模型的 createdAt 排序. ['Task', 'Project', 'createdAt', 'DESC'], // 将使用关联对象按关联模型的 createdAt 排序. (首选方法) [Subtask.associations.Task, 'createdAt', 'DESC'], // 将使用关联对象按嵌套关联模型的 createdAt 排序. (首选方法) [Subtask.associations.Task, Task.associations.Project, 'createdAt', 'DESC'], // 将使用简单的关联对象按关联模型的 createdAt 排序. [{model: Task, as: 'Task'}, 'createdAt', 'DESC'], // 将由嵌套关联模型的 createdAt 简单关联对象排序. [{model: Task, as: 'Task'}, {model: Project, as: 'Project'}, 'createdAt', 'DESC'] ], // 将按最大年龄降序排列 order: sequelize.literal('max(age) DESC'), // 如果忽略方向,则默认升序,将按最大年龄升序排序 order: sequelize.fn('max', sequelize.col('age')), // 如果省略方向,则默认升序, 将按年龄升序排列 order: sequelize.col('age'), // 将根据方言随机排序(但不是 fn('RAND') 或 fn('RANDOM')) order: sequelize.random() }); Model.findOne({ order: [ // 将返回 `name` ['name'], // 将返回 `username` DESC ['username', 'DESC'], // 将返回 max(`age`) sequelize.fn('max', sequelize.col('age')), // 将返回 max(`age`) DESC [sequelize.fn('max', sequelize.col('age')), 'DESC'], // 将返回 otherfunction(`col1`, 12, 'lalala') DESC [sequelize.fn('otherfunction', sequelize.col('col1'), 12, 'lalala'), 'DESC'], // 将返回 otherfunction(awesomefunction(`col`)) DESC, 这种嵌套可能是无限的! [sequelize.fn('otherfunction', sequelize.fn('awesomefunction', sequelize.col('col'))), 'DESC'] ] });

                      order 数组的元素可以如下:

                      一个字符串 (它将被自动引用)

                      一个数组, 其第一个元素将被引用,第二个将被逐字追加

                      一个具有raw字段的对象:

                      • raw 内容将不加引用地逐字添加
                      • 其他所有内容都将被忽略,如果未设置 raw,查询将失败

                      调用 Sequelize.fn (这将在 SQL 中生成一个函数调用)

                      调用 Sequelize.col (这将引用列名)

                      6. group

                      分组和排序的语法相同,只是分组不接受方向作为数组的最后一个参数(不存在 ASC, DESC, NULLS FIRST 等).

                      还可以将字符串直接传递给 group,该字符串将直接(普通)包含在生成的 SQL 中.

                      Model.findAll({ group: 'name' }); Model.findAll({ group: [sequelize.col('date'),sequelize.col('id')] //可以指定多个列进行分组 }); // 生成 'GROUP BY name'

                      Tips:在做分组和排序的时候可以使用sequelize.col()指定列,防止在子查询或者关联查询时找不到列名

                      7. include

                      include关键字表示关联查询

                      简单查询

                      1. findOne

                      findOne 方法获得它找到的第一个条目(它可以满足提供的可选查询参数).

                      &nbsp;const user = await User.findOne({ where: { username: 'admin' } });

                      2.findAll

                      该查询将从表中检索所有条目(除非受到 where 子句的限制).

                      const user = await User.findAll({ where: { username: 'admin' },raw:true });

                      3.findAndCountAll,findAndCount

                      findAndCountAll 方法是结合了 findAllcount 的便捷方法. 在处理与分页有关的查询时非常有用,在分页中,你想检索带有 limitoffset 的数据,但又需要知道与查询匹配的记录总数.

                      当没有提供 group 时, findAndCountAll 方法返回一个具有两个属性的对象:

                      • count : 一个整数 - 与查询匹配的记录总数
                      • rows :一个数组对象 - 获得的记录

                      当提供了 group 时, findAndCountAll 方法返回一个具有两个属性的对象:

                      • count - 一个数组对象 - 包含每组中的合计和预设属性
                      • rows - 一个数组对象 - 获得的记录

                      const { count, rows } = await User.findAndCountAll({ where: { username: { [Op.like]: '%foo%' } }, offset: 10, //查询偏移(跳过)量 limit: 2 //限制返回结果条数 });

                      关联查询

                      let result = await Goods.findAndCount({ include: [ { attributes: [[sequelize.col('title'), 'goods_name']], association: Goods.belongsTo(tbGoods, { targetKey: 'goodsId', foreignKey: 'goodsId' , as:'goods_name_info'}), model: Goods, required: false, where: params2, } ], where: params, limit, offset: currentPage, raw: true, order: [ [sequelize.col('date'), 'DESC'], ] })

                      关联类型

                      A.hasOne(B, { /* 参数 */ }); // A 有一个 B A.belongsTo(B, { /* 参数 */ }); // A 属于 B A.hasMany(B, { /* 参数 */ }); // A 有多个 B A.belongsToMany(B, { through: 'C', /* 参数 */ }); // A 属于多个 B , 通过联结表 C

                      association

                      as指定连接的别名

                      where

                      关联中也支持where子句。

                      required

                      如何通过Nodejs Sequelize手册从快速入门到实际应用?

                      false,表示左外连接(LEFT OUTER JOIN),左表全部出现在结果集中,若右表无对应记录,则相应字段为NULL

                      true,表示内连接(INNER JOIN),满足条件的记录才会出现在结果集中。

                      子查询

                      Tips:由于 sequelize.literal 会插入任意内容而不进行转义

                      //根据goodsId 去匹配 goods_order对应的 goods_name let result = await goods_roi.findAll({ attributes: [ 'goodsId', [sequelize.fn('SUM', sequelize.col('order_count')), 'order_count'], [sequelize.fn('SUM', sequelize.col('total_price_sum')), 'total_price_sum'], [sequelize.fn('SUM', sequelize.col('goods_cost')), 'goods_cost'], [ sequelize.literal(`( SELECT item_title FROM goods_order AS goods_order WHERE goods_order.item_id = goods_roi.goodsId limit 1 )`), 'goods_name' ] ], where: params, raw: true, group: [sequelize.col('goodsId')] })

                      实用方法 countmaxminsumincrement, decrement

                      count 方法仅计算数据库中元素出现的次数

                      const amount = await Model.count({ where: { id: { [Op.gt]: 25 } } }); console.log(`这有 ${amount} 个记录 id 大于 25`);

                      max, minsum

                      假设我们有三个用户,分别是10、5和40岁

                      await User.max('age'); // 40 await User.max('age', { where: { age: { [Op.lt]: 20 } } }); // 10 await User.min('age'); // 5 await User.min('age', { where: { age: { [Op.gt]: 5 } } }); // 10 await User.sum('age'); // 55 await User.sum('age', { where: { age: { [Op.gt]: 5 } } }); // 50

                      increment自增, decrement自减

                      await User.increment({age: 5}, { where: { id: 1 } }) // 将年龄增加到15岁 await User.increment({age: -5}, { where: { id: 1 } }) // 将年龄降至5岁

                      3. 更新 update

                      update查询也接受 where 参数

                      *// 将所有没有姓氏的人更改为 "Doe"* await User.update({ lastName: "Doe" }, { where: { lastName: null } });

                      4. 删除destroy

                      destroy查询也接受 where 参数

                      *// 删除所有名为 "Jane" 的人* await User.destroy({ where: { firstName: "Jane" } });

                      5. 托管事务(transaction)

                      Sequelize 支持两种使用事务的方式:

                      • 托管事务: 如果引发任何错误,Sequelize 将自动回滚事务,否则将提交事务. 另外,如果启用了CLS(连续本地存储),则事务回调中的所有查询将自动接收事务对象.
                      • 非托管事务: 提交和回滚事务应由用户手动完成(通过调用适当的 Sequelize 方法).

                      托管事务会自动处理提交或回滚事务. 通过将回调传递给 sequelize.transaction 来启动托管事务. 这个回调可以是 async(通常是)的.

                      在这种情况下,将发生以下情况:

                      • Sequelize 将自动开始事务并获得事务对象 t
                      • 然后,Sequelize 将执行你提供的回调,并在其中传递 t
                      • 如果你的回调抛出错误,Sequelize 将自动回滚事务
                      • 如果你的回调成功,Sequelize 将自动提交事务

                      只有这样,sequelize.transaction调用才会解决:

                      • 解决你的回调的决议
                      • 或者,如果你的回调引发错误,则拒绝并抛出错误

                      try { const result = await sequelize.transaction(async (t) => { const user = await User.create({ firstName: 'Abraham', lastName: 'Lincoln' }, { transaction: t }); //{transaction: t} 必须作为第二个对象里的参数传递 return user; }); // 如果执行到此行,则表示事务已成功提交,`result`是事务返回的结果 // `result` 就是从事务回调中返回的结果(在这种情况下为 `user`) } catch (error) { // 如果执行到此,则发生错误. // 该事务已由 Sequelize 自动回滚! }

                      注意:t.commit()t.rollback() 没有被直接调用.

                      自动将事务传递给所有查询:在上面的示例中,仍然通过传递 { transaction: t } 作为第二个参数来手动传递事务.

                      以上为js版本,部分不适用于ts,ts要根据具体的官方文档使用。

                      以上就是Nodejs Sequelize手册学习快速入门到应用的详细内容,更多关于Nodejs Sequelize入门手册的资料请关注自由互联其它相关文章!