Skip to content

polewt/mysql-full-tool

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

nodejs-mysql-tool

一个基于 Node.js 和 mysql2 的简洁、安全、高效的 MySQL 数据库操作工具。

特性

  • 简洁易用: 提供直观的 API 接口,简化数据库操作
  • 连接池管理: 自动管理数据库连接,优化资源使用
  • 参数化查询: 内置 SQL 注入防护,确保数据安全
  • 统一错误处理: 所有操作返回统一的结果格式,便于错误处理
  • 完整的 CRUD 支持: 支持 INSERT、SELECT、UPDATE、DELETE 操作
  • 事务支持: 通过 execute() 方法支持完整的事务操作
  • TypeScript 友好: 提供完整的 JSDoc 类型定义
  • 全面测试: 95+ 单元测试和属性测试,确保代码质量

安装

npm install nodejs-mysql-tool

快速开始

const MySQLTool = require('nodejs-mysql-tool');

// 创建实例
const dbTool = new MySQLTool({
  host: 'localhost',
  user: 'root',
  password: 'password',
  database: 'test_db'
});

// 测试连接
const isConnected = await dbTool.testConnection();
if (isConnected) {
  console.log('数据库连接成功');
}

// 查询数据
const result = await dbTool.query('SELECT * FROM users WHERE age > ?', [18]);
if (result.success) {
  console.log('查询结果:', result.data);
}

// 关闭连接
await dbTool.close();

API 文档

构造函数

new MySQLTool(config)

创建 MySQLTool 实例。

参数:

参数 类型 必需 默认值 说明
config.host string - 数据库主机地址
config.port number 3306 数据库端口
config.user string - 数据库用户名
config.password string '' 数据库密码
config.database string - 数据库名称
config.connectionLimit number 10 连接池最大连接数
config.connectTimeout number 10000 连接超时时间(毫秒)
config.charset string 'utf8mb4' 字符集

示例:

const dbTool = new MySQLTool({
  host: 'localhost',
  port: 3306,
  user: 'root',
  password: 'password',
  database: 'test_db',
  connectionLimit: 10,
  connectTimeout: 10000,
  charset: 'utf8mb4'
});

方法

testConnection()

测试数据库连接是否正常。

返回: Promise<boolean> - 连接成功返回 true,失败返回 false

示例:

const isConnected = await dbTool.testConnection();
if (!isConnected) {
  console.error('数据库连接失败');
}

execute(sql, params)

执行任意 SQL 语句。

参数:

  • sql (string): SQL 语句
  • params (array, 可选): 参数数组

返回: Promise<QueryResult>

示例:

// 执行 SELECT 查询
const result = await dbTool.execute('SELECT * FROM users WHERE id = ?', [1]);

// 执行 CREATE TABLE
await dbTool.execute(`
  CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100)
  )
`);

// 执行事务
await dbTool.execute('START TRANSACTION');
await dbTool.execute('INSERT INTO users (name) VALUES (?)', ['张三']);
await dbTool.execute('COMMIT');

query(sql, params)

执行 SELECT 查询。

参数:

  • sql (string): SELECT 语句
  • params (array, 可选): 参数数组

返回: Promise<QueryResult> - 成功时 data 字段包含查询结果数组

示例:

const result = await dbTool.query('SELECT * FROM users WHERE age > ?', [18]);
if (result.success) {
  result.data.forEach(user => {
    console.log(user.name, user.age);
  });
}

insert(table, data)

插入数据。

参数:

  • table (string): 表名
  • data (object): 要插入的数据对象

返回: Promise<QueryResult> - 成功时包含 insertId 和 affectedRows

示例:

const result = await dbTool.insert('users', {
  name: '张三',
  email: 'zhangsan@example.com',
  age: 25
});

if (result.success) {
  console.log('新记录ID:', result.insertId);
}

update(table, data, where)

更新数据。

参数:

  • table (string): 表名
  • data (object): 要更新的字段和值
  • where (object): WHERE 条件对象

返回: Promise<QueryResult> - 成功时包含 affectedRows

示例:

const result = await dbTool.update(
  'users',
  { age: 26, email: 'new@example.com' },  // 更新的字段
  { id: 1 }                                 // WHERE 条件
);

if (result.success) {
  console.log('更新了', result.affectedRows, '行');
}

delete(table, where)

删除数据。

参数:

  • table (string): 表名
  • where (object): WHERE 条件对象(必需,防止全表删除)

返回: Promise<QueryResult> - 成功时包含 affectedRows

示例:

const result = await dbTool.delete('users', { id: 1 });

if (result.success) {
  console.log('删除了', result.affectedRows, '行');
}

close()

关闭连接池。

返回: Promise<void>

示例:

await dbTool.close();
console.log('连接池已关闭');

QueryResult 对象

所有数据库操作都返回 QueryResult 对象:

{
  success: boolean,        // 操作是否成功
  data?: Array<Object>,    // 查询结果(SELECT)
  affectedRows?: number,   // 影响的行数(INSERT/UPDATE/DELETE)
  insertId?: number,       // 插入的ID(INSERT)
  error?: string          // 错误信息(失败时)
}

