2017-02-19 24 views
0

Вот это код, который я пытаюсь оптимизировать:явно близко дб соединение в гладком

object UserRepo 
{ 
    val users = TableQuery[Users] 

    val dbName = "db" 

    lazy val queryAllUsers = for (user <- users) yield user 

    type UserRow = (Int, String, String, String) 

    def getAll() : Future[ Seq[UserRow] ] = 
    { 
    val db = Database.forConfig(dbName) 

    val f: Future[Seq[UserRow]] = db.run(queryAllUsers.result) 

    f.onComplete { 
     case Success(_) => { db.close() } 
     case Failure(_) => { db.close() } 
    } 

    f 
    } 

} 

будет иметь ряд запросов к БД я пытаюсь избавиться от строки, в которой я создаю соединение DB. Есть ли какой-либо контекст выполнения, который я могу использовать, чтобы закрыть соединение явно? поэтому код будет выглядеть более кратким?

Есть ли возможность использовать соединение db в рамках Future.onComplete scope?

Благодаря

+0

Итак, что вы говорите, так это то, что вы хотите создать (и позже закрыть) соединение db для этой единственной операции? Разве вы не должны открывать/закрывать соединение при некотором запуске/завершении работы вашего приложения и повторно использовать при каждом выполнении запроса? –

+0

Хорошая точка, вы хотите управлять соединением db на уровне приложения? Да, это может быть приятно, но, как я понял, мне придется создать этот код вручную? есть ли что-то встроенное в пятно? – Pavel

+0

Вы используете 'Play'? –

ответ

3

Что касается Вашего комментария (explicitly close db connection in slick) обычно то, что вы делаете это, чтобы создать соединение на качестве при запуске приложения (или лениво при первом использовании), а затем закрыть его в конце приложения.

Это, очевидно, все зависит от того, какое приложение вы работаете:

  • если вы имеете DI контейнер вы, вероятно, управлять некоторыми из этого в ваших DI механизмов (как Module s в Guice)

  • , если у вас есть веб-приложение, в частности, например Play - вы, вероятно, используете play-slick, который выполняет эту инициализацию/закрытие для вас (своего рода).

общий способ (без DI)

Самый простой общий способ (если вы не не используете DI или play-slick) делать это было бы возможно, что-то вроде этого:

object DbManager { 
    lazy val db = createDb 

    private def createDb = { 
     Database.forConfig("db") 
    } 

    def close { 
     db.close 
    } 
} 

Тогда ваш код будет:

object UserRepo 
{ 
    val users = TableQuery[Users] 

    lazy val queryAllUsers = for (user <- users) yield user 

    type UserRow = (Int, String, String, String) 

    def getAll() : Future[ Seq[UserRow] ] = 
    { 
    DbManager.db.run(queryAllUsers.result) 
    } 
} 

Выше кода не выполняется очистка - это должно быть добавлено к некоторому крючку при закрытии приложения (в случае, например, веб-приложения), или вам нужно вручную вызвать DbManager.close в определенное время (при закрытии приложения).

Play скользкий

Вы, вероятно, нужно будет начать отсюда: https://github.com/playframework/play-slick/tree/master/samples/basic (самый основной образец, показывающий play-slick конфигурацию).

Обновление ваш ответ с этим будет:

class UserRepo @Inject() (dbConfigProvider: DatabaseConfigProvider) extends HasDatabaseConfigProvider[JdbcProfile]) 
{ 
    import driver.api._ 

    val users = TableQuery[Users] 

    lazy val queryAllUsers = for (user <- users) yield user 

    type UserRow = (Int, String, String, String) 

    def getAll() : Future[ Seq[UserRow] ] = 
    { 
    db.run(queryAllUsers.result) 
    } 
} 

В этом случае вы не могли бы назвать:

UserRepo.getAll 

но скорее нужно будет вводить его:

class MyClientCode @Inject() (userRepo: UserRepo) { 
    ... 
    userRepo.getAll 
    ... 
} 

Вам нужно будет, очевидно, настроить его в своей конфигурации, но это должно быть очень просто сделать wit h образец, указанный выше.

Итак, ваше приложение Play будет иметь конфигурацию подключения к базе данных и сделает все инициализацию/очистку. Ваши внешние модули (например, тот, который вы описали в своем комментарии) просто вытащили DatabaseConfigProvider как Guice управляемая зависимость (как показано выше).

+0

хорошо, учитывая, насколько ясен краткий код scala. Я рассматриваю возможность использования play-slick для моего проекта: (Play project + Akk). Итак, у меня будет отдельный проект для моделей данных/отображения таблиц и т. Д. Спасибо, – Pavel