When DBIInterceptor is aspected to a class, the method which suited Pointcut is performed. DBIInterceptor will treat the return value of a method as an SQL query, if the return value of a method is string. If the return value of a method is Array, the 1st value is treated as an SQL query, the 2nd value is treated as a context at the time of SQL execution.
The sql is executed in a database and a result is returned as a return value of a method. Prepared Statement of DBI is used for execution of the SQL query to a database. As for value bound to Prepared Statement, method arguments are used. If the return value of a method is Array, the 2nd value is treated as bind value.
DBIInterceptor does not have OR map function and automatic SQL construction function.
![]() | NOTE |
|---|---|
|
This Example is located in example/example14 |
Let's create PrefectureDao class which accesses Prefecture table. The find_all method which gets all the data from Prefecture table is implemented in PrefectureDao class. As a return value of the find_all method, SQL query which will be executed to a database is returned.
module Example
class PrefectureDao
s2comp
s2aspect :interceptor => "dbi.interceptor"
def find_all
return 'select * from prefecture'
end
end
end
Please create run.rb which performs the next processing.
require 'rubygems'
require 'dbi'
require 's2container'
require 'seasar/dbi/interceptor'
require 'example'
s2comp(:class => DBI::DatabaseHandle, :namespace => "dbi", :autobinding => :none) {
DBI.connect("dbi:SQLite3:example.db")
}
begin
s2app[Example::PrefectureDao].find_all.each {|h|
puts "#{h['id']}\t#{h['name']}"
}
rescue Seasar::DBI::DBIInterceptor::ConnectError => e
s2logger.fatal(e.cause.class.name){"#{e.cause.message} #{e.cause.backtrace}"}
rescue => e
s2logger.fatal(e.class.name){"#{e.message} #{e.backtrace}"}
ensure
s2app[DBI::DatabaseHandle].disconnect if s2app[DBI::DatabaseHandle]
end
Let's create PrefectureDao class which accesses a Prefecture table. The find_by_id method which searches data with ID from Prefecture table is implemented in PrefectureDao class. ID which searches data is specified by the argument of find_by_id method. The embedding of ID to an SQL query is described like "?".
module Example
class PrefectureDao
s2comp
s2aspect :interceptor => "dbi.interceptor"
def find_by_id(id)
return 'select * from prefecture where id = ?'
end
end
end
Please create the following executable files.
require 'rubygems'
require 'dbi'
require 's2container'
require 'seasar/dbi/interceptor'
require 'example'
s2comp(:class => DBI::DatabaseHandle, :namespace => "dbi", :autobinding => :none) {
DBI.connect("dbi:SQLite3:example.db")
}
begin
s2app[Example::PrefectureDao].find_by_id(1).each {|h|
puts "#{h['id']}\t#{h['name']}"
}
rescue Seasar::DBI::DBIInterceptor::ConnectError => e
s2logger.fatal(e.cause.class.name){"#{e.cause.message} #{e.cause.backtrace}"}
rescue => e
s2logger.fatal(e.class.name){"#{e.message} #{e.backtrace}"}
ensure
s2app[DBI::DatabaseHandle].disconnect if s2app[DBI::DatabaseHandle]
end
Let's create PrefectureDao class which accesses a Prefecture table. The find_by_name method which searches data with NAME from Prefecture table is implemented in PrefectureDao class. Array is returned as a return value of a method, the 1st value is treated as an SQL query, the 2nd value is treated as a context at the time of SQL execution.
module Example
class PrefectureDao
s2comp
s2aspect :interceptor => "dbi.interceptor"
def find_by_name(name)
return "select * from prefecture where name = ?", name
end
end
end
Please create the following executable files.
require 'rubygems'
require 'dbi'
require 's2container'
require 'seasar/dbi/interceptor'
require 'example'
s2comp(:class => DBI::DatabaseHandle, :namespace => "dbi", :autobinding => :none) {
DBI.connect("dbi:SQLite3:example.db")
}
begin
s2app[Example::PrefectureDao].find_by_name("HOKKAIDO").each {|h|
puts "#{h['id']}\t#{h['name']}"
}
rescue Seasar::DBI::DBIInterceptor::ConnectError => e
s2logger.fatal(e.cause.class.name){"#{e.cause.message} #{e.cause.backtrace}"}
rescue => e
s2logger.fatal(e.class.name){"#{e.message} #{e.backtrace}"}
ensure
s2app[DBI::DatabaseHandle].disconnect if s2app[DBI::DatabaseHandle]
end
If using DBI directly in Dao, It is necessary to carry out injection of the DBI component to Dao component. In the following example, Property injection of the DBI::DatabaseHandle component is executed to the PrefectureDao class. In the transactional_insert method, the transaction is started using injected DBI component.
module Example
class PrefectureDao
s2comp
s2aspect :interceptor => "dbi.interceptor", :pointcut => /^insert/
def initialize
@dbh = :di, DBI::DatabaseHandle
end
def transactional_insert(id, name)
result = nil
@dbh['AutoCommit'] = false
begin
result = self.insert(id, name)
@dbh.commit
rescue => e
s2logger.warn(self.class.superclass.name) { "transaction failed. #{e.class.name} #{e.message}" }
@dbh.rollback
end
@dbh['AutoCommit'] = true
return result
end
def insert(id, name)
return 'insert into prefecture values(?, ?)'
end
end
end
Please create the following executable files.
require 'rubygems'
require 'dbi'
require 's2container'
require 'seasar/dbi/interceptor'
require 'example'
s2comp(:class => DBI::DatabaseHandle, :namespace => "dbi", :autobinding => :none) {
DBI.connect("dbi:SQLite3:example.db")
}
begin
puts s2app[Example::PrefectureDao].transactional_insert(48, "Other")
rescue Seasar::DBI::DBIInterceptor::ConnectError => e
s2logger.fatal(e.cause.class.name){"#{e.cause.message} #{e.cause.backtrace}"}
rescue => e
s2logger.fatal(e.class.name){"#{e.message} #{e.backtrace}"}
ensure
s2app[DBI::DatabaseHandle].disconnect if s2app[DBI::DatabaseHandle]
end
Seasar::DBI::Paginate class is a utility class which performs paging when acquiring data from Database. Let's implement the find_by_dto method in PrefectureDao class and do paging.
module Example
class PrefectureDao
s2comp
s2aspect :interceptor => "dbi.interceptor"
def find_by_dto(dto)
return "select * from prefecture where name like ? limit ? offset ?", [dto.name_like, dto.limit, dto.offset]
end
def find_total_by_dto(dto)
return "select count(*) as total from prefecture where name like ?", dto.name_like
end
end
require 'seasar/dbi/paginate'
class PrefectureDto < Seasar::DBI::Paginate
attr_accessor :name_like
end
end
Please create run.rb which performs the next processing.
require 'rubygems'
require 'dbi'
require 's2container'
require 'seasar/dbi/interceptor'
require 'example'
s2comp(:class => DBI::DatabaseHandle, :namespace => "dbi", :autobinding => :none) {
DBI.connect("dbi:SQLite3:example.db")
}
begin
dto = Example::PrefectureDto.new
dto.limit = 5
dto.name_like = '%er'
dto.total = s2app[Example::PrefectureDao].find_total_by_dto(dto)[0]["total"]
puts "page : #{dto.page}"
s2app[Example::PrefectureDao].find_by_dto(dto).each {|h|
puts "#{h['id']}\t#{h['name']}"
}
dto.next
puts "page : #{dto.page}"
s2app[Example::PrefectureDao].find_by_dto(dto).each {|h|
puts "#{h['id']}\t#{h['name']}"
}
rescue Seasar::DBI::DBIInterceptor::ConnectError => e
s2logger.fatal(e.cause.class.name){"#{e.cause.message} #{e.cause.backtrace}"}
rescue => e
s2logger.fatal(e.class.name){"#{e.message} #{e.backtrace}"}
ensure
s2app[DBI::DatabaseHandle].disconnect if s2app[DBI::DatabaseHandle]
end
Seasar::DBI::Paginate.get_total_page method.
All the number of pages is returned. (total records / page limit)
Seasar::DBI::Paginate#paage method.
Current page number is returned.
Seasar::DBI::Paginate#page= method.
Page number is set up.
Seasar::DBI::Paginate#offset method.
Current offset position is returned.
Seasar::DBI::Paginate#limit= method.
The number of records per 1 Paige is set up.
Seasar::DBI::Paginate#total method.
The total number is returned.
Seasar::DBI::Paginate#total= method.
The total number is set up.
Seasar::DBI::Paginate#window_size method.
The number of Pages displayed on a window is set up.。
Seasar::DBI::Paginate#next method.
1 page is advanced.
Seasar::DBI::Paginate#next? method.
It is returned whether there is any next page.
Seasar::DBI::Paginate#prev method.
1 page returns.
Seasar::DBI::Paginate#prev? method.
It is returned whether there is any previous page.
Seasar::DBI::Paginate#page_range method.
Range of page number settled in a page window is returned.
| © Copyright The Seasar Foundation and the others 2008-2009, all rights reserved. |