このエントリーをはてなブックマークに追加
はてなブックマーク - Node.js で MySQL
Share on Facebook
Post to Google Buzz
Bookmark this on Yahoo Bookmark
Bookmark this on Livedoor Clip
Share on FriendFeed
Node.js で MySQLあらかたは回帰、きまぐれは彷徨

Node.jsとMySQLをつなぐためのプラグインは数種類ある。

  • node-mysql — A node.js module implementing the MySQL protocol
  • node-mysql-native — Mysql client module for node.js, written in JavaScript. No other mysql runtime required.
  • node-mysql-libmysqlclient — MySQL bindings for Node.js using libmysqlclient.
  • node-mysql-pool — MySQL connection pool for node.js on top of Felix Geisendörfer’s MySQL client node-mysql.

今回は、node-mysqlを使う。node-界隈は、同じようなことをできる同じようなパッケージがわらわらあるので、よくわかんない時は、とりあえず一番活発なやつ使えば、まあ、よいと思う。笑

sudo npm install

npm install mysql
mysql@0.9.4 ./node_modules/mysql
└── hashish@0.0.4

まずは基本的な設定から

var mysql = require('mysql');
var TEST_DATABASE = 'nodejs_mysql_test';
var TEST_TABLE = 'test';
var client = mysql.createClient({
  user: 'mysqluser',
  password: 'password',

  host: foo.bar

  database: sample

});

接続の設定は、createClientの引数に設定してやってもいいし、


client.host = "foo.bar";

client.database = "sample";

みたいな感じに、メソッドでもいける。他にもあるけれど、詳細は、git/node-mysqlで。

queryを投げるには、cakePHPなどでやるように


client.query('USE sample_table');

みたいにそのままSQL文を書いてやる。

client.query(
  'INSERT INTO '+TEST_TABLE+' '+
  'SET title = ?, text = ?, created = ?',
  ['super cool', 'this is a nice text', '2010-08-16 10:00:23']
);

そのまま変数に突っ込む事も可能だけれど、サニタイズしないといけないので、?で項目を指定しておいて、二つ目の引数に値を配列にまとめて入力している。

node-mysqlクライアントオブジェクトはこれ(質問に対して)を支援することのできるエスケープメソッドを持っています。自分でそれを呼び出すこともできるし、そのパラメータを受け入れるqueryの形式を使うこともできます。たとえば、

client.query('SELECT id, user_name FROM user WHERE email=?',

    [req.body.login], ...

The node-mysql Client object has an escape method that can help with this. You can either call that manually, or use the form of query that accepts parameters. E.g:

client.query('SELECT id, user_name FROM user WHERE email=?',

    [req.body.login], ...

http://stackoverflow.com/questions/5878266/using-mysql-with-nodejs-and-express-node-mysql

たぶん…とは思ってて調べてなかったのだけれど、どうやらエスケープメソッドで、ちゃんとサニタイズしているらしい。

insertやupdateはこれだけでもよいのだが、selectの場合は結果を返す変数が欲しいので、1つ目でselect文、二つ目の引数にコールバック関数を指定してやる。

client.query(
  'SELECT * FROM '+TEST_TABLE,
  function selectCb(err, results, fields) {
    if (err) {
      throw err;
    }

    console.log(results);
    console.log(fields);
//    client.end();
  }
);

で、僕が使ったときにはまってしまったのはここのポイント

client.end();

一度client.end()してしまうと、MySQLとの通信を終了してしまうので、それ以後全く通信できなくなる。end()メソッドをちゃんと理解してなかったのが悪いんだけど…

client.end([callback])
接続を閉じるためにCOM_QUITパケットをスケジュールに組み込みます。コネクションの華麗な切断を試みる前に、すべての投げられたqueryが実行されます。
Schedule a COM_QUIT packet for closing the connection. All currently queued queries will still execute before the graceful termination of the connection is attempted.

ちなみにこんなのもある。

client.destroy([callback])
クライエントに対し直ちに接続を切断させます。これは接続を切断する方法としてはあまり良い方法ではありません。きをつけて使ってください。
Forces the client connection to be destroyed right away. This is not a nice way to terminate the connection, use with caution.

ので、何度も通信する必要があるものは、不用意にclient.end()してはいけない。