Help us understand the problem. What is going on with this article?

Express 4 で MySQL に接続

More than 5 years have passed since last update.

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() の引数は、それを受け取るエラーハンドラが対応している限り、任意のオブジェクトでも大丈夫のようです。

リンク

https://github.com/felixge/node-mysql

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away