基于 Node.js 的 ORM(对象关系映射)工具——Sequelize介绍与使用,并举案例分析

便捷性介绍

支持多种数据库,包括 PostgreSQL、MySQL、MariaDB、SQLite 和 Microsoft SQL Server。Sequelize 提供了丰富的功能,帮助开发者用 JavaScript(或 TypeScript)代码操作数据库,而无需直接书写 SQL 语句。

Sequelize 的主要特点

跨数据库支持:支持主流数据库如 MySQL、PostgreSQL、SQLite 等。

模型(Model)定义:通过定义模型(类似于类),对应数据库的表。

迁移(Migrations)工具:方便管理数据库的版本变化。

事务支持:提供事务操作,确保数据一致性。

查询生成器:支持链式查询和条件查询,生成高效的 SQL 语句。

钩子(Hooks):支持生命周期钩子,方便在特定操作前后执行代码。

基本使用介绍

安装 Sequelize 和数据库驱动

复制代码
npm install sequelize
npm install mysql2 # 对于 MySQL

创建实例

复制代码
const { Sequelize } = require('sequelize');

// 创建与数据库的连接实例
const sequelize = new Sequelize('database_name', 'username', 'password', {
  host: 'localhost',
  dialect: 'mysql', // 数据库类型,可更换为 'postgres', 'sqlite', 'mssql' 等
  logging: false,  // 是否打印 SQL 日志
});

同步模型到数据库

将模型与数据库表同步

复制代码
(async () => {
  try {
    await sequelize.authenticate(); // 验证连接是否成功
    console.log('连接建立成功');

    await sequelize.sync({ force: true }); // 同步模型,`force: true` 表示重建表
    console.log('所有异步模型成功.');
  } catch (error) {
    console.error('不能连接到数据库', error);
  } finally {
    await sequelize.close(); // 关闭数据库连接
  }
})();

定义模型:(相当于是在建数据表)

模型是 Sequelize 的核心,用来描述数据库的表结构

复制代码
const { DataTypes } = require('sequelize');

const User = sequelize.define('User', {
  id: {
    type: DataTypes.INTEGER,
    autoIncrement: true,
    primaryKey: true,
  },
  username: {
    type: DataTypes.STRING,
    allowNull: false,
  },
  email: {
    type: DataTypes.STRING,
    unique: true,
  },
  password: {
    type: DataTypes.STRING,
  },
}, {
  tableName: 'users', // 指定表名
  timestamps: true,  // 是否自动生成 createdAt 和 updatedAt 字段
});

数据操作(增删改查)

复制代码
//创建数据
const newUser = await User.create({
  username: 'JohnDoe',
  email: 'johndoe@example.com',
  password: '123456',
});
console.log(newUser.toJSON());

// 查询所有用户
const users = await User.findAll();
console.log(users);

// 按条件查询
const specificUser = await User.findOne({ where: { username: 'JohnDoe' } });
console.log(specificUser);

//更新数据
await User.update({ email: 'newemail@example.com' }, {
  where: { username: 'JohnDoe' },
});


//删除数据
await User.destroy({
  where: { username: 'JohnDoe' },
});

Sequelize 模型内置的方法总结(常用的)

findAll():查询所有记录(生成 SELECT 查询)。

findByPk():根据主键查询单个记录(生成 SELECT 查询)。

create():创建新记录(生成 INSERT 查询)。

save():保存(更新)模型实例(生成 UPDATE 或 INSERT 查询)。

destroy():删除模型实例对应的记录(生成 DELETE 查询)。

update():更新多条记录(生成 UPDATE 查询)。

count():查询记录的总数(生成 SELECT COUNT 查询)。

这些方法使得你可以用对象化的方式来进行数据库操作,而不需要手动编写 SQL 语句,从而提高了开发效率并减少了错误。

其他基本数据库操作

关联(Associations)

Sequelize 支持表之间的关系:一对一 (1:1)、一对多 (1:N)、多对多 (N:M)。

复制代码
const Post = sequelize.define('Post', { title: DataTypes.STRING });
User.hasMany(Post);  // 一个用户有多个帖子
Post.belongsTo(User); // 一个帖子属于一个用户

事务(Transactions)

复制代码
const t = await sequelize.transaction();

try {
  const user = await User.create({ username: 'Jane' }, { transaction: t });
  await t.commit(); // 提交事务
} catch (error) {
  await t.rollback(); // 回滚事务
}

生命周期钩子(Hooks)

复制代码
User.beforeCreate((user, options) => {
  console.log('Before creating user:', user.username);
});

原生查询

如果需要执行原生 SQL,可以使用 sequelize.query。

复制代码
const [results, metadata] = await sequelize.query('SELECT * FROM users');

具体项目案例

现在要实现一个用户认证模块,以node为后端,数据库是确定的,但是不在数据库当中建任何表,全依靠Sequelize进行:

src/config/db.js(后端数据库连接)

复制代码
const { Sequelize } = require('sequelize')

