前回の記事で、SQlite3のデータベースのファイルを作成しました
今回はそのデータベースにアクセスするプログラムをNode.js のExpressを使って作成していこうと思います
Expressをつかってデータベースにアクセスしよう
ということでExpressをつかっていきます
一から作るのは面倒なのでExpressGeneratorを使います
ターミナルで
express -v ejs sample01app
としてアプリケーション名sample01appでプロジェクトを作成します
そして、同じフォルダ内にDBBrowserでデータベースを作成しす
SQlite3のパッケージをnpm でインストールしよう
では、ExpressでSQLiteにアクセスするために「SQlite3」のパッケージをインストールしましょう
ターミナルを開いてコマンドを実行しましょう
npm install sqlite3
あとは、どんどんコードを書いていきましょう
テンプレートファイルとスクリプトを書きましょう
まずはテンプレートファイルの作成です
viewフォルダーにあたらしいejsファイルを作成しましょう
自分は今回alldata.ejsというファイルを作成しました
コードは以下の通りです
テーブルタグで表を作っています
レコードの数だけデータを並べるために、for文を使っています
今回扱うデータはオブジェクトの配列になるので、
オブジェクトの配列のデータを一つずつ並べています
<% var obj = content[i] %>でレンダリング時に受けとったオブジェクトをobjという変数にi番目のデータを格納しています
for文ですのでiの値がどんどんプラスされていき、レコードの数だけデータが並ぶ形になります
例えば、<td class=”id”><%= obj.id %></td>で、オブジェクトのidを抽出しています
このあたりはオブジェクト形式の配列を理解しておく必要があります
続いて、スクリプトです
まず、モジュールをロードします
今回新しく利用するのはSQlite3のモジュールです
const sqlite3 = require(‘sqlite3’); ということでここでロードしています
あとは
const db = new sqlite3.Database(‘sample01data.db’);
これでデータベースのオブジェクトを作成しています
引数にはデータベースのファイル名を入れましょう
アプリケーションのフォルダ内にない場合はルートを書く必要がありますが、今回は同じフォルダ内にデータベースがあるので、ファイル名だけでOKです
そして、7行目以降でルーティングの処理をしています
serializeシリアライズとは
ルーティングの処理の中で最初に行っているのが、データベースオブジェクトのシリアライズです
db.serialize(()=>{ }) この引数の中の関数の中でデータベースの処理を行います
そうすることで、データベースのクエリを順番に実行するようになります
要するに、同時に複数の処理をしないためにこのような書き方をするわけです
今回のような単体でしかクエリを実行しない場合は気にする必要はないのですが、複雑な処理をしようとした場合は、同時に行うと不具合が生じるばあいがあります
そこで、このdb.serialize(関数)の処理を行い、非同期でのデータベースの処理を行います
レコードの取得を行おう
つづいて
db.all(“select * from customerData”,(err,rows)=>{処理})
でデータベースからデータを抽出してデータの処理を行っています
db.all(クエリ,関数);で処理をします
db.allはデータすべてをまとめて取り出すことができます
“select * from customerData”の部分がクエリです
SQLについては今回は詳しく説明しませんが、
*(アスタリスク)にするとすべてのデータということになります
これによってデータベースのcustomerDataのすべてのデータを条件なしで抽出してそれを第2引数のrowsの中に各レコードのデータをオブジェクトにしたものが入るわけです
あとは、このデータをレンダリング時にテンプレートに受け渡してWebページに表示することになります
最後に本体のapp.jsを修正しましょう
まだこのままだとルーティングの処理が完了していません
最後にapp.jsに修正を加えます
alldata.jsをモジュールとしてロードしてアドレスへ割り当てる処理を追加します
9行目のvar alldataRouter = require(‘./routes/alldata’)
と
25行目のapp.use(‘/alldata’, alldataRouter);を追加してルーティングの処理が完成します
これでプログラムを起動して、localhost:3000/alldataにアクセスすると次のような画面が表示されます
今回は検索もなくすべてのデータを抽出しただけです
次回以降で検索をしたり、新しいレコードを追加したりと順次機能を付け加えていきたいと思います
顧客管理はちょっと題材として重たい内容だったので動画の中身はもう少しライトな内容となっていますが、学べる知識は同じです
ぜひ、動画も参考になさってください
コメント
最初画面に顧客データがまったく表示されず、半分訳のわからないままソースをながめていたら、
下記に気づき修正したら無事に顧客データが表示されました。
前回作成したデータベースのTable名とemailのフィールド名がソースでは違っていました。
alldata.js
9行目:customerData→kokyakuData
alldata.ejs
22行目:mail→email
データベースが扱えるようになるのは、自分でも大きな進歩だと思います。
今後ともよろしくお願いいたします。
こんにちは。
ありがとうございます。
ご指摘いただいたところは修正いたしました。
アプリケーションにおいてデータベースは相当重要だとおもいます。
これからもよろしくお願いします。
少し文法的に引っかかってしまったので、質問させていただきます。
alldata.ejsの17行目のiの値をで表示させると確かに0, 1, 2が入っていますが、
を見たときには、変数iにはcontentオブジェクトが順番に入っていくと思っていました。
データベースのレコードの場合は、この構文でいつもレコード番号が得られると思って
いいのでしょうか。
for in はinの後ろに入るデータの形式によって扱いが変わります
// 配列 [{…},{…},{…}]
const data=
[{ id: 1, name: ‘Kiku Jiro’, mail: ‘maru@examlpe.com’, age: 35 },
{ id: 2, name: ‘Kiku Taro’, mail: ‘sankaku@example.com’, age: 30 },
{ id: 3, name: ‘ABC DEF’, mail: ‘marusankaku@example.com’, age: 25 }]
// オブジェクト {…, …, …}
const object = { id: 1, name: ‘Kiku Jiro’, mail: ‘maru@examlpe.com’, age: 35 }
for (var i in data) { // 配列の場合は i は 0から1ずつ増える
console.log(i)
}
for (var i in object) { //オブジェクトの場合 iに入るのはインデントではなく、オブジェクトの中身が順に入っていく
console.log(i)
}
これを試してもらうとわかると思いますが、inの後ろが配列の場合はiに入るのは0,1,2…とインクリメントされた数字が入ります。
inの後ろがオブジェクトの場合はオブジェクトの中身が順に入っていく形になります。
間違って次回のサンプルコードの質問をしてしまいましたが、
ご教示いただいたサンプルコードで、配列のインデックスが取得されることを確認いたしました。
またalldata.jsにconsole.log(rows)を追加して、データベースから取得したレコードが配列の形で格納されることも確認できました。
丁寧なご説明でとても助かりました。ありがとうございます。