Node.js + MySQL の連携
このトピックを修了すると
Node.js で MySQL に接続し、CRUD クエリを実行するコードを作成できるようになります。
なぜ Node.js でデータベースを使うのか?
これまで SQL を MySQL クライアントで直接入力してきました。しかし、実際のウェブサービスでは、コードが自動的に SQL を実行する必要があります。
ユーザーが会員登録ボタンをクリックすると → サーバーが INSERT INTO users ... を実行 → 結果をレスポンスとして返します。このプロセスを Node.js コードで実装します。
mysql2 のインストールと接続
npm install mysql2const mysql = require('mysql2');
// 接続設定
const connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'mypassword',
database: 'myapp'
});
// 接続確認
connection.connect((err) => {
if (err) {
console.error('接続失敗:', err.message);
return;
}
console.log('MySQL 接続成功');
});mysql2 は、Node.js で MySQL を使用するための標準ライブラリです。mysql という古いパッケージもありますが、mysql2 の方が高速で Promise をサポートしています。
クエリの実行 — CRUD
データの照会 (SELECT)
connection.query('SELECT * FROM users', (err, rows) => {
if (err) {
console.error(err);
return;
}
console.log(rows);
// [ { id: 1, name: '김훈', email: 'hoon@example.com' }, ... ]
});結果は JavaScript 配列 として返されます。各行がオブジェクト 1 つです。
データの挿入 (INSERT)
const name = '박진';
const email = 'jin@example.com';
connection.query(
'INSERT INTO users (name, email) VALUES (?, ?)',
[name, email],
(err, result) => {
if (err) {
console.error(err);
return;
}
console.log('挿入された ID:', result.insertId);
}
);? は プレースホルダー です。値を配列で渡すと、mysql2 が安全に代入します。
データの更新 (UPDATE)
connection.query(
'UPDATE users SET email = ? WHERE id = ?',
['new@example.com', 1],
(err, result) => {
console.log('更新された行:', result.affectedRows);
}
);データの削除 (DELETE)
connection.query(
'DELETE FROM users WHERE id = ?',
[3],
(err, result) => {
console.log('削除された行:', result.affectedRows);
}
);プレースホルダー (?) — なぜ重要なのか
// ❌ 絶対にこのようにしないでください
const userInput = "'; DROP TABLE users; --";
connection.query(`SELECT * FROM users WHERE name = '${userInput}'`);
// ✅ 常にプレースホルダーを使用
connection.query('SELECT * FROM users WHERE name = ?', [userInput]);ユーザー入力を SQL 文字列に直接入れると、SQL インジェクション攻撃にさらされます。プレースホルダー (?) を使うと、mysql2 が自動的に危険な文字をエスケープします。
コネクションプール — 実践的なパターン
実際のサーバーでは、リクエストごとに接続を作成して切断する代わりに、コネクションプールを使用します。
const pool = mysql.createPool({
host: 'localhost',
user: 'root',
password: 'mypassword',
database: 'myapp',
waitForConnections: true,
connectionLimit: 10
});
// プールからクエリを実行 (接続の自動管理)
pool.query('SELECT * FROM users WHERE id = ?', [1], (err, rows) => {
console.log(rows);
});プールは事前に複数の接続を作成しておき、クエリが入ると空いている接続を割り当てます。クエリが終了すると、接続をプールに戻します。毎回接続/切断するコストがなくなります。
Promise 方式 (async/await)
コールバックパターンが複雑な場合は、Promise 方式を使用できます。
const mysql = require('mysql2/promise');
async function main() {
const pool = mysql.createPool({
host: 'localhost',
user: 'root',
password: 'mypassword',
database: 'myapp'
});
const [rows] = await pool.query('SELECT * FROM users');
console.log(rows);
const [result] = await pool.query(
'INSERT INTO users (name, email) VALUES (?, ?)',
['새사용자', 'new@example.com']
);
console.log('挿入 ID:', result.insertId);
}
main();mysql2/promise を import すると、すべてのメソッドが Promise を返します。await できれいに使用できます。