为了帮助大家入门使用新一代分布式关系型数据库 OceanBase,我们撰写了系列文章:用SvelteKit 和 OceanBase 构建一个全栈应用,如何用OceanBase和Python构建无界面电商应用。这篇文章我们将引导大家如何使用流行的 Sequelize ORM 和 Express 服务器将 OceanBase 集成到 Node.js 项目中。
Sequelize 是一个基于 Promise 的 Node ORM,支持 PostgreSQL、 MySQL、 MariaDB、 SQLite 以及 OceanBase。它提供了一套强大的功能,用于模型的查询和操作。另一方面,Express 是一个轻量灵活的 Node Web 应用程序框架,为 Web 和移动 APP 提供了强大的功能。
您可能会问,为什么要在 OceanBase 中使用 Sequelize 和 Express?Sequelize 帮助我们以更符合 JavaScript 习惯的方式与 OceanBase 进行交互,它抽象了大部分 SQL 语法。而 Express 作为一个快速、开放和精简的 Node Web 框架,能够轻松高效地构建应用程序的后端。
我们要构建的应用:
一个 Mini CRM 系统
在本文中,我将构建一个迷你的客户关系管理( CRM )系统。CRM 系统是管理客户数据、互动和业务信息的组成部分。无论企业规模大小, CRM 系统对于维护有效的客户关系和确保业务顺利运作都至关重要。
这个 Mini CRM 系统将充分利用 OceanBase 的强大功能。OceanBase 是下一代分布式关系型数据库,以处理大量数据、具有高可用性和强一致性而著称。OceanBase 的可伸缩性和分布式特性使其成为各种规模企业的理想选择。随着企业规模的扩大和数据量的增加,他们可以轻松地使用 OceanBase 来扩展其数据库,使其成为 CRM 系统和其他企业资源规划应用的理想选择。
这个 Mini CRM 系统是一个简单但功能丰富的应用程序,可以允许我们在数据库中执行创建、读取、更新和删除(CRUD)操作。这些操作是任何数据驱动型应用程序的基础,对于管理数据库中的记录至关重要。
CRM系统将具有以下功能:
1、创建联系人:我们能够向数据库中添加新的联系人。每个联系人将有基本信息,如姓名、电子邮件、公司和所有者。
2、读取联系人:我们能够查看存储在数据库中的所有联系人。这个功能可显示所有联系人的列表以及他们各自的信息。我们还可以读取特定联系人的记录。
3、更新联系人:这个功能允许我们修改特定联系人的详细信息。我们可以更新与联系人相关的任何信息,如更改他们的电子邮件或公司。
4、删除联系人:如果我们不再需要在数据库中保留某个联系人,我们可以将其删除。这个功能将从数据库中删除联系人及其所有相关信息。
通过构建这个 Mini CRM系统,我们将学习如何在 Node.js 项目中有效使用 OceanBase,并使用 Sequelize 作为 ORM 和 Express 作为服务端。我们将了解如何使用 Sequelize 执行 CRUD 操作,并如何构建我们的 Express 应用程序来处理这些操作。最重要的是,我们将看到 OceanBase 如何轻松地管理我们的数据,为我们的应用程序的数据库需求提供可靠的和可扩展的解决方案。
系统配置搭建
1、设置数据库
要设置项目,首先需要一个运行中的 OceanBase 集群。这里有几种选择方式。可以在本地环境中安装 OceanBase ,在云中启动虚拟机运行它,也可以使用 AWS 市场中的 OceanBase Cloud ,通过几次点击即可设置集群。
在本教程中,我将在 AWS EC2 实例上简单设置一个演示用的 OceanBase 集群。(戳蓝色链接回顾如何在 AWS EC2 上安装 OceanBase 集群。)
安装 OceanBase 并启动演示集群后,我将为开发设置一个演示用户,而不是使用不安全的 root 用户。
我们可以创建一个名为 demo 的新用户,该用户只能访问我们使用的数据库。在此之前,我还在 OceanBase 中创建了一个名为 app 的数据库,这将是本文中我们与之进行交互的主要数据库。
要创建一个新用户,将使用以下命令:
CREATE USER 'demo'@'localhost' IDENTIFIED BY 'password';接下来,授予用户访问 app 数据库的权限。
GRANTALL PRIVILEGES ON app.*TO'demo'@'localhost';现在,使用演示用户凭证从项目连接到 OceanBase 实例。
Host: YOUR_EC2_PUBLIC_IP_ADDRESSPort: 2881User: demoPassword: password
2、设置项目
现在,我们需要设置 Node.js 项目。假设已经安装了 Node.js 和 npm。如果没有安装,可以从官方 Node.js 网站下载并安装它们。准备就绪后,为项目创建一个新目录,并使用 npm 初始化它:
mkdir oceanbase-sequelize && cd oceanbase-sequelizenpm init -y
接下来,安装 Express、 Sequelize 和 mysql2 驱动程序。(由于 Sequelize 没有直接支持 OceanBase,并且 OceanBase 兼容 MySQL,我将在 Sequelize 中使用 MySQL 驱动程序连接到 OceanBase,在我的所有测试中都能正常工作。)
npm install express sequelize mysql23、配置 Sequelize
Sequelize 是一个强大的 ORM 工具,提供了高级抽象来管理数据库操作。它支持各种数据库,包括 OceanBase(通过 MySQL)。配置 Sequelize 涉及设置与数据库的连接、定义表示数据库中表的模型。
可以使用命令行界面(CLI)简化设置和管理项目的过程。Sequelize CLI 提供的其中一个命令是 sequelize init,它设置了一个基本的项目结构。
在使用 Sequelize CLI 之前,需要安装它。可通过运行以下命令安装:
npm install --save-dev sequelize-cliSequelize CLI 安装好之后,可运行以下命令初始化项目:
npx sequelize init这个命令将创建以下目录和文件:
config/:该目录包含一个 config.json 文件,您可以在其中为不同环境(开发、测试和生产)指定数据库配置。
models/:该目录用于存放 Sequelize 模型。默认情况下,它包含一个 index.js 文件,用于设置 Sequelize 并导入所有模型。
migrations/:该目录用于存放迁移脚本。
seeders/:该目录用于存放种子文件。
4、配置数据库连接
要连接到OceanBase数据库,需要使用您的数据库凭证更新 config/config.json 文件。以下是我在上一节中创建的凭据的配置示例:
{"development": {"username": "demo","password": "password","database": "app","host": "YOUR_EC2_PUBLIC_IP_ADDRESS","port": 2881,"dialect": "mysql"},"test": {"username": "your_username","password": "your_password","database": "your_database","host": "localhost","dialect": "mysql"},"production": {"username": "your_username","password": "your_password","database": "your_database","host": "localhost","dialect": "mysql"}}
现在, Sequelize 已经配置好并可以在项目中使用了。可以在 models/ 目录下开始定义模型,并使用 Sequelize 的功能与 OceanBase 数据库进行交互。
系统初始化
1、定义数据模型
在 Sequelize 中,数据模型代表数据库中的表。可以使用 Sequelize 实例上的 define 方法来定义它们。该方法有两个参数:模型的名称(将用作表名)和定义模型属性的对象。
我们为CRM系统定义一个 Contact 模型。该模型将具有以下属性:firstName、lastName、email、age、company 和 owner。
下面是如何在 models/Contact.js 文件中定义这个模型的示例:
module.exports = (sequelize, DataTypes) => {const Contact = sequelize.define('Contact', {firstName: {type: DataTypes.STRING,allowNull: false,validate: {notEmpty: true,},},lastName: {type: DataTypes.STRING,allowNull: false,validate: {notEmpty: true,},},email: {type: DataTypes.STRING,allowNull: false,validate: {notEmpty: true,},},age: {type: DataTypes.INTEGER,allowNull: true,validate: {notEmpty: true,},},company: {type: DataTypes.STRING,allowNull: true,validate: {notEmpty: true,},},owner: {type: DataTypes.STRING,allowNull: true,validate: {notEmpty: true,},},});return Contact;};
在这段代码中,我们定义了一个具有6个属性的 Contact 模型。每个属性都是一个对象,指定了数据类型和验证规则。
例如,firstName、lastName 和 email 属性的类型为 STRING,并且不能为空或为空字符串。age、company 和 owner 属性也是 STRING 类型,但可以为空,但是如果提供了值,则不能为空。
Validate 属性用于指定验证规则。在这种情况下,我们使用了 notEmpty 规则,确保值不是空字符串。
Define 方法返回模型,然后我们将其导出,以便在应用程序的其他部分中使用。该 Contact 模型现在代表我们 OceanBase 数据库中的一个 Contact 表。您可以使用该模型对 Contact 表执行 CRUD 操作。
2、构建 Express 应用程序
Express 应用程序是我们项目的核心。我们在其中定义路由并处理请求。在这种情况下,我们将创建路由来对 Contact 模型执行 CRUD(创建、读取、更新、删除)操作。
3、设置 Express
首先,我们导入 Express 并创建其实例。我们还从 models 目录导入 Contact 模型和 Sequelize 实例。
const express = require('express');const app = express();// Connect to the databaseconst db = require('./models');const { Contact } = require('./models');
我们还添加了一个中间件来解析 JSON 主体。这是必要的一步,因为我们将在 POST 和 PATCH 请求中接收 JSON 数据。
app.use(express.json());系统功能
1、获取所有联系人
我们的第一个路由是一个路径为 /contacts 的 GET 路由,该路由使用 Contact 模型上 findAll 的方法从数据库中检索所有联系人。
app.get('/contacts', async (req, res) => {const contacts = await Contact.findAll();res.json(contacts);});
2、通过 ID 获取联系人
接下来,我们有一个 GET 路由,路径为 /contact/:id。该路由使用 findByPk 方法按照 ID 检索单个联系人。
app.get('/contact/:id', async (req, res) => {const contact = await Contact.findByPk(req.params.id);if (contact) {res.json(contact);} else {res.status(404).send({status: 'failed',message: 'Contact not found',});}});
3、创建新联系人
我们还有一个 POST 路由,路径为 /contact。该路由使用 create 方法创建一个新的联系人。
app.post('/contact', async (req, res) => {const newContact = await Contact.create(req.body);res.json(newContact);});
当向该路由发送 POST 请求时,请求体应该是一个表示新联系人的 JSON 对象。该对象的结构应该与我们 Contact 模型的结构相匹配。
以下是一个示例,展示了如何构造请求体的结构:
{"firstName": "John","lastName": "Doe","email": "john.doe@example.com","age": 30,"company": "Tech Corp","owner": "Jane Doe"}
4、删除联系人
DELETE 路由的路径为 /contact/:id,该路由使用 destroy 方法按照 ID 删除联系人。
app.delete('/contact/:id', async (req, res) => {const result = await Contact.destroy({where: {id: req.params.id,},});if (result) {res.status(200).send({status: 'succeed',message: 'Contact deleted',});} else {res.status(404).send({status: 'failed',message: 'Contact not found',});}});
在这个路由中,:id 是一个路由参数,表示要删除的联系人的 ID。当发起 DELETE 请求时,将 : id 替换为实际的联系人 ID。
例如,如果想删除 ID 为 5 的联系人,可发送一个 DELETE 请求到 /contact/5。
联系人的 ID 通常在创建联系人时由 OceanBase 分配。可以通过向 /contacts 路由发送 GET 请求来查找联系人的 ID ,该路由返回所有联系人的列表。列表中的每个联系人都包含一个 id 属性,可以在 DELETE 路由中使用该属性。
5、更新联系人
最后,我们有一个 PATCH 路由,路径为 /contact/:id,使用 update 方法按照 ID 更新联系人。
app.patch('/contact/:id', async (req, res) => {const updatedContact = await Contact.update(req.body, {where: {id: req.params.id,},});if (updatedContact[0]) {res.status(200).send({status: 'Contact updated',data: await Contact.findByPk(req.params.id),});} else {res.status(404).send({status: 'failed',message: 'Contact not found',});}});
当向该路由发送 PATCH 请求时,请求体应该是一个包含要更新属性的 JSON 对象。该对象的结构应该与我们 Contact 模型的结构相匹配,但您只需要包含要更改的属性。
以下是一个示例,展示了如何构造请求体的结构:
{"email": "new.email@example.com","company": "New Tech Corp"}
在这个示例中,我们只更新了 email 和 company 属性,而 firstName、lastName、age 和 owner 属性将保持不变。
系统启动
1、启动服务器
最后,我们使用 db.sequelize.sync() 将 Sequelize 模型与 OceanBase 数据库同步,并启动我们的服务器。
db.sequelize.sync().then((req) => {app.listen(3000, () => {console.log('Server running at port 3000...');});});
sync 方法会在数据库中创建必要的表(如果它们不存在)。在同步完成后,在端口 3000 上启动我们的服务器。
现在我们拥有一个完全功能的 Express 应用程序,可以使用 Sequelize 和 OceanBase 对我们的 Contact 模型进行 CRUD 操作。
2、运行应用程序
要运行应用程序,只需在终端中导航到项目的根目录,并运行以下命令:
node index.js如果在终端中看到消息 " Server running at port 3000... ",这表示应用程序正在运行并准备接受请求。
要与应用程序进行交互,可以使用像 Postman 这样的工具,它允许我们向服务器发送 HTTP 请求并查看响应。在本文中,我将使用 VS Code 中的 Thunder Client 插件来测试这些请求。
下面是我们可以使用 Thunder Client 与应用程序进行交互的一些示例。
系统功能示例
1、创建新联系人
要创建新的联系人,可以发送一个 POST 请求到 http://127.0.0.1:3000/contact。在请求的正文中,需要包含一个表示新联系人的 JSON 对象。
在这个示例中,我们正在创建一个名为 "John Smith",电子邮件为 "john@example.com",年龄为 33 岁,公司为 "EXAMPLE INC",所有者为 "Wayne" 的新联系人。发送请求后,会收到一个响应,其中包含由 OceanBase 分配的新联系人的 ID。
2、获取所有联系人
要获取所有联系人,可以发送一个 GET 请求到 http://127.0.0.1:3000/contacts。
在这个示例中,我们从 OceanBase 数据库中检索所有联系人,得到的响应是一个联系人数组。
3、通过 ID 获取联系人
要通过ID获取联系人,可发送一个GET请求到 http://127.0.0.1:3000/contact/:id,将 :id 替换为联系人的 ID。
在这个示例中,我们正在检索 ID 为 7 的联系人,得到的响应是具有该 ID 的联系人。
4、更新联系人
要更新联系人,可以发送一个 PATCH 请求到 http://127.0.0.1:3000/contact/:id,将 :id 替换为联系人的 ID。在请求的正文中,需要包含要更新的属性的 JSON 对象。
在这个示例中,我们正在更新 ID 为 6 的联系人的名字,得到的响应是更新后的联系人。
5、删除联系人
要删除联系人,可以发送一个 DELETE 请求到 http://127.0.0.1:3000/contact/:id,将 :id 替换为联系人的 ID。
在这个示例中,我们正在删除 ID为 5 的联系人。响应是一条消息,指示联系人已成功删除。
结论
在本文中,我们讨论了如何使用 Sequelize 和 Express 将 OceanBase 集成到一个 Node 项目中,并构建了一个 Mini CRM 系统,对 Contact 模型执行 CRUD 操作。
我们看到 Sequelize 将大部分 SQL 语法抽象化,以一种对 JavaScript 友好的方式与 OceanBase 数据库进行交互。我们还看到 Express 使我们能够轻松高效地构建应用程序的后端。我们构建的 Mini CRM 系统是一个简单但可扩展的应用程序,利用了 OceanBase 的可扩展性和分布式特性,使其非常适合各种规模的企业。




