2017-01-27 5 views
0

У меня есть следующий метод, который фактически обновляет строку базы данных по таблице. Сначала он проверяет запись, если она существует с определенным условием, и только если она существует, она обновляет соответствующую строку. Таким образом, в базе данных есть два вызова. Я хотел бы избежать двух вызовов, отправленных в базу данных. Так вот код:Slick 3.0 Update Row на основе условия

def confirmUserRegistration(hash: String) = async { 
    val query = UserRegistrationTable.registrationForHash(hash) 
    val isRowAvailable = await(database.run(query.result.headOption)) 
    if (isRowAvailable.isDefined) { 
     // do the update 
    } else { 
    // do nothing and return 
    } 
    } 

UserRegistrationTable.registrationForHash (хэш) запрос выглядит следующим образом:

object UserRegistrationTable { 

    val all = TableQuery[UserRegistrationTable] 

    val registrationForHash = (hash: String) => { 
     all.filter(_.registrationHash === hash) 
    } 
    } 

Так как я могу оптимизировать обслуживание выпустить только один вызов к базе данных?

EDIT: обновление с обратной связью, заданной ниже сообщение:

Вот как мой метод выглядит:

def confirmUserRegistration(hash: String) = async { 
    val query = { 
     UserRegistrationTable.registrationForHash(hash) 
     .map(_.hasUserConfirmed) 
     .update(true) 
    } 

    val isUpdated: Int = await(database.run(query)) 

    } 

ответ

1

Просто используйте следующее сообщение:

val updateOperation: DBIO[Int] = all 
    .filter(_.registrationHash === hash) 
    .map(u => (u.field1, u.field2, u.field3)) 
    .update((newValue1, newValue2, newValue3)) 

Обратите внимание, что updateResult выше - DBIO, содержащий Int - число обновленных строк.

Так что вы можете сделать:

db.run(updateOperation).map { updatedRows => 
    if(updatedRows >= 0) { 
     // at least one row was affected, return something here 
    } else { 
     // nothing got updated, return something here 
    } 
} 

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

val userRegistration: UserRegistrationCaseClass = ... 

val updateOperation: DBIO[Int] = all 
    .filter(_.registrationHash === hash) 
    .update(newUserRegistration) 
+0

Так что если ни одно средство из строк были обновлены, значение для Int было бы 0? – sparkr

+0

Это правильно. Имейте в виду, что это 'DBIO [Int]', поэтому вам нужно сначала 'db.run (...)' it, а затем 'map' over' Future' –

+0

Я использую макрос Scala async. Я обновил свой пост. Посмотрите на это и дайте мне знать, если это звучит хорошо. – sparkr

Смежные вопросы