ColdFusion-開発効率を求められる今だから知りたい高性能Webアプリケーションサーバー

第3回 ColdFusionでデータベースにアクセスする

この記事を読むのに必要な時間:およそ 5 分

サンプルデータベースにクエリーを発行する

それでは,ColdFusion付属のサンプルデータベースに対してクエリーを発行してみることにしましょう。cfartgalleryデータソースを用いて,artテーブルから「mediaID=2」の条件にマッチする行を取得してくる例です。cfartgalleryはアートギャラリーの商品在庫を管理しているデータベースで,artテーブルには商品の在庫情報が入っています。テーブル構成は以下の通りです。

列名備考
artIDintプライマリーキー
artistIDintartistテーブルのプライマリーキー値
artNamevarchar商品名
descriptionclob商品の説明
isSoldint商品が売れたかどうか
largeImagevarchar商品の画像へのパス
mediaIDintmediaテーブルのプライマリーキー値
priceint商品の価格

まずはどのようなデータがartテーブルに入っているか調べてみることにしましょう。どのようなデータが入っているか調べたい場合,cfdumpタグが便利です。cfdumpタグでは,var属性に渡した文字列や構造体・配列・クエリーなどを分かりやすい形に整形して出力してくれるタグです。

まず、{cf_root}フォルダ({cf_root}はColdFusionをインストールしたディレクトリです。Windowsでは『C:\ColdFusion8』になります)内にある『wwwroot』の中に『gihyo』という名前のフォルダを作り、その中に『3』というフォルダを作ってください。⁠3』のフォルダの中に以下のような中身のファイルをdump.cfmとして保存してください(ファイルのパスは{cfroot}/wwwroot/gihyo/3/dump.cfmになります⁠⁠。なお保存時の文字コードはUTF-8としてください。

<cfprocessingdirective pageEncoding="UTF-8" />
<cfcontent type="text/html; charset=UTF-8">
<cfquery datasource="cfartgallery" name="qry">
  SELECT
    *
  FROM
    art
  WHERE
    mediaID=2
</cfquery>
<cfdump var="#qry#">

そして,http://127.0.0.1:8500/gihyo/3/dump.cfmにアクセスすると,以下のような実行結果を得ることができると思います。

図4 cfdumpでクエリーをダンプした例

図4 cfdumpでクエリーをダンプした例

ご覧頂いて分かるとおり,cfqueryタグで生成したクエリーオブジェクト(qry)の中身が整形されてダンプされています。qry.RESULTSETの中に,実行したSQLの結果が格納されているのが分かります。その他,クエリーに関するメタデータとして,クエリーをColdFusion上でキャッシュしているかどうかのブール値(qry.CACHED⁠⁠,クエリーの実行にかかった時間(qry.EXECUTIONTIME 単位はミリ秒⁠⁠,実行したSQL文(qry.SQL)が保持されていることが分かります。また,ここにダンプされていないメタデータとして,実行したSQLで取得できたレコードの件数(qry.RecordCount)を取得することができます。このように,ColdFusionの任意のオブジェクトの中身をとりあえず知りたいという場合,cfdumpしてみるとそのオブジェクトの中身が整形されて表示されるため,オブジェクトの中身が分からず困ったときにはとりあえずcfdumpタグを使うと便利です。

さてここで,見慣れないタグとしてcfprocessingdirectiveタグcfcontentタグがあるかと思います。

cfprocessingdirectiveタグは,処理するCFMLテンプレートの文字コードが何であるかを指定するタグです。Windows環境において,ColdFusionの想定しているCFMLテンプレートの文字コードはShift_JIS(実際は類似のMS932)がデフォルトとなっています(ColdFusionを動かしているOSによってデフォルトの文字コードが異なるので注意して下さい⁠⁠。従ってShift_JISでCFMLテンプレートを作成した場合,cfprocessingdirectiveタグを省略することができます。

しかしながら,作成するアプリケーションの国際化を考えた場合,ページエンコーディングはUTF-8にするのが妥当な場合が多いので,今回はCFMLテンプレートをUTF-8で作成し,cfprocessingdirectiveタグでCFMLテンプレートの文字コードがUTF-8であると明示しています。なお,BOM(Byte Order Mark)付きUTF-8でCFMLテンプレートを作成した場合,ColdFusionはBOMからCFMLテンプレートの文字コードを判断できるため,cfprocessingdirectiveタグでの文字コードの明示は必要なくなります。

cfcontentタグは,HTTPレスポンスヘッダのContent-Typeにtype属性で指定した値を入れるようにするタグです。今回のCFMLテンプレートではUTF-8のHTMLを出力しているため,このようなMIMEタイプが入ります。

クエリーを表示してみる

cfdumpでクエリーに含まれている中身が分かったので,今度は実際にそれを整形した形で表示してみることにしましょう。

クエリーで得られた全ての行に対してループを行うにはcfloopタグを使います。cfloopタグはその名前の通り各種ループを行うためのタグです。cfloopタグのquery属性にループしたいクエリーを渡すと,そのクエリーの各行をループで取得することができます。

cfloopタグでループしているクエリーの各行のデータをHTMLに出力するにはcfoutputタグを使います。cfoutputタグで囲まれた部分のうち,シャープサイン(#)で挟まれた部分がColdFusionによって変数やプログラムとして解釈されます。

以下の例は,クエリーの各行のartNameという列の値をpタグで囲う例です。{cf_root}/wwwroot/gihyo/3/qry1.cfmとして保存し,http://127.0.0.1:8500/gihyo/3/qry1.cfmでアクセスしてみましょう。

<cfprocessingdirective pageEncoding="UTF-8" />
<cfcontent type="text/html; charset=UTF-8">
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<cfquery datasource="cfartgallery" name="qry">
  SELECT
    artName
  FROM
    art
  WHERE
    mediaID=2
</cfquery>
<title>クエリーテスト</title>
<body>
  <cfloop query="qry">
    <cfoutput><p>artName: #HtmlEditFormat(qry.artName)#</p></cfoutput>
  </cfloop>
</body>

図5 qry1.cfmの実行結果

図5 qry1.cfmの実行結果

cfoutputタグで囲まれている部分のうち,シャープサインで囲った部分はプログラムと解釈されます。今回の場合,HtmlEditFormat()という関数の引数に,qry.artName(ループしているクエリーの各行のartNameという名前の列の値)を渡して,その関数の実行結果を出力するという意味です。HtmlEditFormat()関数はHTMLの特殊な文字列(⁠⁠<」「&」など)をエスケープしてくれる関数で,これを入れておかないとXSS脆弱性などが生じるおそれがあるため,データベースのデータなどを出力する場合はこの関数を必ず使うようにしましょう。

なお,ColdFusionは変数の大文字小文字を区別しません。なので「qry.artName」「qry.ARTNAME」も同じものとして扱われます。しかしながら,データベース上のカラム名と違う名前を記述すると,後で読み返したときなどにコードが分かりづらくなることが予想されるため,データベース上と同じ綴りで記述しておくことをお奨めします。

著者プロフィール

酒井克幸(さかいかつゆき)

フリーのテクノロジーコンサルタント。サーバー選定やネットワーク設計などハードウェアレイヤーから,Webアプリケーションの実装(サーバーサイド,クライアントサイド共)などのソフトウェアレイヤーまでの幅広い経験を活かし,クライアント企業のWebアプリケーション構築支援を行っている。殊にAdobe製品(特にMacromedia)製品には精通している。

ブログcyano(シアノ)