在现代 Web 开发中,数据库操作是后端服务的核心组成部分。MySQL 作为一款广泛使用的开源关系型数据库,与各种编程语言都有良好的集成。对于 Deno 开发者来说,掌握如何高效操作 MySQL 数据库是构建完整应用的关键技能。本文将从基础入门到进阶应用,再到实用技巧,全面解析 Deno 与 MySQL 的交互之道。
一、基础入门教程
1. 环境准备与连接建立
首先需要在系统上安装并启动 MySQL 服务,创建测试数据库和表。在 Deno 中操作 MySQL,常用的模块是deno_mysql,通过 URL 直接引入:
import { Client } from "https://deno.land/x/mysql/mod.ts"; |
建立数据库连接的代码如下:
async function connectToMySQL() { const client = new Client(); try { await client.connect({ hostname: "localhost", port: 3306, user: "root", password: "your_password", db: "test_db" }); console.log("成功连接到MySQL数据库"); // 后续操作 client.close(); } catch (error) { console.error("连接数据库失败:", error); } } connectToMySQL(); |
运行时需添加网络权限:deno run --allow-net your_script.ts
2. 执行基本查询
连接成功后,可执行 SQL 查询语句。以下是查询和插入数据的示例:
async function basicQueries() { const client = new Client(); await client.connect({/* 连接配置 */}); // 查询数据 const selectResult = await client.query("SELECT * FROM users"); console.log("查询结果:", selectResult); // 插入数据 const insertResult = await client.execute( "INSERT INTO users (name, age) VALUES (?, ?)", ["Alice", 30] ); console.log("插入成功,ID:", insertResult.insertId); client.close(); } |
这里使用了预处理语句(execute方法),通过占位符?防止 SQL 注入。
3. 处理查询结果
查询结果是一个对象数组,每个对象代表一行记录:
// 假设users表结构为id, name, age const users = await client.query("SELECT * FROM users"); for (const user of users) { console.log(`用户: ${user.name}, 年龄: ${user.age}`); } |
对于复杂查询,可使用别名提高结果可读性:
const result = await client.query( "SELECT u.id AS user_id, u.name AS username FROM users u" ); |
二、进阶教程
1. 事务处理
事务能确保一组操作要么全部成功,要么全部失败。示例如下:
async function transactionExample() { const client = new Client(); await client.connect({/* 连接配置 */}); try { // 开始事务 await client.execute("START TRANSACTION"); // 执行多个操作 await client.execute("UPDATE accounts SET balance = balance - 100 WHERE id = 1"); await client.execute("UPDATE accounts SET balance = balance + 100 WHERE id = 2"); // 提交事务 await client.execute("COMMIT"); console.log("事务提交成功"); } catch (error) { // 回滚事务 await client.execute("ROLLBACK"); console.error("事务失败,已回滚:", error); } finally { client.close(); } } |
2. 连接池管理
频繁创建和关闭数据库连接会影响性能,使用连接池可以复用连接:
import { createPool, Pool } from "https://deno.land/x/mysql/mod.ts"; const pool: Pool = createPool({ hostname: "localhost", port: 3306, user: "root", password: "your_password", db: "test_db", poolSize: 5 // 连接池大小 }); async function useConnectionPool() { const connection = await pool.getConnection(); try { const result = await connection.query("SELECT * FROM users"); console.log("使用连接池查询结果:", result); } finally { connection.release(); // 释放连接回池 } } |
3. 存储过程调用
MySQL 存储过程可封装复杂业务逻辑,Deno 中调用示例:
async function callStoredProcedure() { const client = new Client(); await client.connect({/* 连接配置 */}); const result = await client.execute( "CALL GetUserCount(?)", ["Admin"] ); console.log("存储过程返回:", result); client.close(); } |
三、实用技巧
1. 错误处理与重试机制
数据库操作可能因网络波动等原因失败,添加重试机制可提高稳定性:
async function executeWithRetry(query: string, params: any[] = [], maxRetries = 3) { let retries = 0; while (retries < maxRetries) { try { const client = new Client(); await client.connect({/* 连接配置 */}); const result = await client.execute(query, params); client.close(); return result; } catch (error) { retries++; console.error(`尝试 ${retries}/${maxRetries} 失败:`, error); if (retries >= maxRetries) throw error; await new Promise(resolve => setTimeout(resolve, 1000)); // 等待1秒后重试 } } } |
2. 性能优化
- 批量操作:使用INSERT INTO ... VALUES ?, ?, ?批量插入数据
const values = [ ["Bob", 25], ["Charlie", 35] ]; await client.execute( "INSERT INTO users (name, age) VALUES ?", [values] ); |
- 索引优化:对查询频繁的字段添加索引,提高查询速度
- 连接池配置:根据应用负载调整连接池大小,避免连接耗尽
3. 安全最佳实践
- 参数化查询:始终使用预处理语句和占位符,防止 SQL 注入
- 最小权限原则:为数据库用户分配最小必要权限,避免使用 root 账户
- 密码安全:不硬编码数据库密码,使用环境变量或配置文件管理
const password = Deno.env.get("MYSQL_PASSWORD"); |
通过本文的学习,你已掌握了 Deno 操作 MySQL 数据库的核心技能,从基础的连接建立、数据查询,到进阶的事务处理、连接池管理,再到实用的错误处理和安全优化。这些知识将帮助你构建高效、稳定的数据库驱动应用,充分发挥 Deno 和 MySQL 的组合优势。