1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【初心者】JRubyでSQLiteデータベースを読み書きする

Last updated at Posted at 2024-07-13

手軽に使える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の知識が必要なんですかね。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?