Sequelize 操作 Oracle 数据库完整指南

前言

在我们的日常开发中,操作数据库是一个不可避免的任务,而 Sequelize 是一个开源的、基于 Promise 的 ORM 的库,可以方便地操作不同的数据库。虽然在 Sequelize 的文档中,不支持在 Oracle 数据库下的操作,但我们可以从其他 ORM 的使用经验出发,通过 Sequelize 对 Oracle 数据库进行 ORM 操作。

安装与环境准备

在使用 Sequelize 操作 Oracle 数据库前,需要确保我们有一个可操作的 Oracle 数据库,同时也需要在本地环境中安装 Oracle Instant Client 和 ODPI-C。这里以 macOS 系统为例:

  1. 安装 Oracle Instant Client
  1. 修改环境变量
  1. 安装 ODPI-C

Sequelize 的基础操作

建立连接

我们可以通过如下的方式,创建 Sequelize 对象,并与 Oracle 数据库直接建立连接:

const { Sequelize } = require('sequelize');
const sequelize = new Sequelize('database', 'username', 'password', {
  dialect: 'oracle',
  host: 'localhost'
})

定义模型

我们可以使用 Sequelize.define() 方法来定义一个模型。可以指定列名、数据类型、默认值等等,如下所示:

const Book = sequelize.define('book', {
  title: {
    type: Sequelize.STRING,
    allowNull: false
  },
  author: Sequelize.STRING,
  year: Sequelize.DATE,
  pages: Sequelize.INTEGER,
  language: Sequelize.STRING
})

同步、迁移和填充

在我们创建了模型之后,可以使用 sync() 方法将它与数据库中的表关联起来。如果没有表,则会自动生成,示例代码如下:

await sequelize.sync()

如果进行了相关的迁移操作,则可以使用 migrate() 方法对数据库进行更新,示例代码如下:

await sequelize.migrate()

如果需要对表中的数据进行填充,则可以使用 bulkCreate() 方法将数据批量添加到表中,如下所示:

await Book.bulkCreate([
  { title: 'JavaScript: The Good Parts', author: 'Douglas Crockford', year: '2008-05-08', pages: 152, language: 'English' },
  { title: 'The Hitchhiker\'s Guide to the Galaxy', author: 'Douglas Adams', year: '1979-10-12', pages: 193, language: 'English' }
])

查询

Sequelize 提供了多种方式查询表中的数据。如果要获取表中的所有记录,可以使用 findAll() 方法,如下所示:

const books = await Book.findAll()

如果要查询特定记录,则可以使用 findOne() 方法,如下所示:

const book = await Book.findOne({ where: { title: 'JavaScript: The Good Parts' }})

如果要进行分页,则可以使用 findAndCountAll() 方法,如下所示:

const page = 2 // 第二页
const pageSize = 10 // 每页 10 条记录
const books = await Book.findAndCountAll({ offset: (page - 1) * pageSize, limit: pageSize })

修改和删除

如果要修改表中的记录,可以使用 update() 方法,如下所示:

await Book.update({ language: 'Chinese' }, { where: { id: 1 }})

如果要删除指定的记录,可以使用 destroy() 方法,如下所示:

await Book.destroy({ where: { id: 1 }})

高级操作

聚合查询

Sequelize 支持多种聚合查询操作,例如计数、求和、最大值、最小值等等。可以使用 Sequelize.fn() 方法和 Sequelize.col() 方法来实现,示例代码如下:

await Book.count() // 计数

await Book.sum('pages') // 求和

await Book.max('pages') // 最大值

await Book.min('pages') // 最小值

await Book.findAll({
  attributes: [['year', 'year'], [Sequelize.fn('SUM', Sequelize.col('pages')), 'totalPages']],
}) // 分组统计

关联查询

在 Sequelize 中,关联是实现数据模型间互操作的重要方式。关联查询可以帮助您组合多张表的记录,以便更快、更方便地获取数据。Sequelize 支持以下五种关联查询方式:

  • 一对一关联
  • 一对多关联
  • 多对多关联
  • 自引用关联
  • 链式关联

我们以一对多关联为例进行说明。例如我们有两张表,分别为 AuthorBook,每本书都有一个作者,而每个作者可以写多本书。在这种情况下,我们可以使用 belongsTo()hasMany() 方法来创建这样的关联,如下所示:

const Author = sequelize.define('author', {
  name: Sequelize.STRING,
})

const Book = sequelize.define('book', {
  title: Sequelize.STRING,
  authorId: {
    type: Sequelize.INTEGER,
    references: {
      model: Author,
      key: 'id',
    },
  },
})

Author.hasMany(Book)
Book.belongsTo(Author)

接下来,我们可以很方便地通过 Author.findAll({ include: Book }) 获取作者以及他们写的所有书籍,或通过 Book.findAll({ include: Author }) 获取每本书以及它的作者信息。

事务

在 Sequelize 中,我们可以使用 transaction() 方法创建一个事务,通过 ORM 方式实现事务操作。如果事务操作失败,则可以使用 rollback() 方法进行回滚,如下所示:

await sequelize.transaction(async (transaction) => {
  await Book.update({ language: 'English' }, { where: { id: 1 }, transaction })

  await Book.update({ language: 'English' }, { where: { id: 2 }, transaction })

  // 事务操作失败
  throw new Error()
})
  .then(() => console.log('Transaction has been committed'))
  .catch(() => console.log('Transaction has been rolled back'))

实例方法和钩子

Sequelize 的模型实例也可以定义自己的方法,甚至可以定义钩子函数来处理每个保存操作。可以使用 instanceMethodshooks 来定义它们,如下所示:

const Book = sequelize.define('book', {
  title: Sequelize.STRING,
  author: Sequelize.STRING,
  year: Sequelize.DATE,
  pages: Sequelize.INTEGER,
  language: Sequelize.STRING,
}, {
  instanceMethods: {
    incrementPages() {
      this.pages++
    },
  },
  hooks: {
    beforeSave: (book, options) => {
      console.log('Preparing to save the book')
    },
    afterSave: (book, options) => {
      console.log('Book has been saved')
    },
  },
})

在定义这些方法和钩子之后,我们就可以在我们的应用程序中使用它们了,如下所示:

const book = await Book.findOne()
book.incrementPages()
await book.save()

总结

通过本文的介绍,我们可以了解到如何使用 Sequelize 操作 Oracle 数据库。Sequelize 提供了丰富的 API 和强大的功能,使得我们可以更加方便地进行数据模型、数据关联、数据查询、事务操作等等。希望这篇文章对你在实际开发中有所帮助。完整的示例代码已经上传到 GitHub 了,可以自由参考、修改、使用。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65b2f641add4f0e0ffc088a1