第6篇:EggJS数据库操作与ORM实践

在Web应用开发中,数据库操作是核心环节之一。EggJS通过集成Sequelize ORM框架,提供了高效、安全的数据库操作方案。本文将深入讲解如何在EggJS中配置MySQL数据库、定义数据模型、优化复杂查询,以及管理数据库迁移与种子数据。

在这里插入图片描述

一、MySQL基础配置与多环境适配

1. 安装与基础配置

安装Egg-Sequelize插件:

npm install egg-sequelize mysql2 --save

配置数据库连接(config/config.default.js):

module.exports = {sequelize: {dialect: 'mysql',host: '127.0.0.1',port: 3306,username: 'root',password: 'your_password',database: 'egg_demo',timezone: '+08:00', // 设置时区define: {freezeTableName: true, // 禁止自动修改表名timestamps: false      // 禁用默认时间戳字段}}
};

2. 多环境配置策略

使用EggJS环境配置机制:

config
├── config.default.js
├── config.prod.js
└── config.unittest.js

生产环境配置示例(config/config.prod.js):

const { GetDatabaseConfig } = require('./utils/config-loader');module.exports = {sequelize: {...GetDatabaseConfig('prod'), // 从安全存储获取配置pool: { // 连接池配置max: 5,min: 1,idle: 10000}}
};

安全建议

  • 敏感信息通过环境变量注入
  • 生产配置使用加密存储方案
  • 不同环境完全隔离数据库实例

二、Sequelize模型定义与关联关系

1. 基础模型定义

创建用户模型(app/model/user.js):

module.exports = app => {const { STRING, INTEGER, DATE } = app.Sequelize;const User = app.model.define('user', {id: { type: INTEGER, primaryKey: true, autoIncrement: true },username: { type: STRING(30), unique: true },password: { type: STRING(64) },created_at: DATE,updated_at: DATE});return User;
};

2. 关联关系类型

一对多关系(用户-文章):
// app/model/user.js
User.associate = function() {this.hasMany(app.model.Article, { foreignKey: 'author_id' });
};// app/model/article.js
Article.associate = function() {this.belongsTo(app.model.User, { foreignKey: 'author_id' });
};
多对多关系(文章-标签):
// app/model/article.js
Article.associate = function() {this.belongsToMany(app.model.Tag, {through: 'article_tag',foreignKey: 'article_id'});
};

三、复杂查询构建与性能优化

1. 高级查询示例

分页查询+关联数据:
async listArticles(page = 1, pageSize = 10) {const { count, rows } = await ctx.model.Article.findAndCountAll({offset: (page - 1) * pageSize,limit: pageSize,include: [{ model: ctx.model.User, attributes: ['id', 'username'] },{ model: ctx.model.Tag, through: { attributes: [] } }],order: [['created_at', 'DESC']]});return { total: count, list: rows };
}

2. 性能优化策略

索引优化:
// 模型定义时添加索引
Article.init({title: {type: STRING(100),index: true // 普通索引}
}, { sequelize });
避免N+1查询:
// 错误做法
const articles = await Article.findAll();
for (const article of articles) {const user = await article.getUser(); // 产生N次查询
}// 正确做法
const articles = await Article.findAll({include: [User]
});
慢查询监控:
// config/config.default.js
sequelize: {logging: (sql, timing) => {if (timing > 200) { // 记录超过200ms的查询app.logger.warn(`Slow query (${timing}ms): ${sql}`);}}
}

四、数据库迁移与种子数据管理

1. 使用迁移工具

安装迁移模块:

npm install umzug --save-dev

创建迁移文件(database/migrations/2023090101-create-user.js):

module.exports = {async up(queryInterface, Sequelize) {await queryInterface.createTable('users', {id: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true },username: { type: Sequelize.STRING(30), allowNull: false },created_at: { type: Sequelize.DATE, allowNull: false },updated_at: { type: Sequelize.DATE, allowNull: false }});await queryInterface.addIndex('users', ['username'], { unique: true });},async down(queryInterface) {await queryInterface.dropTable('users');}
};

2. 种子数据管理

创建种子文件(database/seeders/2023090101-demo-user.js):

module.exports = {up: async queryInterface => {await queryInterface.bulkInsert('users', [{username: 'admin',created_at: new Date(),updated_at: new Date()}]);},down: async queryInterface => {await queryInterface.bulkDelete('users', { username: 'admin' });}
};

操作命令

# 执行迁移
npx umzug up # 回滚迁移
npx umzug down# 运行种子
npx umzug seed

五、最佳实践建议

  1. 模型设计原则

    • 优先选择Snake Case命名(user_groups)
    • 为常用查询字段添加索引
    • 避免过度范式化设计
  2. 事务使用规范

    await ctx.model.transaction(async t => {await User.create({...}, { transaction: t });await Account.create({...}, { transaction: t });
    });
    
  3. 缓存策略

    • 高频读取数据使用Redis缓存
    • 缓存失效时间不超过5分钟
    • 写操作同步更新缓存

总结

通过合理使用Sequelize ORM,开发者可以:

  • 用面向对象的方式操作数据库
  • 保持代码的可维护性和扩展性
  • 实现高效的复杂查询
  • 保证数据操作的原子性和一致性

正确实施数据库迁移方案,能够有效管理数据库结构变更,配合种子数据机制,显著提升开发测试效率。下一篇文章我们将探讨《RESTful API设计与安全防护》,解析如何构建安全高效的API系统。欢迎在评论区留下你遇见的「数据库操作与ORM」设计经验与挑战,共同探讨最佳实践!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/79418.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

法线纹理采样+可视化Shader编辑器

法线贴图,对主纹理凹凸显示 建模原理 法线贴图:切线空间,存储xy切线,映射法线,法线信息存储在切线空间中。 模型是否凹凸,是由模型顶点决定的,现在实现的法线贴图,控制凹凸,实际上是…

OID是什么?

什么是 OID? OID 是 Object Identifier(对象标识符) 的缩写,是SNMP(Simple Network Management Protocol,简单网络管理协议)中用来唯一标识被管理对象(比如设备的某项信息)的一串数字。

STM32 ZIBEE DL-20 无线串口模块

一.配置方法 二.串口中断 u8 i; u16 buf[20],res; u8 receiving_flag 0; // 新增一个标志,用于标记是否开始接收数组 void USART1_IRQHandler(void) {if(USART_GetITStatus(USART1, USART_IT_RXNE) ! RESET) //接收中断{res USART_ReceiveData(USART1);if(receiv…

全感官交互革命:当 AI 大模型学会 “看、听、说、创”

引言:从 “文字对话” 到 “全感官体验”,AI 正在重塑人类认知边界 当 AI 不再局限于文本对话,而是能 “看懂” 图像、“听懂” 语音、“生成” 视频,并将这些模态无缝融合时,一场关于人机交互的革命已然开启。DeepSe…

C++模板知识

目录 引言 一、非类型模板参数 二、类模板的特化 (一)概念 (二)函数模板特化 (三)类模板特化 1. 全特化 2. 偏特化 (四)类模板特化应用示例 三、模板的分离编译 …

Pillow 移除或更改了 FreeTypeFont.getsize() 方法

w, h self.font.getsize(label) # text width, height AttributeError: FreeTypeFont object has no attribute getsize 在Pillow 项目的变更日志里可以查到哪个版本移除了 getsize() 方法,Pillow仓库: Releases python-pillow/Pillow GitHub 因为…

Matlab自学笔记

一、我下载的是Matlab R2016a软件,打开界面如下: 二、如何调整字体大小,路径为:“主页”->“预设”->“字体”。 三、命令行窗口是直接进行交互式的,如下输入“3 5”,回车,就得到结果“…

VR汽车线束:汽车制造的新变革

汽车线束,作为汽车电路网络的主体,宛如汽车的 “神经网络”,承担着连接汽车各个部件、传输电力与信号的重任,对汽车的正常运行起着关键作用。从汽车的发动机到仪表盘,从传感器到各类电子设备,无一不是通过线…

目标检测YOLO实战应用案例100讲-基于多级特征融合的小目标深度检测网络

目录 知识储备 基于多级特征融合的小目标深度检测网络实现 一、环境配置 二、核心代码实现 1. 多级特征融合模块(models/fpn.py ) 2. 主干网络(models/backbone.py ) 3. 检测头(models/detector.py ) 三、完整网络架构(models/net.py ) 四、训练代码(train.p…

【云原生】基于Centos7 搭建Redis 6.2 操作实战详解

目录 一、前言 二、Redis 6.2 安装过程 2.1 下载安装包 2.2 安装包解压 2.3 安装包编译 2.3 安装 2.4 启动redis 2.4.1 前台启动(不推荐) 2.4.2 后启动(推荐) 2.4.3 关闭redis服务 2.4.4 设置客户端连接 三、写在最后 …

云计算-容器云-服务网格

服务网格:创建VirtualService(3分) ​ 将Bookinfo应用部署到default命名空间下,为Bookinfo应用创建一个名为reviews的VirtualService,要求来自名为Jason的用户的所有流量将被路由到reviews服务的v2版本。(需要用到的软件包:ServiceMesh.tar.gz) # 上传解压 tar -xf Se…

【Res模块学习】结合CIFAR-100分类任务学习

初次尝试训练CIFAR-100:【图像分类】CIFAR-100图像分类任务-CSDN博客 1.训练模型(MyModel.py) import torch import torch.nn as nnclass BasicRes(nn.Module):def __init__(self, in_cha, out_cha, stride1, resTrue):super(BasicRes, sel…

爱胜品ICSP YPS-1133DN Plus黑白激光打印机报“自动进纸盒进纸失败”处理方法之一

故障现象如下图提示: 用户的爱胜品ICSP YPS-1133DN Plus黑白激光打印机在工作过程中提示自动进纸盒进纸失败并且红色故障灯闪烁; 给出常见故障一般处理建议如下: 当您的爱胜品ICSP YPS-1133DN Plus 黑白激光打印机出现“自动进纸盒进纸失败”…

Flinkcdc 实现 MySQL 写入 Doris

Flinkcdc 实现 MySQL 写入 Doris Flinkcdc 实现 MySQL 写入 Doris 一、环境配置 Doris:3.0.4 JDK 17 MySQL (业务数据库):5.7 MySQL(本地数据库):5.7 Flink:flink-1.19.1 flinkc…

【Linux庖丁解牛】—环境变量!

目录 1. 环境变量 1.1 概念介绍 1.2 命令行参数 1.3 一个例子,一个环境变量 1.4 认识更多的环境变量 1.5 获取环境变量的方法 a. 指令操作 b. 代码操作 1.6 理解环境变量的特性 a.环境变量具有全局特性 b.补充两个概念(为后面埋一个伏笔) 1. 环境变量 …

LangChain4j +DeepSeek大模型应用开发——7 项目实战 创建硅谷小鹿

这部分我们实现硅谷小鹿的基本聊天功能,包含聊天记忆、聊天记忆持久化、提示词 1. 创建硅谷小鹿 创建XiaoLuAgent package com.ai.langchain4j.assistant;import dev.langchain4j.service.*; import dev.langchain4j.service.spring.AiService;import static dev…

普通 html 项目也可以支持 scss_sass

项目结构示例 下载vscode的插件Live Sass Compiler 自动监听编译scss 下载插件Live Server 用于 web 服务器,打开 html 文件到浏览器,也可以不用这个,自己用 nginx 或者宝塔其他 web 工具 新建一个 index.scss打开,点击 vscode 底…

网工_IP协议

2025.02.17:小猿网&网工老姜学习笔记 第19节 IP协议 9.1 IP数据包的格式(首部数据部分)9.1.1 IP协议的首部格式(固定部分可变部分) 9.2 IP数据包分片(找题练)9.3 TTL生存时间的应用9.4 常见…

SQL语句练习 自学SQL网 在查询中使用表达式 统计

目录 Day 9 在查询中使用表达式 Day 10 在查询中进行统计 聚合函数 Day 11 在查询中进行统计 HAVING关键字 Day12 查询执行顺序 Day 9 在查询中使用表达式 SELECT id , Title , (International_salesDomestic_sales)/1000000 AS International_sales FROM moviesLEFT JOIN …

基于机器学习的舆情分析算法研究

标题:基于机器学习的舆情分析算法研究 内容:1.摘要 随着互联网的飞速发展,舆情信息呈现爆炸式增长,如何快速准确地分析舆情成为重要课题。本文旨在研究基于机器学习的舆情分析算法,以提高舆情分析的效率和准确性。方法上,收集了近…