手軽に使えるSQLiteだが思ったよりも苦労した
何もわざわざJRubyなんて使う必要ないと言われそうなんですが、プログラミングを人に教えるときにデータベースの使い方を扱う必要が出てきまして、Windowsで手軽に環境構築できるので、JRubyを使うことにしました。
また、手軽に利用できるデータベースを探していたところSQLiteにたどり着きました。実際、selectは他のDBよりもかなり速いですね(個人が利用する範囲ならば)
ネットで色々と検索したのですが、自分の環境ではJRuby + SQLiteの読み書きは、Rubyのライブラリーではあまりうまく行きませんでした。
普段からJavaでsql2o( https://www.sql2o.org/ )を利用していたので、これをJRubyで呼び出せば行けるのではないかと考えました
準備
sqlite-jdbc-3.46.0.0.jar , slf4j-api-1.7.30.jar , slf4j-simple-1.7.30.jar ,sql2o-1.8.0.jar を使います。
sqlite-jdbcは、slf4jに依存しているので(以前のバージョンはそうではなかったですね。ほんとうはやめてほしい)、これも必要となります。
また、sqlite-jdbcの中身を見ると、sqlite接続に必要なネイティブライブラリーが格納されていました。少なくともWinodwsとLinuxでは利用できました。多分macも大丈夫でしょう。
上記ライブラリーをカレントディレクトリに保存します。
JRubyで書いてみました
自分は jruby-complete-9.4.7.0.jar を利用しています
require 'java'
require 'rubygems'
require './sqlite-jdbc-3.46.0.0.jar'
require './slf4j-api-1.7.30.jar'
require './slf4j-simple-1.7.30.jar'
require './sql2o-1.8.0.jar'
# DBの場所(カレントディレクトリになります)
url = "jdbc:sqlite:test.db"
sql2o = org.sql2o.Sql2o.new(url, "","")
# 各種SQL
create_sql = "create table if not exists test (id integer , name text)"
insert_sql = "insert into test values ( :id , :name)"
select_sql = "select id , name from test where name like :kwd"
# 挿入データ
table_data = [
[0 , "なんとかたろう" ],
[1 , "なんとかじろう" ],
[2 , "あれこれたろう" ]
]
begin
con = sql2o.open
# テーブル作成
con.createQuery(create_sql)
.executeUpdate()
# データ追加(一レコードずつ)
for col in table_data
con.createQuery(insert_sql)
.addParameter("id" , col[0])
.addParameter("name" , col[1])
.executeUpdate()
end
#挿入ここまで
# nameに「たろう」という文字が含まれるレコードを出す
list = con.createQuery(select_sql)
.addParameter("kwd" , "%たろう%") # もっといい方法があるかも
.executeAndFetchTable().asList()
for l in list
puts "ID:#{l['id']} 名前:#{l['name']}"
end
con.close # こうするのではなくブロックにしたい
end
実行結果
ID:0 名前:なんとかたろう
ID:2 名前:あれこれたろう
大量のデータを追加するとき
いわゆる「バルクインサート」というやつをやる時は、上記のコードのデータ追加部分を以下のように修正します。このほうが実用的かもしれません。
# データ追加(まとめて)
query = con.createQuery(insert_sql)
for col in table_data
query
.addParameter("id" , col[0])
.addParameter("name" , col[1])
.addToBatch()
end
query.executeBatch()
#挿入ここまで
終わりに
JRubyは、Javaのライブリーが利用できるのが大きな魅力です。Rubyのライブラリーを使う方法が色々あるかもしれませんが、自分は普段からJavaで作ることが多いので、慣れたライブラリーを手軽に利用しました。
sql2oを利用した出力が、簡単にRubyのオブジェクトに格納できるのは、Rubyの懐の深さを感じました。
こうしたライブラリーのAPIは、Javaに詳しい人でないと呼び出せないかもしれません。
となると、やはりJRubyならではのメリットを享受するにはJavaの知識が必要なんですかね。