前言
在我们的日常开发中,操作数据库是一个不可避免的任务,而 Sequelize 是一个开源的、基于 Promise 的 ORM 的库,可以方便地操作不同的数据库。虽然在 Sequelize 的文档中,不支持在 Oracle 数据库下的操作,但我们可以从其他 ORM 的使用经验出发,通过 Sequelize 对 Oracle 数据库进行 ORM 操作。
安装与环境准备
在使用 Sequelize 操作 Oracle 数据库前,需要确保我们有一个可操作的 Oracle 数据库,同时也需要在本地环境中安装 Oracle Instant Client 和 ODPI-C。这里以 macOS 系统为例:
- 安装 Oracle Instant Client
brew install instantclient
- 修改环境变量
export OCI_HOME=/usr/local/instantclient_19_8 export DYLD_LIBRARY_PATH=$OCI_HOME:$DYLD_LIBRARY_PATH
- 安装 ODPI-C
npm i --save oracledb mssql sqlite3 tedious pg mysql2 pg-hstore sequelize
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 支持以下五种关联查询方式:
- 一对一关联
- 一对多关联
- 多对多关联
- 自引用关联
- 链式关联
我们以一对多关联为例进行说明。例如我们有两张表,分别为 Author
和 Book
,每本书都有一个作者,而每个作者可以写多本书。在这种情况下,我们可以使用 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 的模型实例也可以定义自己的方法,甚至可以定义钩子函数来处理每个保存操作。可以使用 instanceMethods
和 hooks
来定义它们,如下所示:
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