お首が長いのよお首が長いのよ

チラシの裏よりお届けするソフトウェアエンジニアとして成長したい人のためのブログ

2018-10-08

express + pugを使ってMariaDB(MySQL)と連携する

前提

  • 予めexpress-generatorなどを用いてexpress環境が出来ている事
  • MySQL環境(データベース、テーブル)は準備済みである事
  • pugのレイアウト分け、インポート等はなんとなく理解した上で分けている事

テストテーブル

手始めにこんな感じのシンプルなテーブルを用意した。

下準備

 mysqlパッケージインストール

npmでmysqlパッケージをインストール

bash
1npm install --save mysql
2

node環境変数にMySQL接続情報をセット

予めnode_envにユーザ名やパスワードを格納しておく。 node.jsの起動時やdotenvを使って記録しておくなど何でもよい。 詳しいことはググって。次の内容からいきなり読み出しています。

app.js

js
1let bodyParser    = require('body-parser');
2let createError   = require('http-errors');
3let express       = require('express');
4let path          = require('path');
5let cookieParser  = require('cookie-parser');
6let logger        = require('morgan');
7let indexRouter   = require('./routes/index');
8let userRouter    = require('./routes/user');
9let mysql         = require('mysql');
10let app           = express();
11
12//--------- ①Database settings-------------
13const db_conf = {
14  host     : 'データベース接続先FQDN or IP addr',
15  user     : process.env.MYSQL_USER,
16  password : process.env.MYSQL_PASS,
17  database : 'test_database'
18}
19const pool = mysql.createPool(db_conf);
20app.set('pool', pool);
21
22//----------------------------------------
23
24app.use(bodyParser.urlencoded({extended: true}));
25
26// view engine setup
27app.set('views', path.join(__dirname, 'views'));
28app.set('view engine', 'pug');
29
30app.use(logger('dev'));
31app.use(express.json());
32app.use(express.urlencoded({ extended: false }));
33app.use(cookieParser());
34app.use(express.static(path.join(__dirname, 'public')));
35
36app.use('/', indexRouter);
37app.use('/user', userRouter);
38
39〜〜〜省略〜〜〜
40module.exports = app;
41

まず、①でデータベースに接続するコンフィグを定義し、mysql.createPoolによってPoolオブジェクトを生成している。app.jsのこの位置に記載する事によってどのリクエストもデータベースとコネクションを開始する。

場合によっては記載する位置を変えて別モジュールから読み出させるなどで、必要に応じてデータベースにつなぎに行く回数を減らしてもいいのかもしれない。というかそうするべきである。

app.setによって各ルーターからコネクションに介入する事が出来る。

index.js

js
1'use strict';
2require('dotenv').config();
3const express = require('express');
4const router = express.Router();
5const date = require('date-utils')
6
7/* GET home page. */
8router.get('/', function(req, res, next) {
9
10  //-------- ②リクエストからDBのコネクション情報を読取る--------
11  const app   = req.app;   
12  const pool  = app.get('pool');
13
14  //---------③クエリを発行 -> テンプレートにレンダリング ------
15  pool.query('SELECT * FROM test_table;', function(error, results, fields){
16    if(error) throw error;
17    res.render('index', { title: 'DB Connect Test, results: results });
18  });
19
20});
21
22module.exports = router;
23

続いてindexルーター。 ②は、①の最後でセットしておいたコネクション情報を読み出し。

③でqueryメソッドを実行する。コールバック関数の2つ目「results」に結果が格納されるので、res.renderの第二引数のオブジェクトに設置してテンプレートエンジンにレンダリングさせる。

index.pug

最後にフロントエンド側。 node.jsでこねくり回したデータ、オブジェクトはここで表示する。 #{results}とすれば[Object object]としか表示されないので、一件ずつ解いていくやり方にした。

pug
1extends layout
2block contents
3  h1.title= title
4  p.subtitle Welcome to #{title}
5  div.columns
6    each row in results  /* ここでループ。DBのresultsで返された件数分rowに格納していく。 */
7      div.box
8        p.row__id ID: #{row.id}  /* rowに渡されたDBカラムの内容は row.{カラム名}で取得できる */
9        p.row__name Name:  #{row.name}
10        p.row__other_name Other_name: #{row.other_name}
11

pugの書き方で each ~ inというのがあって、node.jsでいう for ~ of と同じニュアンスで使えるような記法がある。今回はそれを使って pugで受け取っているオブジェクトを1つずつ取り出し、HTMLに吐き出す事とした。

今までサーバサイドからフロントエンドにデータを受け渡しするのはsocket.ioにJSONオブジェクトとして乗っけてしまえる所に頼ってしまっていたので、res.renderを使ってpugに表示させるやり方の理解に躓いた。

pugもpugで、javascriptが埋め込める分、console.log()とか使ってデバッグをしてもサーバ側でプリントされてしまうのでブラウザコンソールで表示させるのはどうしたらええんやと躓いた。

/以上

よかったらシェアしてください!