使用示例

基础 CRUD 操作

const MySQLTool = require('nodejs-mysql-tool');

const dbTool = new MySQLTool({
  host: 'localhost',
  user: 'root',
  password: 'password',
  database: 'test_db'
});

// INSERT
const insertResult = await dbTool.insert('users', {
  name: '张三',
  email: 'zhangsan@example.com',
  age: 25
});

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

// UPDATE
const updateResult = await dbTool.update(
  'users',
  { age: 26 },
  { id: insertResult.insertId }
);

// DELETE
const deleteResult = await dbTool.delete('users', { id: 1 });

await dbTool.close();

事务操作

try {
  await dbTool.execute('START TRANSACTION');
  
  // 转账操作
  await dbTool.execute('UPDATE accounts SET balance = balance - ? WHERE id = ?', [100, 1]);
  await dbTool.execute('UPDATE accounts SET balance = balance + ? WHERE id = ?', [100, 2]);
  
  await dbTool.execute('COMMIT');
  console.log('转账成功');
} catch (error) {
  await dbTool.execute('ROLLBACK');
  console.error('转账失败,已回滚');
}

错误处理

const result = await dbTool.query('SELECT * FROM users');

if (result.success) {
  // 操作成功
  console.log('查询结果:', result.data);
} else {
  // 操作失败
  console.error('查询失败:', result.error);
  
  // 根据错误类型采取不同处理
  if (result.error.includes('连接')) {
    console.log('建议: 检查数据库连接配置');
  } else if (result.error.includes('不存在')) {
    console.log('建议: 检查表名是否正确');
  }
}

复杂查询

// JOIN 查询
const result = await dbTool.query(`
  SELECT users.name, orders.product, orders.amount
  FROM users
  INNER JOIN orders ON users.id = orders.user_id
  WHERE users.age > ?
  ORDER BY orders.amount DESC
`, [18]);

// 聚合查询
const stats = await dbTool.query(`
  SELECT 
    COUNT(*) as total,
    AVG(age) as avg_age,
    MAX(age) as max_age
  FROM users
`);

// 分页查询
const page = 1;
const pageSize = 10;
const offset = (page - 1) * pageSize;

const pageResult = await dbTool.query(
  'SELECT * FROM users ORDER BY id LIMIT ? OFFSET ?',
  [pageSize, offset]
);

配置建议

开发环境

const dbTool = new MySQLTool({
  host: 'localhost',
  user: 'root',
  password: 'password',
  database: 'dev_db',
  connectionLimit: 5,
  connectTimeout: 10000
});

生产环境

const dbTool = new MySQLTool({
  host: process.env.DB_HOST,
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_NAME,
  connectionLimit: 50,      // 根据并发量调整
  connectTimeout: 5000      // 快速失败
});

最佳实践

  1. 使用环境变量: 不要在代码中硬编码数据库凭据
  2. 参数化查询: 始终使用参数化查询防止 SQL 注入
  3. 错误处理: 检查 result.success 字段,妥善处理错误
  4. 连接管理: 使用 try-finally 确保连接池被正确关闭
  5. 事务处理: 在 try-catch 中处理事务,确保错误时能够回滚
  6. 连接池配置: 根据实际并发量调整 connectionLimit

常见问题

Q: 如何处理连接失败?

A: 使用 testConnection() 方法在应用启动时验证连接:

const isConnected = await dbTool.testConnection();
if (!isConnected) {
  console.error('数据库连接失败,应用停止启动');
  process.exit(1);
}

Q: 如何防止 SQL 注入?

A: 始终使用参数化查询:

// ✅ 正确 - 使用参数化查询
await dbTool.query('SELECT * FROM users WHERE name = ?', [userName]);

// ✗ 错误 - 字符串拼接
await dbTool.query(`SELECT * FROM users WHERE name = '${userName}'`);

Q: 如何处理大量数据?

A: 使用分页查询:

const pageSize = 100;
const page = 1;
const offset = (page - 1) * pageSize;

const result = await dbTool.query(
  'SELECT * FROM users LIMIT ? OFFSET ?',
  [pageSize, offset]
);

Q: 连接池耗尽怎么办?

A:

  1. 增加 connectionLimit
  2. 优化查询性能,减少连接占用时间
  3. 检查是否有连接泄漏(未正确关闭)

更多示例

查看 documents/example 目录获取更多示例:

测试

# 运行所有测试
npm test

# 运行特定测试
npm test -- --testNamePattern="insert"

# 查看测试覆盖率
npm test -- --coverage

依赖

  • Node.js >= 14.0.0
  • mysql2 ^3.6.0

开发依赖

  • jest ^29.0.0
  • fast-check ^3.0.0
  • eslint ^8.0.0

许可证

MIT

贡献

欢迎提交 Issue 和 Pull Request!

作者

nodejs-mysql-tool 开发团队

About

MySQL Full Tool - MCP Server for database operations

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors