LoginSignup
94
94

More than 5 years have passed since last update.

Express 4 で MySQL に接続

Last updated at Posted at 2014-04-15

Express 4 から MySQL に接続してみました。

なお、コードは github にあります。(mysql ブランチに移動しました。)
https://github.com/hoshi-takanori/express-sample/tree/mysql

準備

あらかじめ MySQL に適当なデータベースとユーザーを作っておきます。

$ mysql -u root -p
Enter password: ********
mysql> create database test_db;
mysql> grant all on test_db.* to test_user@localhost;
mysql> set password for test_user@localhost=password('test_password');
mysql> exit
Bye
$ 

また、テスト用のテーブルとデータを作成します。

sql/table.sql
create table users (
    name varchar(255) primary key,
    email text not null
);
sql/test_data.sql
insert into users values ('admin', 'admin@example.com');
insert into users values ('user1', 'user1@example.com');
insert into users values ('user2', 'user2@example.com');
$ mysql -u test_user -p test_db
Enter password: test_password
mysql> source sql/table.sql;
mysql> source sql/test_data.sql;
mysql> select * from users;
+-------+-------------------+
| name  | email             |
+-------+-------------------+
| admin | admin@example.com |
| user1 | user1@example.com |
| user2 | user2@example.com |
+-------+-------------------+
3 rows in set (0.00 sec)

mysql> exit
Bye
$ 

とりあえず接続

まず、MySQL に接続するためのパッケージを package.json に追加します。

package.json
{
  ...
  "dependencies": {
    "express": "*",
    "jade": "*",
    "mysql": "*"
  }
}

次に、app.js を編集します。

app.js
var express = require('express');
var mysql = require('mysql');
var app = express();

var connection = mysql.createConnection({
  host: process.env.DB_HOST || 'localhost',
  user: process.env.DB_USER || 'test_user',
  password: process.env.DB_PASS || 'test_password',
  database: process.env.DB_NAME || 'test_db'
});

...

これで、node app 起動時に MySQL に接続するようになります。
なお、接続先 DB の情報は環境変数で与えることもできます。

run.sh
#!/bin/sh

export DB_HOST="localhost"
export DB_USER="test_user"
export DB_PASS="test_password"
export DB_NAME="test_db"

node app

DB アクセス

実際に DB にアクセスするには connection の query メソッドを使います。もちろん非同期です。

app.js
...

app.get('/users', function (req, res) {
  connection.query('select * from users', function (err, rows) {
    res.render('users', { title: 'Express Users', users: rows });
  });
});

...
views/users.jade
doctype html
html
  head
    meta(charset='utf-8')
    title= title
    link(rel='stylesheet', href='/css/style.css')
  body
    h1= title
    table(border=1)
      tr
        th name
        th email
      - each user in users
        tr
          td= user.name
          td= user.email
public/css/style.css
...

table {
  border-collapse: collapse;
}

th, td {
  padding: 4px;
}

接続プール

とりあえずこれで動きますが、某レンタルサーバーで動かした場合、しばらく放っておくとエラーになりました。どうやら MySQL の接続がタイムアウトしてしまうようです。
そこで、接続プール機能を利用することにします。そうすると、接続を自動的にプールして使い回してくれる上に、接続がタイムアウトした場合は自動的に接続プールから削除されるようです。

app.js
...

var pool = mysql.createPool({
  host: process.env.DB_HOST || 'localhost',
  user: process.env.DB_USER || 'test_user',
  password: process.env.DB_PASS || 'test_password',
  database: process.env.DB_NAME || 'test_db'
});

...

app.get('/users', function (req, res) {
  pool.query('select * from users', function (err, rows) {
    res.render('users', { title: 'Express Users', users: rows });
  });
});

...

接続プールとかよく分かってませんが、これでいいのかなぁ。
さらに、プールクラスターなんてものまであるようです。

エラー処理

エラーが発生した場合は next(err); を呼ぶとエラーハンドラが呼ばれます。
なお、エラーハンドラとは app.use() で設定した引数が 4 個の関数のことです。

app.js
...

app.get('/users', function (req, res, next) {
  pool.query('select * from users', function (err, rows) {
    if (err) return next(err);
    res.render('users', { title: 'Express Users', users: rows });
  });
});

app.use(function (err, req, res, next) {
  res.send(500, 'Error: ' + err.message);
});

...

ちなみに、next() の引数は、それを受け取るエラーハンドラが対応している限り、任意のオブジェクトでも大丈夫のようです。

リンク

94
94
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
94
94