Skip to content

Node.jsとデータベースを接続しよう

osamu38 edited this page Aug 17, 2018 · 31 revisions

Node.jsとデータベースを接続しよう

目次

  • フォームをつくろう
  • フォームからデータを受け取ろう
  • Moment.jsで日付を取得してみよう
  • データベースと接続しよう

フォームをつくろう

データベースとのやりとりをする前にHTML側でリクエストを送るためのフォームを作りましょう。

views/index.ejsを以下のように書き換えます。

<!-- 中略 -->
<body>
<div class="wrapper">
  <form action="/" method="post" class="board-form">
    タイトル: <input type="text" name="title" class="input" required><br>
    <br>
    <button type="submit" class="submit">ボード作成</button>
  </form>
</div>
</body>
<!-- 中略 -->

これでリクエストを送るためのフォームができましたね。

formactionというのはリクエストを送るURLです。今回だと/です。

formmethodというのはリクエストを送るときの形式です。今回だとpostです。

フォームからリクエストを受け取ろう

routes/index.jsを開いてください。

var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

module.exports = router;

前にも説明しましたがここではルーティングと呼ばれる、どのURLにリクエスト(GET or POST)がきたときに何をするか(関数)を定義しています。 routerにはgetメソッドやpostメソッドがあり、第一引数にURL、第二引数にcallback関数をとります。

ここでは/というURL(localhost:3000/)にgetリクエストがきたときにcallback関数を実行するという流れです。

では内部の処理を見てみましょう。

res.render('index', { title: 'Express' });とかいてあります。resがでてきましたが、こいつはcallback関数の第二引数に渡されたオブジェクトです。試しにconsole.log(res);をしてみると大量のプロパティやメソッドをもっているのがわかると思います。

このresにはrenderメソッドがあり、第一引数にViewファイル、第二引数にオブジェクトをとります。renderは第一引数に渡したViewファイルに対して第二引数のオブジェクトを渡した状態で描画するメソッドです。

ちなみにViewファイルはviewsフォルダの中の~.jsです。この~の部分を第一引数に渡してあげましょう。なぜこのフォルダと紐付いているかというと、app.jsの13行目のapp.set('views', path.join(__dirname, 'views'));viewsをViewフォルダとして設定しているからです。

ではこのソースにpostされた場合の処理を追加してみましょう。

routes/index.jsを以下のように書き換えます。

// 中略
/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

router.post('/', function(req, res, next) {
  var title = req.body.title;
  console.log(title);
});
// 中略

フォームから送られたリクエストはreq.body.[name属性]といった形で取得することができます。今回の場合はinputタグのname属性はtitleなので、req.body.titleで取得することができます。そのパラメータをconsole.logでターミナルに出力するといった流れです。

実際にフォームに値を入力してボード作成を押したあとにサーバーで値が取得されているか見てみましょう。

ちゃんとGizumoという文字列が取得できていますね!クライアント(index.ejs)で作ったフォームからサーバーに値を送ることができました。

ちなみに今の状態だとブラウザ側でずっと読み込み中になると思いますが、これはPOSTリクエストが終わっていないためです。もしリクエストを単純に終えたい場合はres.end();console.log(title);の下に書けば終わります。

Moment.jsで日付を取得してみよう

boardsテーブルにはtitle以外にもcreated_atというDATETIME型のカラムもあるので次はこの部分をやってみます。

まずDATETIME型がよくわかってないと思うのでどのような型かと言いますと2015-12-09 21:11:47ような形式の日付の型です。

JavaScriptでは日付を取得することはできますが、このような形に整形するのは少し面倒なので、日付用のライブラリMoment.jsを導入しましょう。

$ npm i -S moment

routes/index.jsを以下のように書き換えます。

var express = require('express');
var router = express.Router();
var moment = require('moment'); // 追加

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

