Grails で GORM と同一の Connection を使用する
Grails で GORM に使用している Connection を、GORM以外で使用する方法を記します。
サンプルソースはGithubに公開しています。
// 2013/06/08 追記 ---------------------------------------
// --------------------------------------------------------
■何が問題?
以下のソースの場合、DIしたSqlManager の Connection と、GORMで使用している Connection が異なるため、count2(DI)とcount3(GORM)が異なる値となります。
insert.sql がコミットされるのは#update が終わってからなので、count3はレコード追加前の件数となります。
// -------------------------------------------------------------------
class CustomerService {
SqlManager sqlManager
def update() {
int count = sqlManager.getCount("com/area_b/samples/select.sql")
sqlManager.executeUpdate("com/area_b/samples/insert.sql")
int count2 = sqlManager.getCount("com/area_b/samples/select.sql")
int count3 = Customer.count
}
}
// -------------------------------------------------------------------
ちょっと困ったちゃんですよね。
■GORMで使用しているConnectionを取り出す。
以下のような感じで、取り出すことができます。
// -------------------------------------------------------------------
import jp.sf.amateras.mirage.SqlManager
import jp.sf.amateras.mirage.SqlManagerImpl
import jp.sf.amateras.mirage.dialect.Dialect
import jp.sf.amateras.mirage.provider.ConnectionProvider
import jp.sf.amateras.mirage.provider.DefaultConnectionProvider
import org.hibernate.SessionFactory
import org.hibernate.connection.ConnectionProvider as SCP
import org.hibernate.engine.SessionFactoryImplementor
class CustomerService {
MySQLDialect dialect
def sessionFactory
def update() {
SqlManager manager = createInstance(sessionFactory, dialect)
int count = manager.getCount("com/area_b/samples/select.sql")
manager.executeUpdate("com/area_b/samples/insert.sql")
int count2 = manager.getCount("com/area_b/samples/select.sql")
int count3 = Customer.count
}
SqlManager createInstance(SessionFactory sessionFactory, Dialect dialect) {
SessionFactoryImplementor sfi = (SessionFactoryImplementor) sessionFactory
SCP scp = sfi.getConnectionProvider()
ConnectionProvider connectionProvider = new DefaultConnectionProvider()
connectionProvider.connection = scp.connection
SqlManager manager = new SqlManagerImpl()
manager.connectionProvider = connectionProvider
manager.dialect = dialect
return manager
}
}
// -------------------------------------------------------------------
もっと良い方法がありそうな気もしますが、とりあえずの目標は達成!