はじめに
Node.jsを使ってDB操作をしてみたかったため,sqlite3モジュールを使ってみました。
こちらの記事は,その際の備忘録となります。
大まかな流れ
- 必要なパッケージのダウンロード
- 実行ファイルの作成
- 実行
以下で一つ一つについて詳細に説明します。
1. 必要なパッケージのダウンロード
今回は,sqlite3モジュールを利用しますので,以下のコマンドでパッケージをダウンロードします。
$ npm install sqlite3
$ npm install --save sqlite3
-
--save
オプション : package.jsonのdependenciesに追加される(npm 5.0.0 以降ではデフォルト)
2. 実行ファイルの作成
今回は、ダミーのデータベースを作成し、その中身をコンソールログに出力するようなサンプルを作成します。
// .verbose() をつけると、デバッグしやすくなる
const sqlite3 = require('sqlite3').verbose();
// sqlite3.Database() の第一引数に ':memory:' を指定することで、メモリ上にDBを作成することができる
const db = new sqlite3.Database(':memory:');
// db is instance of Database class
console.log(db instanceof sqlite3.Database); // => true
// DB操作を行う処理を serializeメソッドのコールバック関数内で記述することで、クリエを順に実行することができる
db.serialize(function() {
// 指定したクエリを実行する
db.run("CREATE TABLE dummy (info TEXT)");
// Statementオブジェクトを作成する
const statement = db.prepare("INSERT INTO dummy VALUES (?)");
// statement is instance of Statement class
console.log(statement instanceof sqlite3.Statement); // => true
for (let i = 0; i < 10; i++) {
// prepareメソッドで指定したSQL文中の ? に値を設定し、SQLを実行する
statement.run("number" + i);
}
// statementオブジェクトを終了する
statement.finalize();
// 結果を取得する毎にコールバック関数を実行する
db.each("SELECT rowid AS id, info FROM dummy", function(err, row) {
console.log(row.id + ": " + row.info);
});
});
// DBをクローズする
db.close();
以下で詳細に説明します。
sqlite3モジュールを読み込む
const sqlite3 = require('sqlite3').verbose();
requireでsqlite3モジュールを読み込みます。
verboseメソッドについては、下記を参照してください。
参照 : https://github.com/mapbox/node-sqlite3/wiki/API#sqlite3verbose
新規DBを作成
const db = new sqlite3.Database(':memory:');
Databaseクラスの新規インスタンスを作成します。
第一引数に :memory:
を指定することで、メモリ上に一時的なDBを作成することができます。
:memory:
ではなくファイル名を指定すれば、永続的なDBを扱うこともできます。
参照 : https://github.com/mapbox/node-sqlite3/wiki/API#new-sqlite3databasefilename-mode-callback
DB操作を上から順に実行する
db.serialize(function() {
...
}
serializeメソッドを使用することで、引数に指定された関数内の処理を、順に実行します。
参考 : https://github.com/mapbox/node-sqlite3/wiki/Control-Flow#databaseserializecallback
並列に実行したい場合は、parallelizeメソッドを使用してください。
クエリを実行する
db.run("CREATE TABLE dummy (info TEXT)");
runメソッドは、引数で指定したクエリを実行します。
参考 : https://github.com/mapbox/node-sqlite3/wiki/API#databaserunsql-param--callback
Statementオブジェクトの作成・実行
const statement = db.prepare("INSERT INTO dummy VALUES (?)");
for (let i = 0; i < 10; i++) {
statement.run("number" + i);
}
statement.finalize();
prepareメソッドを使用して、Statementクラスの新規インスタンスを作成します。
Statementオブジェクト作成後、runメソッドを使用することで、prepareメソッドの第一引数で指定したクエリの ?
の箇所に値を代入してクエリを実行することができます。
Statementオブジェクトの使用後は、finalizeメソッドで終了させます。
参考 : https://github.com/mapbox/node-sqlite3/wiki/API#statement
DBの中身の取得
db.each("SELECT rowid AS id, info FROM dummy", function(err, row) {
console.log(row.id + ": " + row.info);
});
eachメソッドを使用して、クエリの実行結果1行毎に行う処理を記述します。
参考 : https://github.com/mapbox/node-sqlite3/wiki/API#databaseeachsql-param--callback-complete
似たようなメソッドに、allメソッドがあります。
allメソッドは、全ての結果を一度に配列に格納するため、取得する件数がある程度わかっている場合には有効です。
しかし、取得件数が膨大であったりあまり予測できなかったりする場合は、メモリを使用しすぎる可能性があるため、eachメソッドの方が有効です。
参考 : https://github.com/mapbox/node-sqlite3/wiki/API#databaseallsql-param--callback
DBをクローズ
db.close();
closeメソッドを使用して、データベースをクローズします。
参考 : https://github.com/mapbox/node-sqlite3/wiki/API#databaseclosecallback
3. 実行
$ node sample.js
1: number0
2: number1
3: number2
4: number3
5: number4
6: number5
7: number6
8: number7
9: number8
10: number9