我的项目是sbt 1.1.6 + playframework 2.7 + play-slick 3.0.0 + mysql-connector-java 5.1.34。
我通过
sbt/dist
unzip {package}
./bin/{project_name} -Dhttp.port=8080
在将此<logger name="com.zaxxer.hikari" level="DEBUG"/>
附加到登录后,我发现Hikari在第一次执行代码db.run()
之后创建了与数据库的连接。
初始化数据库连接需要一些时间,有时会发生错误,例如getConnection超时或等待连接超时。
因此,有什么方法可以预加载创建连接,而不是在第一次调用db.run()
之后创建连接。
我制作了一个热切的单例类,该类执行db.run()
直到成功,然后在应用启动之前运行。
例如
class InitialDB @Inject() (areaCodeInfoDAO: AreaCodeInfoDAO) (implicit exec: ExecutionContext) {
def init(): Future[String] = {
areaCodeInfoDAO.getProvince("440782")
}
RetryUtil.retry4Future(10)(init())
}
class ApiModule extends AbstractModule {
override def configure(): Unit = {
bind(classOf[InitialDB]).asEagerSingleton()
}
}
解决了这个问题,但并不优雅。
这是我的示例代码:
import javax.inject._
import scala.concurrent.duration.Duration
import scala.concurrent.{Await, ExecutionContext, Future}
import model.TableQueries
import play.api.db.slick.{DatabaseConfigProvider, HasDatabaseConfigProvider}
import play.api.mvc._
import slick.jdbc.JdbcProfile
import slick.jdbc.MySQLProfile.api._
class HomeController @Inject()(protected val dbConfigProvider: DatabaseConfigProvider)
(cc: ControllerComponents)
(implicit exec: ExecutionContext)
extends AbstractController(cc)
with HasDatabaseConfigProvider[JdbcProfile] {
def index() = Action { implicit request: Request[AnyContent] =>
val query = TableQueries.CODE_NAME_MAPPING
.filter { info =>
info.code === "test"
}
.map(_.name)
.take(1)
val result: Future[String] = db
.run(query.result)
.map(info => if (info.nonEmpty) info.head else "test")
Ok(Await.result(result, Duration.Inf))
}
}
import slick.lifted.TableQuery
object TableQueries {
val CODE_NAME_MAPPING = TableQuery[CodeNameMapping]
}
import slick.jdbc.MySQLProfile.api._
# model
class CodeNameMapping(tag: Tag)
extends Table[(String, String)](tag, "nydd_channel_info") {
def code = column[String]("code", O.PrimaryKey)
def name = column[String]("name")
def * = (code, name)
}
我将<logger name="com.zaxxer.hikari" level="DEBUG"/>
附加到logback.xml。
[调试]日志是在我向数据库发送查询请求之后,因此我认为Hikari在第一次执行代码db.run()
时会创建与数据库的连接。
[info] play.api.Play - Application started (Prod) (no global state)
[info] p.c.s.AkkaHttpServer - Listening for HTTP on /0:0:0:0:0:0:0:0:9000
[debug] c.z.h.HikariConfig - db - configuration:
[debug] c.z.h.HikariConfig - allowPoolSuspension.............false
[debug] c.z.h.HikariConfig - autoCommit......................true
[debug] c.z.h.HikariConfig - catalog.........................null
[debug] c.z.h.HikariConfig - connectionInitSql...............null