router.post('/', function(req, res, next) {
  var title = req.body.title;
  var createdAt = moment().format('YYYY-MM-DD HH:mm:ss'); // 追加
  console.log(title);
  console.log(createdAt); // 追加
});

module.exports = router;

$ npm install --save momentしたあとにvar moment = require('moment');でinstallしたライブラリを使用することができます。

そしてvar createdAt = moment().format('YYYY-MM-DD HH:mm:ss');でDATETIME型の現在時刻が取得できます。

このような形で取得できていれば大丈夫です。Node.jsではnpmを使うことによって簡単に他のライブラリを使用することができます。

あとはboardsテーブルにはboard_idというのカラムもあるのですが、これはデータの挿入時に勝手に追加されるカラムなので、気にしないで大丈夫です。

データベースと接続しよう

Node.jsでデータベース(MySQL)に接続するためには接続するためのライブラリをいれてあげないといけません。なのでmysqlというライブラリを入れましょう。

$ npm install --save mysql

これでmysqlライブラリを使用する準備はできましたが、接続するための関数は様々な箇所で使うため汎用的な関数にしなければいけません。 なので今回はmysqlConnection.jsという自前のjsファイルを作成し、それをroutes/index.jsでrequireできるような形で実装しましょう。

汎用的なデータベース接続モジュールを作成しよう

mysqlConnection.jsを作成します。

var mysql = require('mysql');

var dbConfig = {
  host: '127.0.0.1',
  user: 'root',
  password: '',
  database: 'bulletin_board'
};

var connection = mysql.createConnection(dbConfig);

module.exports = connection;

先ほどvar moment = require('moment')したようにvar mysql = require('mysql')をします。これでnpmでインストールしたmysqlが使えるようになります。

そしてmysql.connection()でデータベースの情報をオブジェクトにして引数に渡し、その返り値をconnectionという変数に代入します。

最後にmodule.exports = connection;で外部からrequireできる形にします。

これでmysqlConnection.jsは完成です。データベースに接続するモジュールが完成しましたね!

データベースにデータを入れてみよう

routes/index.jsを以下のように書き換えます。

// 中略
var moment = require('moment');
var connection = require('../mysqlConnection'); // 追加

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

router.post('/', function(req, res, next) {
  var title = req.body.title;
  var createdAt = moment().format('YYYY-MM-DD HH:mm:ss');
  var query = 'INSERT INTO boards (title, created_at) VALUES ("' + title + '", ' + '"' + createdAt + '")';
  connection.query(query, function(err, rows) {
    res.redirect('/');
  });
});

module.exports = router;

では作ったmysqlConnection.jsをさっそく利用しましょう。

var connection = require('../mysqlConnection'); このようにrequireで呼び出すことができます。しかし今回の場合は自作したモジュールなのでrequireするときにパスを通してあげないといけないです。routes/index.jsから見てmysqlConnection.jsはひとつ上の階層なのでrequire('../mysqlConnection');のようにしてパスを通してあげましょう。また.jsの部分は省略できます。

データベースに接続する前にMySQLのクエリーを作りましょう。クエリーの書き方は既に勉強していると思うので割愛しますが、素でMySQLを書くのと違い、文字列を+を使って結合します。

ではconnection.query();について説明します。connectionqueryメソッドは第一引数にMySQLのクエリー、第二引数にcallback関数をとります。この第一引数のクエリーを実行することによって、データがデータベースに蓄積されます。そしてcallback関数が実行されます。

callback関数内ではres.redirect('/');をしています。res.redirect()は第一引数にURLをとります。そしてこのURLに移動するだけです。今回だと'/'なのでlocalhost:3000/に移動するだけですね!

では実際に動かしてみましょう。

ボード作成を押して、Sequel Proを見てみると、、、

おお!データベースにデータを追加することができました!意外と簡単でしたかね?練習も兼ねて追加で3件ぐらい投稿してみてください。

前のページ:MySQLを使ってデータベースを構築しよう

次のページ:Node.jsでデータベースからデータを取得して表示させてみよう