// 使用 Sequelize 连接 MySQL
// 这里配置数据库名称、用户名、密码、主机和方言
const sequelize = new Sequelize('project', 'root', '123456', {
  host: 'localhost',
  dialect: 'mysql',
})

/**
 * 连接数据库的异步函数
 * 尝试验证与数据库的连接,如果成功则打印确认消息
 * 如果连接失败,则打印错误消息并退出进程
 */
const connectDB = 
  async () => {
  try {
    await sequelize.authenticate()
    console.log('MySQL Connected')
  } catch (err) {
    console.error('Unable to connect to the database:', err.message)
    process.exit(1)
  }
}

// 导出 sequelize 实例和 connectDB 函数供外部使用
module.exports = { sequelize, connectDB }

src/modules/User.js(用户模型-用户数据表定义建立)

复制代码
const { Sequelize, DataTypes } = require('sequelize')
const bcrypt = require('bcrypt')
const { sequelize } = require('../config/db')

// 定义 User 模型
const User = sequelize.define('User', {
  username: {
    type: DataTypes.STRING,
    allowNull: false,
    unique: true,
  },
  password: {
    type: DataTypes.STRING,
    allowNull: false,
  },
})

// 在保存用户之前加密密码
User.beforeCreate(async (user) => {
  user.password = await bcrypt.hash(user.password, 10)
})

module.exports = User

src/app.js(程序入口)

复制代码
//dotenv 是一个用于 加载环境变量 的 Node.js 模块,它会从项目根目录的 .env 文件中读取环境变量,并将其添加到 process.env 对象中
//开发者就可以通过 process.env.变量名 来访问环境变量。
require('dotenv').config()
const express = require('express')
//---------------------数据库部分-------------------------------------------------------------------------------
const { connectDB, sequelize } = require('./config/db')
const app = express()

// 初始化数据库连接
connectDB()

// 同步数据库表结构,sequelize.sync 会同步模型与数据库表。alter: true 会根据模型的定义修改数据库表结构(谨慎使用于生产环境)。
sequelize.sync({ alter: true }).then(() => {
  console.log('数据库和表结构已经同步成功')
})
//---------------------------------------------------------------------------------------------------------------
//express.json() 是一个中间件,用于解析 JSON 格式的请求体。
app.use(express.json())

//通过 process.env.PORT 读取 .env 文件中配置的端口号,如果未定义,则默认使用 5000
const PORT = process.env.PORT || 5000
app.listen(PORT, () => console.log(`Server running on port ${PORT}`))


// app.use('/api/auth', authRoutes):当访问 /api/auth 路径时,将由 authRoutes 处理请求。
// 这是模块化路由的常见实现方式。
const authRoutes = require('./routes/authRoutes')

app.use('/api/auth', authRoutes)

其他一些可能用得上的功能

支持原始 SQL 查询

复制代码
const results = await sequelize.query('SELECT * FROM Users WHERE username = :username', {
  replacements: { username: 'JohnDoe' },
  type: QueryTypes.SELECT,
});

高级查询

条件查询

复制代码
const users = await User.findAll({
  where: {
    username: {
      [Op.like]: 'J%',
    },
  },
});

分页与排序

复制代码
const users = await User.findAll({ limit: 10, offset: 20, order: [['username', 'ASC']] });

还有数据迁移和数据库连接池此处就不讲了

此处提供:
官方文档 : https://sequelize.org/
GitHub 仓库 : https://github.com/sequelize/sequelize

Sequelize 是一个功能全面的 ORM 工具,它简化了数据库操作,支持多种数据库类型。通过模型定义、查询构建、事务管理和数据库迁移,开发者可以高效地处理复杂的数据管理需求。如果你的项目需要频繁的数据库操作或希望避免直接使用 SQL,Sequelize 是一个值得选择的解决方案。

相关推荐
ywf121513 小时前
前端的dist包放到后端springboot项目下一起打包
前端·spring boot·后端
恋猫de小郭13 小时前
2026,Android Compose 终于支持 Hot Reload 了,但是收费
android·前端·flutter
hpoenixf19 小时前
2026 年前端面试问什么
前端·面试
还是大剑师兰特19 小时前
Vue3 中的 defineExpose 完全指南
前端·javascript·vue.js
泯泷19 小时前
阶段一:从 0 看懂 JSVMP 架构,先在脑子里搭出一台最小 JSVM
前端·javascript·架构
mengchanmian20 小时前
前端node常用配置
前端
sinat_2554878120 小时前
读者、作家 Java集合学习笔记
java·笔记·学习
华洛20 小时前
利好打工人,openclaw不是企业提效工具,而是个人助理
前端·javascript·产品经理
xkxnq20 小时前
第六阶段:Vue生态高级整合与优化(第93天)Element Plus进阶:自定义主题(变量覆盖)+ 全局配置与组件按需加载优化
前端·javascript·vue.js
A黄俊辉A21 小时前
vue css中 :global的使用
前端·javascript·vue.js