scala-guice는 google-guice를 이용해 scala quill에 맞게 inject를 구현한 간단 코드이다.
libraryDependencies ++= Dependencies.guice
val guice = Seq(
"com.google.inject" % "guice" % "4.2.2",
"com.google.inject.extensions" % "guice-assistedinject" % "4.2.2",
"net.codingwell" %% "scala-guice" % "4.2.2"
)
scala quill 를 사용할 때 데이터 타입 관련해서 Encoder/Decoder로 사용할 Implicits를 구현한다.
package com.google.quill
import java.util.Date
import io.getquill.MappedEncoding
import org.joda.time.DateTime
object Implicits {
implicit val dateTimeDecoder = MappedEncoding[Date, DateTime](Decoders.fromDateField)
implicit val dateTimeEncoder = MappedEncoding[DateTime, Date](_.toDate)
}
object Decoders {
def fromDateField(date: Date): DateTime = {
new DateTime(date)
}
}
데이터베이스에서 사용하는 Orders 클래스를 정의한다.
package com.google.datalake.dao.shopping
import org.joda.time.DateTime
case class Orders(
id: Long,
payment_id: Long,
refund_id: Option[Long],
channel_id: Long,
seller_id: Long,
buyer_id: Option[Long],
buyer_user_id: Long, #...
)
properties 정보
orderDB.dataSourceClassName=com.mysql.jdbc.jdbc2.optional.MysqlDataSource
orderDB.dataSource.url="jdbc:mysql://test.google.com:3306/buy?useTimezone=true&serverTimezone=UTC&characterEncoding=UTF-8"
orderDB.dataSource.user=xxx
orderDB.dataSource.password=xxx
orderDB.dataSource.cachePrepStmts=true
orderDB.dataSource.prepStmtCacheSize=250
실제 Inject 중심 클래스를 정의한다. google-guice의 AbstractModule를 상속하고 scala-guide의 ScalaModule를 믹싱한 DataBaseModule을 정의한다.
package com.google.datalake.db.modules
import com.google.inject._
import com.google.datalake.db.SelectOrderDB
import io.getquill.{MysqlJdbcContext, SnakeCase}
import net.codingwell.scalaguice.ScalaModule
import com.google.inject.AbstractModule
class DataBaseModule extends AbstractModule with ScalaModule {
override def configure(): Unit = {
bind(classOf[SelectOrderDB]).asEagerSingleton()
}
@Provides
def provideDataBaseSource(): MysqlJdbcContext[SnakeCase] = {
new MysqlJdbcContext(SnakeCase, "orderDB")
}
}
quill을 이용한 DAO 코드이다. MysqlJdbcContext를 inject해서 사용할 수 있게 한다.
package com.google.datalake.db
import com.google.inject.Inject
import com.google.datalake.dao.shopping.Orders
import io.getquill.{MysqlJdbcContext, SnakeCase}
class SelectOrderDB @Inject()(val ctx: MysqlJdbcContext[SnakeCase]) {
import ctx._
def findById(id: Long) = {
val q = quote {
query[Orders].filter(_.id == lift(id))
}
ctx.run(q)
}
def findByIds(ids: List[Long]): Unit = {
val q = quote {
query[Orders]
.filter(p => liftQuery(ids).contains(p.id))
}
ctx.run(q)
}
}
실제 테스크 코드는 다음과 같다.
package com.google.datalake.db
import com.google.inject.Guice
import com.google.datalake.db.modules.DataBaseModule
import org.scalatest.FunSuite
class SelectOrderDBTest extends FunSuite {
val injector = Guice.createInjector(new DataBaseModule()).getInstance(classOf[SelectOrderDB])
val selectOrderDB = injector.asInstanceOf[SelectOrderDB]
test("find by id") {
val row = selectOrderDB.findById(71721303)
println(row)
}
}