2. データベースの導入
mysqlパッケージをインストールする
Node.jsをMySQLに接続するには、mysqlパッケージを利用する必要があります。パッケージのインストールは学習ⅠでExpressを準備した時と同様です。
MySQLに接続しよう
mysqlパッケージを読み込み、createConnectionメソッドを用います。データベースに接続するための情報を定数connectionに代入しましょう。これでMySQLへの接続が完了です。書き方を細かく覚える必要はありません。
ターミナル
npm install mysql
app.js
const express = require(‘express’);
// MySQLを使うためのコードを貼り付けてください
const mysql = require(‘mysql’);
const app = express();
app.use(express.static(‘public’));
// 定数connectionを定義して接続情報の書かれたコードを代入してください
const connection = mysql.createConnection({
host: ‘localhost’,
user: ‘progate’,
password: ‘password’,
database: ‘list_app’
});
3. データベースの利用
クエリを実行するには
connection.query(‘クエリ’, クエリ実行後の処理)と書くことで、Node.jsからデータベースに対してクエリを実行することができます。
クエリ実行後の処理
クエリ実行後の処理は2つの引数を取ることができます。
第1引数のerrorにはクエリが失敗したときのエラー情報が、第2引数のresultsにはクエリの実行結果(ここでは取得したメモ情報)が入ります。
list-app/app.js
「/index」に対応するルーティングの中で、connection.queryを用いてください。
また、第1引数にitemsテーブルから全レコードを取得するクエリを指定してください。
ヒント
クエリを実行するには、
connection.query(‘クエリ’, クエリ実行後の処理);
のように記述します。
テーブルから全レコードを取得するには、
SELECT * FROM テーブル名
のように記述します。
connection.queryの第2引数にクエリ実行後の処理を指定してください。
ヒント
クエリ実行後の処理は以下のように書きます。
connection.query(
‘クエリ’,
(error, results) => {
// 処理
}
);
app.get(‘/index’, (req, res) => {
// データベースからデータを取得する処理を書いてください
connection.query(
‘SELECT * FROM items’,
(error, results) => {
console.log(results);
res.render(‘index.ejs’);
}
);
// 下記のコードを削除してください
});
4. 取得した値の表示EJSに値を渡す
EJSはrenderメソッドから値を受け取ることができます。renderメソッドの第2引数に{プロパティ : 値}と書くことで、EJS側に値を渡すことができます。今回はデータベースから取得した値を使いましょう。
app.js
app.get(‘/index’, (req, res) => {
connection.query(
‘SELECT * FROM items’,
(error, results) => {
// res.renderの第2引数にオブジェクトを追加してください
res.render(‘index.ejs’, {items: results});
}
);
});
5. 作成画面の作成
手順
まずは作成画面を表示できるようにしましょう。
手順は以下の通りです。
①URLに対応するルーティングを用意
②ルーティングの処理の中でビューファイルを指定
③ビューファイルを用意
①②
app.js
// 作成画面を表示するルーティングを作成してください
app.get(‘/new’, (req, res) => {
res.render(‘new.ejs’);
});
③
new.ejs 作成
④一覧画面に作成画面へのリンクを作成しましょう。
index.ejs
+ 新規作成
6. フォームを使ったリクエスト
メモ作成のルーティングを用意しよう
メモ作成用のルーティングを作ります。今まではapp.getを使っていましたが、今回はapp.postを使いましょう。このgetやpostはメソッドと呼ばれるもので、リクエストの種類を表します。詳しくは次のスライドで説明します。
getとpostとは
Webでは、サーバーへリクエストするときに、どんな処理をしたいかをメソッドで伝えるようにルールで決まっています。getメソッドやpostメソッドは、それぞれ下図のような処理をしたい時に使います。
getメソッド⇒画面を表示したいとき
postメソッド⇒データベースを変更したいとき
フォームを用意しよう
フォームを作るときはHTMLの
7. フォームの値の受け取り
フォームの値を受け取る
準備をしよう(1)
input要素にname属性を指定すると、右の図のようなオブジェクトの形で情報がサーバーに送信されます。よってサーバー側ではreq.body.name属性の値でフォームの値を取得できます。
フォームの値を受け取る
準備をしよう(1)
input要素にname属性を指定すると、右の図のようなオブジェクトの形で情報がサーバーに送信されます。よってサーバー側ではreq.body.name属性の値でフォームの値を取得できます。
フォームの値を受け取る
準備をしよう(2)
フォームの値を受け取るにはapp.jsで下図のソースコードを追加する必要があります。
new.ejs
app.js
app.use(express.static(‘public’));
// フォームから送信された値を受け取れるようにしてください
app.use(express.urlencoded({extended: false}));
app.post(‘/create’, (req, res) => {
// フォームから送信された値を出力してください
console.log(req.body.itemName);
connection.query(
‘SELECT * FROM items’,
(error, results) => {
res.render(‘index.ejs’, {items: results});
}
);
});
買うもの
8. データベースへの追加
データを追加する
SELECTの時と同様にqueryメソッドを使うことで INSERTを実行することができます。itemsテーブルのidにはAUTO INCREMENTを設定しているので、idの値を指定する必要はありません。
メモ内容を追加しよう
フォームからの値をクエリに使うときは、VALUESに「?」を含めます。次
に「connection.query()」の第2引数に渡したい配列を指定します。この配列の要素が「?」の部分に入り、実行されます。
ヒント
テーブルにデータを追加するには、
INSERT INTO テーブル名 (カラム名) VALUES (追加する値)
のように記述します。
ヒント
フォームから受け取った値は、req.body.itemNameで取得することができます。
// データベースに追加する処理を書いてください
connection.query(
‘INSERT INTO items (name) VALUES (?)’,
[req.body.itemName],
(error, results) => {
connection.query(
‘SELECT * FROM items’,
(error, results) => {
res.render(‘index.ejs’, {items: results});
}
);
}
);
// 以下の一覧画面表示の処理を削除してください
// ここまで削除してください
});
9. リダイレクトの活用
なんでリロードをするとメモが増えてしまうんだろう…。
リロードは直前のリクエストを実行する機能なのじゃ。そのため、一覧表示と一緒に追加処理も実行されてしまうのじゃよ。
どうすればよいのでしょうか?
この問題を解決するために、リダイレクトという新しい知識を学ぼう。
リダイレクトとは
サーバーは「次はこのURLにリクエストしてね」というレスポンスを返すことができます。このレスポンスを受け取ったブラウザは指定されたURLに自動的にリクエストします。このような別のURLに再度リクエストさせる仕組みをリダイレクトと言います。
リダイレクト後のリロード
リダイレクトを用いると、追加処理後に/indexにリクエストして一覧画面を表示することができます。これによりメモ作成後にリロードしても、追加処理が実行されないのでメモが増えません。
リダイレクトの使い方
メモ追加後に一覧画面(/index)にリダイレクトするようにしましょう。リダイレクトするにはres.redirectメソッドを用い、引数にURLを指定します。
リダイレクトの使いどころ
リダイレクトを使う場面はいくつかありますが、よくあるのは今回のようにpostメソッドでリクエストした時です。こういう時はres.renderではなくres.redirectを使って、getのルーティングにリダイレクトしてあげましょう。
app.post(‘/create’, (req, res) => {
connection.query(
‘INSERT INTO items (name) VALUES (?)’,
[req.body.itemName],
(error, results) => {
// 下記のコードを削除してください
// ここまで削除してください
// 一覧画面にリダイレクトしてください
res.redirect(‘/index’);
}
);
});