m-namikiの日記

おもしろき こともなき世を おもしろく

DBIを使ってデータベースアクセス

前回、MySQLの接続用ライブラリを直接使ってMySQLにアクセスしていたが、Ruby/DBIというライブラリを使うとRDBMSに依存しない透過的なアクセスが可能となるらしいので、今回はそれを利用してCRUD処理を行ってみる。

Ruby/DBIについて

Ruby/DBIDBI(データベースインターフェース)層というRDBMSに依存しない層と、DBD(データベースドライバ)層というRDBMSに依存する層から成り立っていて、DBIとドライバをそれぞれインストールする必要がある。

DBIのインストール

まずはDBIのインストール。いつも通りgemsで行う。

gem install dbi

インストールされたバージョンは、deprecated-2.0.1とdbi-0.4.3だった。deprecated〜が想定外だったので、これが何かは後で調べる。

MySQL用ドライバのインストール

次にMySQLのDBDレベルドライバのインストール。こちらもいつも通りgemsで。

gem install dbd-mysql

インストールされたバージョンは、dbd-mysql-0.4.3だった。

検索処理

ここからは実際にCRUD処理を行っていく。まずは検索してすべてのレコードを表示してみる。

require 'rubygems'
require 'dbi'

begin
  # MySQLへの接続
  # DBI.connect(DSN["dbi":drivername:databese], user, password)
  dbh = DBI.connect("dbi:Mysql:demo", "root", "mysql")
  # 文字コードの設定
  dbh.do("SET CHARACTER SET utf8")
  
  puts "===== 全件検索 ====="
  
  # ステートメントハンドラの生成
  sth = dbh.prepare("SELECT * FROM tbl_employee")
  # ステートメントの実行
  sth.execute
  
  # 実行結果の取得・表示
  sth.fetch {|row|
    puts row.join(", ")
  }
  
  puts "===== 条件検索 ====="
  
  # preparedstatement相当の処理
  sth = dbh.prepare("SELECT * FROM tbl_employee WHERE employee_no = ?")
  sth.execute(1)

  # 実行結果の取得・表示
  sth.fetch {|row|
    puts row.join(", ")
  }

rescue DBI::DatabaseError => e
  puts "Error code: #{e.err}"
  puts "Error message: #{e.errstr}"
ensure
  sth.finish if sth
  dbh.disconnect if dbh 
end

最初の検索は特に条件を指定しない全件検索、2つ目の検索は検索条件を指定した場合の検索。JavaのPreparedStatementのようにプレースホルダーを置いてパラメータを指定すると、自動でバインドされて実行される。上記の例では「?」の部分に「1」がバインドされ、「SELECT * FROM tbl_employee WHERE employee_no = 1」というSQL文が組み立てられるが、パラメータが文字列だと自動で「"」で括ったり特殊文字をエスケープしてくれたりもする。

登録・更新・削除処理

続いて登録・更新・削除処理を行う。こちらは検索処理とは違って

require 'rubygems'
require 'dbi'

require 'date'

begin
  # MySQLへの接続
  # DBI.connect(DSN["dbi":drivername:databese], user, password)
  dbh = DBI.connect("dbi:Mysql:sspj_demo", "root", "mysql")
  # 文字コードの設定
  dbh.do("SET CHARACTER SET utf8")
  
  puts "===== 登録処理 ====="
  dbh.do("INSERT INTO tbl_employee VALUES(?, ?, ?, ?, ?, ?, ?)", "1", "password", "テスト太郎", "example@sample.com", 1, DateTime.now, "system")

  puts "===== 更新処理 ====="
  dbh.do("UPDATE tbl_employee SET employee_name = ? WHERE employee_no = ?", "テスト次郎", "1")
  
  puts "===== 削除処理 ====="
  dbh.do("DELETE FROM tbl_employee WHERE employee_no = ?", "1")
  

rescue DBI::DatabaseError => e
  puts "Error code: #{e.err}"
  puts "Error message: #{e.errstr}"
ensure
  dbh.disconnect if dbh 
end

検索処理と違ってこれらの処理は結果セットを返さないので、ステートメントハンドラではなく、データベースハンドラ(dbh)のdoメソッドを使う。こちらも検索処理同様プレースホルダーを置いて、追加の引数にパラメータを指定すると自動でバインドしてくれる。

これでRubyアプリからのCRUD処理は一通り完了。パラメータの指定方法とかもうちょっと調べたい部分があるのがそれは追々やっていく。

参考にしたサイト:http://www.kitebird.com/articles/ruby-dbi.html