Node.jsとデータベースを接続しよう - osamu38/node-express-curriculum GitHub Wiki
- フォームをつくろう
- フォームからデータを受け取ろう
- 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>
<!-- 中略 -->
これでリクエストを送るためのフォームができましたね。
form
のaction
というのはリクエストを送るURLです。今回だと/
です。
form
のmethod
というのはリクエストを送るときの形式です。今回だと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);
の下に書けば終わります。
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();
について説明します。connection
のquery
メソッドは第一引数にMySQLのクエリー、第二引数にcallback関数をとります。この第一引数のクエリーを実行することによって、データがデータベースに蓄積されます。そしてcallback関数が実行されます。
callback関数内ではres.redirect('/');
をしています。res.redirect()
は第一引数にURLをとります。そしてこのURLに移動するだけです。今回だと'/'
なのでlocalhost:3000/
に移動するだけですね!
では実際に動かしてみましょう。
ボード作成を押して、Sequel Proを見てみると、、、
おお!データベースにデータを追加することができました!意外と簡単でしたかね?練習も兼ねて追加で3件ぐらい投稿してみてください。
前のページ:MySQLを使ってデータベースを構築しよう