某クラウドソーシング経由で「問い合わせからデータを自動取得してほしい」という依頼が来ました。
NodeでNoSQLを触ることはあってもMySQLを触ったことはなかったので、どうすればいいのか勉強がてら試してみたので、やり方を紹介します。
NodeでMySQLを使うためには
NodeでMySQLを使うためにはmysqlというライブラリがあるので、そちらを利用しました。
ちなみに、node-mysql2という別のライブラリもあります。使い方はそのままで、より高速に動作するようです。
また、Nodeのサーバーサイドライブラリとしてはexpressを採用しています。
今回は、formから値を取得してデータを格納する処理を記載しています。
Node+MySQLでクライアント側からデータを扱うには
今回扱わなかったのは、クライアント側でDBからデータを取得して画面にデータを表示させるということです。
こちらは、socket.ioを使えば実装可能のようですが、サーバー側からデータをクライアントに送れば実現可能(なはず)なので、expressでも同様のことができるはずですがまたの機会で調査してみようと思います。
Node+MySQLのコード:クライアント側
まずはクライアント側のコードを下記のようにしています。
<!-- 省略 -->
<body>
    <div id="wrapper">
        <form action="/" method="post">
            <p>
                <label for="name">name: </label>
                <input type="text" name="name" required /><br>
            </p>
            <p>
                <label for="title">title: </label>
                <input type="text" name="title" required /><br>
            </p>
            <p>
                <label for="body">body: </label>
                <input type="text" name="body" required /><br>
            </p>
            <button type="submit" class="submit">submit</button>
        </form>
    </div>
</body>
<!-- 省略 -->name, title, formを取得する非常にシンプルなコードです。
特にここは説明が不要かと思います。
Node+MySQLのコード:サーバー側
続いてサーバー側のコードを見ていきましょう。
// 省略
 
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
 
app.get('/', (req, res) => {
    res.render('./index');
});
 
app.post('/', (req, res) => {
    try {
        controller(req.body.name, req.body.title, req.body.body);
        res.render('./index');
    } catch (e) {
        alert(e);
        res.end();
    }
});
 
app.listen(3000);こちらの
app.get('/', (req, res) => {
    res.render('./index');
});この部分はgetでアクセスされた際にindex.ejs(前章のhtml)を表示するだけなので、それほど難しくはないと思います。
一方、
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
 
app.post('/', (req, res) => {
    try {
        controller(req.body.name, req.body.title, req.body.body);
        res.render('./index');
    } catch (e) {
        alert(e);
        res.end();
    }
});こちらのpostの部分はformでデータを入力してアクセスされた場合に実行されます。
expressのpost処理では、bodyParserを利用しないとreqの中身がundefinedになってしまいます。
クライアント側のinputタグのname属性がそれぞれname、title、bodyとなっているので、req.body.[name属性]とすることによってformからのデータを取得することができます。
Node+MySQLのコード:データベース
上記のコードを見るとcontrollerにformから取得したデータを渡していますが、単純にデータベース処理を行うmodelのメソッドを呼び出しているだけです。
なので、modelファイルの処理を見ていくことにします。
const connection = require('../database/database');
 
const formInsert = (name, title, body) => {
    const query = 'insert into form_content set ?';
    connection.query(query, { name: name, title: title, body: body }, (err, rows) => {
        if (err) throw new Error('データの登録に失敗しました');
    });
};
 
module.exports.formInsert = (name, title, body) => formInsert(name, title, body);データベースにデータをinsertするformInsertメソッドを記述しています。
また、1行目にmysqlの設定をいろいろ記述しているdatabase.jsの中身は下記のようになっています。
const mysql = require('mysql');
const env = require('dotenv');
 
env.config();
 
const config = {
    host: process.env.DATABASE_HOST,
    user: process.env.DATABASE_USER,
    password: process.env.DATABASE_PASSWORD,
    database: process.env.DATABASE,
    port: process.env.DATABASE_PORT,
};
 
module.exports = mysql.createConnection(config);database.jsでは、.envファイルからデータベースのhostやuserといった設定値を読み込むようにしています。
そしてライブラリのcreateConnectionメソッドを実行しているだけなので、非常にシンプルかと思います。
話をformInsertメソッドに戻しますが、SQLのqueryを作成して実行しているだけということがわかります。
escape処理はどうなっているのか?と気になるかもしれませんが、connection.queryの第二引数に値を指定してあげることで、自動でescapeされるみたいです。便利なものですね。
まとめ
今回はNodeでMySQLを触ってみる作業をしてみましたが、ぶっちゃけNoSQLの方が処理が楽な気がしています。
とはいえNodeでMySQLを使用しなければならない場面もあると思うので、少しでも参考になれば幸いです。

