404 Not Found

404 Not Found


nginx

実践的な開発:Node.jsとMySQLの連携

フロントエンド開発者がバックエンド開発を学ぶには、Node.js と MySQL から始めるのが最適です。

このレッスンでは、Node.js を使って MySQL を操作する方法について解説します。

100%
graph TB
    A[Node.js Applications] --> B[mysql2 Driver]
    B --> C[Connection Pool]
    C --> D[Get the link]
    D --> E[Parametric Queries]
    E --> F{Operation Type}
    F -->|Search| G[execute SELECT]
    F -->|Insert| H[execute INSERT]
    F -->|Update| I[execute UPDATE]
    F -->|Delete| J[execute DELETE]
    F -->|Transactions| K[beginTransaction]
    K --> L[commit / rollback]
    D --> M[Release the connection back to the pool]

1. 学習内容


2. 実話

(1) 課題:SQLは学んだものの、プロジェクトでどのように活用すればよいか分からない

SQLを学んだフロントエンド開発者は、Node.jsを使ってバックエンドのコードを書く際に、しばしば途方に暮れてしまいます。SQL文字列を手動で連結するとインジェクション攻撃の標的になりやすく、接続管理が不十分だとデータベース接続が枯渇してしまい、ネストされた非同期コールバックによってコードの保守が困難になるからです。

(2) MySQL 2 以降向けの接続プールとパラメータ化クエリの解決策

mysql2 ドライバー(Promises をサポート)を使用し、接続プール機能で接続を管理し、パラメータ化されたクエリを用いてインジェクション攻撃を防止してください。

ディメンション 手動でのSQL構築 MySQL 2+ 接続プール
SQLインジェクションのリスク 極めて高い ゼロ(パラメータ化されたクエリ)
接続管理 非管理型(接続が枯渇する可能性がある) 自動管理(プール化および再利用)
コーディングスタイル コールバック地獄 async/await
本番環境対応

3. 設置と接続

▶ 例:mysql2 のインストール

BASH
npm install mysql2

▶ 例:接続の作成

JAVASCRIPT
const mysql = require('mysql2/promise');

async function main() {
    const connection = await mysql.createConnection({
        host: 'localhost',
        user: 'root',
        password: 'Root123!',
        database: 'mydb'
    });
    
    const [rows] = await connection.execute('SELECT VERSION()');
    console.log(rows);
    
    await connection.end();
}

main();
▶ 試してみよう

4. コネクションプール

JAVASCRIPT
const pool = mysql.createPool({
    host: 'localhost',
    user: 'root',
    password: 'Root123!',
    database: 'mydb',
    waitForConnections: true,
    connectionLimit: 10,
    queueLimit: 0
});

// Querying Using a Connection Pool
const [rows] = await pool.execute('SELECT * FROM users WHERE id = ?', [1]);

5. CRUD操作

▶ 例:データの照会

JAVASCRIPT
// Search All Users
const [users] = await pool.execute('SELECT * FROM users');

// Conditional Query
const [user] = await pool.execute(
    'SELECT * FROM users WHERE id = ?', 
    [userId]
);
▶ 試してみよう

▶ 例:データの挿入

JAVASCRIPT
const [result] = await pool.execute(
    'INSERT INTO users (username, email) VALUES (?, ?)',
    ['alice', 'alice@email.com']
);
console.log(result.insertId);
▶ 試してみよう

▶ 例:データの更新

JAVASCRIPT
const [result] = await pool.execute(
    'UPDATE users SET email = ? WHERE id = ?',
    ['new@email.com', 1]
);
console.log(result.affectedRows);
▶ 試してみよう

▶ 例:データの削除

JAVASCRIPT
const [result] = await pool.execute(
    'DELETE FROM users WHERE id = ?',
    [1]
);
console.log(result.affectedRows);
▶ 試してみよう

6. SQLインジェクションの防止

(1) エラー:文字列の連結

JAVASCRIPT
// Danger! SQL injection
const sql = `SELECT * FROM users WHERE username = '${username}'`;

(2) 正解:パラメータ化されたクエリ

JAVASCRIPT
// Safe: Parameterized query
const [rows] = await pool.execute(
    'SELECT * FROM users WHERE username = ?',
    [username]
);

7. トランザクションのカプセル化

JAVASCRIPT
async function transfer(fromId, toId, amount) {
    const conn = await pool.getConnection();
    
    try {
        await conn.beginTransaction();
        
        await conn.execute(
            'UPDATE accounts SET balance = balance - ? WHERE id = ?',
            [amount, fromId]
        );
        
        await conn.execute(
            'UPDATE accounts SET balance = balance + ? WHERE id = ?',
            [amount, toId]
        );
        
        await conn.commit();
        return { success: true };
    } catch (error) {
        await conn.rollback();
        return { success: false, error: error.message };
    } finally {
        conn.release();
    }
}

8. ORMの概要

ORM 説明
Sequelize 充実した機能を備えた老舗のORM
Prisma 次世代の型ベースのセキュリティ
TypeORM TypeScriptへの優れた対応
Knex.js クエリビルダー
JAVASCRIPT
// Prisma Example
const users = await prisma.user.findMany({
    where: { status: 'active' },
    include: { orders: true }
});

❓ よくある質問

Q mysql と mysql2 のどちらを使うべきですか?
A mysql2 をお勧めします(Promises をサポートしており、パフォーマンスも優れています)。
Q 接続プールのサイズはどのように設定すべきですか?
A 通常は10~20ですが、同時接続数に応じて調整します。
Q ORMはどのような場合に使うべきですか?
A 複雑なプロジェクトでは開発を簡略化するためにORMを使用し、単純なプロジェクトでは柔軟性を高めるためにネイティブSQLを使用します。
Q mysql と mysql2 の違いは何ですか?
A mysql はコールバックのみをサポートする旧式のドライバーですが、mysql2 は Promise をサポートし、パフォーマンスも向上しています。mysql2 の使用をお勧めします。
Q 接続プールのサイズはどう設定すべきですか?
A 計算式は「CPUコア数 × 2 + ディスク数」です。一般的なWebアプリケーションの場合、10~20で十分です。

📖 まとめ


📝 練習問題

  1. 基本問題(難易度:⭐):Node.js を使用して MySQL に接続し、データベースをクエリして、ユーザーの一覧を出力してください。

  2. 上級演習(難易度:⭐⭐):完全なCRUD API(作成、読み取り、更新、削除)を実装してください。

  3. 課題(難易度:⭐⭐⭐):取引やエラー処理を含む、資金移動機能を実装してください。

Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%