5.3. DBIを用いたデータベースアクセス

5.3.1. DBI::DatabaseHandleのコンポーネント化

DBIを用いてデータベースにアクセスする場合は、DBI.connectメソッドを使用してDBI::DatabaseHandle インスタンスを取得します。 このDBI::DatabaseHandleをコンポーネントとして扱うことで、DaoコンポーネントへのDIが可能となります。

DBI::DatabaseHandleコンポーネントの作成には、s2compメソッドを使用します。 s2compメソッドにコンストラクタ ブロックを渡し、そのブロック内でDBI.connectメソッドを実行します。 また、デストラクタ ブロックで、DBI::DatabaseHandle.disconnectを実施します。

component_info = s2comp(:class => DBI::DatabaseHandle, :name => :dbh, :autobinding => :none) {
  next DBI.connect("dbi:SQLite3:sample.db")
}

component_info.destructor {|dbh|
  dbh.disconnect
}

DBI::DatabaseHandleコンポーネントを使用するCdDaoを作成します。

module Example
  class Dao
    s2comp

    def initialize
      @dbh = nil             # DBI::DatabaseHandle インスタンスがDIされる
    end

    def find_by_name(name)
      sth = @dbh.prepare("SELECT * FROM people WHERE name = ?")
      sth.execute(name)
      sth.fetch {|row|
        printf "ID: %d, Name: %s, Height: %.1f\n", row[0], row[1], row[2]
      }
      sth.finish
    end
  end
end

実行ファイルは次になります。

require 'rubygems'
require 'dbi'
require 's2container'
require 'example'

component_info = s2comp(:class => DBI::DatabaseHandle, :name => :dbh, :autobinding => :none) {
  s2logger.info(File.basename(__FILE__)){"Database handle connected."}
  next DBI.connect("dbi:SQLite3:sample.db")
}

component_info.destructor {|dbh|
  s2logger.info(File.basename(__FILE__)){"Database handle disconnected."}
  dbh.disconnect
}

container = s2app.create
begin
  dao = container.get(Example::Dao)
  dao.find_by_name('hoge')
rescue => e
  s2logger.fatal(e.class.name){"#{e.message} #{e.backtrace}"}
ensure
  container.destroy
end
[注意]NOTE

このExampleは example/example13 にあります。



© Copyright The Seasar Foundation and the others 2008-2009, all rights reserved.