【RuoYi-Eggjs】:让 MySQL 更简单

前言

在 Node.js 开发中,操作数据库是最常见的需求之一。虽然 mysql2 库功能强大,但在 Egg.js 项目中直接使用还需要处理连接池、配置管理等繁琐的工作。[ruoyi-eggjs-mysql](https://github.com/undsky/ruoyi-eggjs-mysql) 就是为了解决这个痛点而生的——它是一个基于 mysql2 的 Egg.js 插件,提供了开箱即用的数据库操作能力。

核心特性

🚀 简洁的 API 设计

插件封装了最常用的数据库操作,让代码更加直观:


    
    
    
  // 查询单条记录
const
 user = await app.mysql.select('SELECT * FROM users WHERE id = 1');

// 查询多条记录

const
 users = await app.mysql.selects('SELECT * FROM users WHERE age > 18');

// 插入数据

const
 insertId = await app.mysql.insert("INSERT INTO users (name, age) VALUES ('张三', 25)");

// 更新数据

const
 affectedRows = await app.mysql.update("UPDATE users SET age = 26 WHERE id = 1");

// 删除数据

const
 deleted = await app.mysql.del("DELETE FROM users WHERE id = 1");

📊 执行SQL实时输出并显示执行时间

在开发过程中,了解每条 SQL 的执行性能至关重要。ruoyi-eggjs-mysql 插件内置了智能的 SQL 执行监控功能,每次执行 SQL 时都会在控制台实时输出执行信息,让性能优化变得一目了然。当你执行任何数据库操作时,插件会自动在控制台输出:

🔄 智能驼峰命名转换

支持自动将数据库字段从 snake_case 转换为 camelCase,让前后端数据格式保持一致:


    
    
    
  // 配置开启驼峰转换
config.mysql = {
  camelCase
: true,
  // ...其他配置

};

// 数据库字段:user_id, user_name, created_at

const
 user = await app.mysql.select('SELECT * FROM users WHERE id = 1');
// 返回:{ userId: 1, userName: '张三', createdAt: '2024-01-01 12:00:00' }

这个功能对于前端开发者特别友好,避免了在代码中手动转换字段名的麻烦。

⏰ 时区问题一劳永逸

mysql2 默认会将时间转换为 UTC。插件默认配置已经解决了这个问题:


    
    
    
  config.mysql = {
  default
: {
    timezone
: '+08:00',    // 设置为东八区
    dateStrings
: true,     // 保持日期为字符串格式
  },
};

配置后,时间字段会保持原样返回,不再有时区困扰。

🔒 内置事务支持

处理转账、批量操作等场景时,事务是必不可少的。插件提供了简单易用的事务 API:


    
    
    
  // 转账示例:从账户 A 转 100 元到账户 B
await
 app.mysql.transaction([
  "UPDATE accounts SET balance = balance - 100 WHERE user_id = 1"
,
  "UPDATE accounts SET balance = balance + 100 WHERE user_id = 2"
,
  "INSERT INTO transactions (from_user, to_user, amount) VALUES (1, 2, 100)"
,
]);

如果任何一条 SQL 执行失败,所有操作会自动回滚,数据安全有保障。

快速上手

安装


    
    
    
  npm i ruoyi-eggjs-mysql --save

配置

1. 启用插件


    
    
    
  // config/plugin.js
exports
.mysql = {
  enable
: true,
  package
: "ruoyi-eggjs-mysql",
};

2. 配置数据库连接


    
    
    
  // config/config.default.js
config.mysql = {
  default
: {
    port
: 3306,
    charset
: "utf8mb4",
    multipleStatements
: true,
    connectionLimit
: 100,
    timezone
: '+08:00',      // 时区设置
    dateStrings
: true,       // 日期保持字符串格式
  },
  camelCase
: false,          // 是否开启驼峰转换
  client
: {
    host
: "127.0.0.1",
    user
: "root",
    password
: "your_password",
    database
: "your_database",
  },
};

实战示例

下面是一个完整的用户管理 Service 示例:


    
    
    
  // app/service/user.js
const
 { Service } = require('egg');

class
 UserService extends Service {
  // 创建用户

  async
 create(name, age) {
    const
 insertId = await this.app.mysql.insert(
      `INSERT INTO users (name, age, created_at) VALUES ('${name}', ${age}, NOW())`

    );
    return
 insertId;
  }

  // 查询单个用户

  async
 findById(id) {
    return
 await this.app.mysql.select(`SELECT * FROM users WHERE id = ${id}`);
  }

  // 查询所有用户

  async
 findAll() {
    return
 await this.app.mysql.selects('SELECT * FROM users ORDER BY id DESC');
  }

  // 更新用户

  async
 update(id, data) {
    const
 affectedRows = await this.app.mysql.update(
      `UPDATE users SET name = '${data.name}', age = ${data.age} WHERE id = ${id}`

    );
    return
 affectedRows > 0;
  }

  // 删除用户

  async
 delete(id) {
    const
 deleted = await this.app.mysql.del(`DELETE FROM users WHERE id = ${id}`);
    return
 deleted > 0;
  }
}

module
.exports = UserService;

多数据库支持

当项目需要连接多个数据库时(如主从分离、跨库查询),插件也能轻松应对:


    
    
    
  // 配置多个数据库
config.mysql = {
  default
: { /* 默认配置 */ },
  clients
: {
    db1
: {
      host
: "127.0.0.1",
      database
: "database1",
      // ...

    },
    db2
: {
      host
: "192.168.1.100",
      database
: "database2",
      // ...

    },
  },
};

// 使用不同数据库

const
 db1 = app.mysql.get('db1');
const
 db2 = app.mysql.get('db2');

const
 user = await db1.select('SELECT * FROM users WHERE id = 1');
const
 order = await db2.select('SELECT * FROM orders WHERE user_id = 1');

安全建议

上面的示例为了简洁使用了字符串拼接,但在生产环境中强烈建议使用参数化查询来防止 SQL 注入:


    
    
    
  const pool = app.mysql.pool;

// ✅ 推荐:参数化查询

const
 [users] = await pool.query('SELECT * FROM users WHERE age > ?', [18]);

// ❌ 不推荐:字符串拼接(有 SQL 注入风险)

const
 users = await app.mysql.selects(`SELECT * FROM users WHERE age > ${age}`);

总结

ruoyi-eggjs-mysql 是一个轻量但实用的 Egg.js MySQL 插件,它的优势在于:

如果你正在使用 Egg.js 开发项目,并且需要操作 MySQL 数据库,不妨试试这个插件,相信它会让你的开发效率提升不少!


引用链接

[1] ruoyi-eggjs-mysql: https://github.com/undsky/ruoyi-eggjs-mysql
[2] RuoYi-Eggjs: https://github.com/undsky/ruoyi-eggjs
[3] RuoYi-Eggjs 文档: https://www.undsky.com/blog/?category=RuoYi-Eggjs#