Node.js/ExpressでPostgreSQLを使おう (5/6)
作成:2013-07-06 09:55
更新:2015-08-13 14:22
更新:2015-08-13 14:22
■indexでテーブルの一覧を表示する
では、スクリプトを作成していきましょう。まずはトップページ(「/」アドレス)からです。これは、「routes」フォルダ内の「index.js」ファイルとして処理を用意します。表示用のテンプレートは、「views」フォルダ内に「index.ejs」として作成しておきます。
下のリスト欄に、それぞれのファイルのソースコードを掲載しておきました。記述して指定のフォルダ内にファイルを配置しておいてください。
このままでは動きませんよ! ★のテキストを、それぞれの環境に合わせて書き換えて下さい。デフォルトではデータベース名も管理者名もpostgresになっていますから、パスワードをhogeにしてあったならば、こんな感じに設定すればいいでしょう。
これで、mydataにあるデータを全て取得し、テーブルにまとめて表示します。ただし、まだ/addと/createを作ってないので、この段階で実行してもうまく動かないでしょう。最後まで完成してから表示を確かめて下さい。
では、ソースコードの説明をしましょう。Node.jsのpgを使ってデータベースアクセスを行う基本について順に説明していきます。
●データベースに接続する
データベースへの接続は、pg.connectというメソッドを使います。これは第1引数に接続先のアドレスを、第2引数には接続が開始されてから実行されるコールバック関数を指定します。サンプルのスクリプトでは、以下のように記述しています。
接続先は、tcpというプロトコルのテキストで用意します。利用者、パスワード、ホスト、ポート番号、データベースといった情報を一つにまとめて記述するので、書き方を間違えないように注意して下さい。
connectは非同期関数で、接続が完了したところで引数の関数を呼び出して実行します。このコールバック関数は、2つの引数を用意します。第1引数にはエラーが発生した時の情報をまとめたオブジェクトが、また第2引数には接続したデータベースへのアクセスを管理するClientというオブジェクトが返されます。
●SQLクエリーを実行する
接続したデータベースを操作するには、Clientの「query」メソッドを使います。これは、SQL文をデータベースに送って実行するためのものです。引数にはSQLのクエリーテキストを指定します。
SQL文では、selectのように値を取得する処理もありますが、このqueryメソッドそのもので返値を返すわけではないので注意が必要です。このqueryメソッドは、非同期でアクセスを行います。このため、実行結果となる返値でデータを受け取れるわけではないのです。
では、何が返値として返されるのか? それは、「Query」というオブジェクトです。このQureryには、処理の実行状況に応じて発生するイベントハンドラが用意されており、これを利用して処理を行うのです。
サンプルのリストを見てみましょう。まず以下のようにしてselect文を実行し、そのQueryを変数に取得しています。
このqueryでは、第2引数に実行後の処理をコールバック関数として指定することもできるのですが、ここでは単にクエリーを実行するだけの使い方で説明をします。――このqueryを実行後、返されるQueryオブジェクトのイベントを設定します。このイベントは全部で3種類用意されています。それぞれ以下のようにして設定を行います。
・rowの取得イベント
selectなどレコードを取得するクエリーを実行したとき、レコードを取得するごとにこのrowイベントが発生し処理が呼び出されます。引数rowには、取得したレコードをオブジェクトにまとめたものが保管されます。
・終了イベント
すべての処理が完了したときに呼び出されます。引数には、クエリー実行に関する各種の情報をまとめたResultオブジェクトが渡されます。
・エラーイベント
エラーが発生した際に呼び出されます。ただし、queryメソッドを呼び出す際にコールバック関数を設定してあった場合は、そちらが優先され、このイベントは発生しないので注意ください。
この3つのイベントを組み合わせることで、クエリー実行後の処理を構築できます。サンプルのスクリプトでは、rowイベントで、取得されたrowオブジェクトを配列に追加し保存しています。こうすることで、取得されたすべてのrowデータをひとまとめにできます。
また、注目して欲しいのは、index.jsのレンダリングのタイミングです。ここでは、endイベントが発生したところでrenderで表示をレンダリングしていることがわかります(他、error時にも行なっていますが……)。このように、処理が完了したところで表示をレンダリングしないと、うまく結果を取り出して表示することができないので注意しましょう。
下のリスト欄に、それぞれのファイルのソースコードを掲載しておきました。記述して指定のフォルダ内にファイルを配置しておいてください。
このままでは動きませんよ! ★のテキストを、それぞれの環境に合わせて書き換えて下さい。デフォルトではデータベース名も管理者名もpostgresになっていますから、パスワードをhogeにしてあったならば、こんな感じに設定すればいいでしょう。
"tcp://postgres:hoge@localhost:5432/postgres"
これで、mydataにあるデータを全て取得し、テーブルにまとめて表示します。ただし、まだ/addと/createを作ってないので、この段階で実行してもうまく動かないでしょう。最後まで完成してから表示を確かめて下さい。
では、ソースコードの説明をしましょう。Node.jsのpgを使ってデータベースアクセスを行う基本について順に説明していきます。
●データベースに接続する
pg.connect( 接続先 , コールバック関数 );
データベースへの接続は、pg.connectというメソッドを使います。これは第1引数に接続先のアドレスを、第2引数には接続が開始されてから実行されるコールバック関数を指定します。サンプルのスクリプトでは、以下のように記述しています。
var con = "tcp://利用者:パスワード@ホスト:ポート番号/データベース";
pg.connect(connectionString, function(err, client) {…接続時の処理…}
接続先は、tcpというプロトコルのテキストで用意します。利用者、パスワード、ホスト、ポート番号、データベースといった情報を一つにまとめて記述するので、書き方を間違えないように注意して下さい。
connectは非同期関数で、接続が完了したところで引数の関数を呼び出して実行します。このコールバック関数は、2つの引数を用意します。第1引数にはエラーが発生した時の情報をまとめたオブジェクトが、また第2引数には接続したデータベースへのアクセスを管理するClientというオブジェクトが返されます。
●SQLクエリーを実行する
変数 = client.query( クエリー文 );
接続したデータベースを操作するには、Clientの「query」メソッドを使います。これは、SQL文をデータベースに送って実行するためのものです。引数にはSQLのクエリーテキストを指定します。
SQL文では、selectのように値を取得する処理もありますが、このqueryメソッドそのもので返値を返すわけではないので注意が必要です。このqueryメソッドは、非同期でアクセスを行います。このため、実行結果となる返値でデータを受け取れるわけではないのです。
では、何が返値として返されるのか? それは、「Query」というオブジェクトです。このQureryには、処理の実行状況に応じて発生するイベントハンドラが用意されており、これを利用して処理を行うのです。
サンプルのリストを見てみましょう。まず以下のようにしてselect文を実行し、そのQueryを変数に取得しています。
var query = client.query('select * from mydata;');
このqueryでは、第2引数に実行後の処理をコールバック関数として指定することもできるのですが、ここでは単にクエリーを実行するだけの使い方で説明をします。――このqueryを実行後、返されるQueryオブジェクトのイベントを設定します。このイベントは全部で3種類用意されています。それぞれ以下のようにして設定を行います。
・rowの取得イベント
query.on('row', function(row){……処理……} );
selectなどレコードを取得するクエリーを実行したとき、レコードを取得するごとにこのrowイベントが発生し処理が呼び出されます。引数rowには、取得したレコードをオブジェクトにまとめたものが保管されます。
・終了イベント
query.on('end', function(result){……処理……} );
すべての処理が完了したときに呼び出されます。引数には、クエリー実行に関する各種の情報をまとめたResultオブジェクトが渡されます。
・エラーイベント
query.on('error', function(error){……処理……} );
エラーが発生した際に呼び出されます。ただし、queryメソッドを呼び出す際にコールバック関数を設定してあった場合は、そちらが優先され、このイベントは発生しないので注意ください。
この3つのイベントを組み合わせることで、クエリー実行後の処理を構築できます。サンプルのスクリプトでは、rowイベントで、取得されたrowオブジェクトを配列に追加し保存しています。こうすることで、取得されたすべてのrowデータをひとまとめにできます。
また、注目して欲しいのは、index.jsのレンダリングのタイミングです。ここでは、endイベントが発生したところでrenderで表示をレンダリングしていることがわかります(他、error時にも行なっていますが……)。このように、処理が完了したところで表示をレンダリングしないと、うまく結果を取り出して表示することができないので注意しましょう。
(by. SYODA-Tuyano.)
※プログラムリストが表示されない場合
AddBlockなどの広告ブロックツールがONになっていると、プログラムリスト等が表示されない場合があります。これらのツールをOFFにしてみてください。
●プログラム・リスト●
※index.js var express = require('express'); var router = express.Router(); var pg = require('pg'); /* GET home page. */ router.get('/', function(request, response, next) { var con = "tcp://利用者:パスワード@ホスト:ポート番号/データベース"; //★ pg.connect(con, function(err, client) { var query = client.query('select * from mydata;'); var rows = []; query.on('row', function(row) { rows.push(row); }); query.on('end', function(row,err) { response.render('index', { title: 'Express', data:rows }); }); query.on('error', function(error) { console.log("ERROR!!" + error); response.render('index', { title: title, data: null, message: "ERROR is occured!" }); }); }); }); module.exports = router; ※index.ejs <!DOCTYPE html> <html> <head> <title><%= title %></title> <link rel='stylesheet' href='/stylesheets/style.css' /> </head> <body> <h1><%= title %></h1> <p>Welcome to <%= title %></p> <% if (data != null) { %> <table border="1"> <% for(var i=0; i < data.length; i++){ %> <tr> <td width="200px"><%= data[i].name %></td> <td width="200px"><%= data[i].mail %></td> <td width="300px"><%= data[i].memo %></td> </tr> <% } %> </table> <% } %> </body> </html>
※関連コンテンツ