rubyのmysql2にprepared statementがサポートされました。
使い方がどこにも書いてないのでメモしときます。
require 'mysql2'
client = Mysql2::Client.new(
:host => "localhost",
:username => "username",
:password => "XXXXXXXXX",
:database => "database"
)
sql = %{
SELECT
id,
created_date as created_at
from users
where
created_date > ?
limit ?
}
stmt = client.prepare(sql)
# DateやTimeは自動的にCastされる
# パラメータが足りなければ当然エラー
res = stmt.execute(Date.today - 365, 100)
res.each { |c| p c }
# field名を取得
p stmt.fields
# close は GC 時に自動で呼ばれるが明示的に呼ぶこともできる
stmt.close
2018/09/22 sonots 追記:
mysql2 gem の prepared statement は server side prepared statement です。mysql の statement handle は使い回すのが正しい使い方なので、stmt オブジェクトをすぐに close して破棄するのではなく、キャッシュして使い回すのが正しい使い方となります。
mysql2 gem そのものに Go の Prepared Statement のような気の利いたキャッシュ機構はないですが、ActiveRecordではデフォルト1 connectionにつき1000 statementまでStatementPoolというところにキャッシュして超えたら一番古いやつを捨てるような実装になっているとのこと。
ref. https://twitter.com/sonots/status/1042829959989882880
参考
- brianmario/mysql2
- Prepared statement support by nyaxt · Pull Request #289 · brianmario/mysql2
- https://github.com/brianmario/mysql2/blob/95bfea3d430187fda31caea44ded0a8ab606525d/ext/mysql2/statement.c#L584
- https://github.com/brianmario/mysql2/blob/95bfea3d430187fda31caea44ded0a8ab606525d/ext/mysql2/statement.c#L561-L563