Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Select single row based on Id in Slick

I want to query a single row from user based on Id. I have following dummy code

case class User(
    id: Option[Int], 
    name: String
}

object Users extends Table[User]("user") {
  def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
  def name = column[String]("name")
  def * = id ~ name <>(User, User.unapply _)

  def findById(userId: Int)(implicit session: Session): Option[User] = {
    val user = this.map { e => e }.where(u => u.id === userId).take(1)
    val usrList = user.list
    if (usrList.isEmpty) None
    else Some(usrList(0))
  }
}

It seems to me that findById is a overkill to query a single column as Id is standard primary key. Does anyone knows any better ways? Please note that I am using Play! 2.1.0

like image 245
Khalid Saifullah Avatar asked May 09 '13 11:05

Khalid Saifullah


People also ask

How do I delete a specific row in slick?

Deleting works very similarly to querying. You write a query which selects the rows to delete and then get an Action by calling the delete method on it: A query for deleting must only use a single table - no joins are allowed (Slick does not yet support the USING keyword for deletes).

What is the difference between select single and Uto 1 rows?

Select Single is the best one compared to UPto one rows. Select Single will get the first record from the table which satisfies the given condition.So it will interact once with the database. UTO 1 rows will get the list of the records for the given match and iwll show the first record from the list.So it will take time to get the record.

What is the difference between inserts and deletes in slick?

A query for deleting must only use a single table - no joins are allowed (Slick does not yet support the USING keyword for deletes). Any projection is ignored (it always deletes full rows). If you need to perform a join, you can filter based on another Query: Inserts are done based on a projection of columns from a single table.

What is the difference between select single and select up to 1?

According to SAP Performance course the SELECT UP TO 1 ROWS is faster than SELECT SINGLE because you are not using all the primary key fields. select single is a construct designed to read database records with primary key.


2 Answers

Use headOption method in Slick 3.*:

  def findById(userId: Int): Future[Option[User]] ={
    db.run(Users.filter(_.id === userId).result.headOption)
  }
like image 188
Saeed Zarinfam Avatar answered Sep 22 '22 20:09

Saeed Zarinfam


You could drop two lines out of your function by switching from list to firstOption. That would look like this:

def findById(userId: Int)(implicit session: Session): Option[User] = {
  val user = this.map { e => e }.where(u => u.id === userId).take(1)
  user.firstOption
}

I believe you also would do your query like this:

def findById(userId: Int)(implicit session: Session): Option[User] = {
  val query = for{
    u <- Users if u.id === userId
  } yield u
  query.firstOption
}
like image 27
cmbaxter Avatar answered Sep 24 '22 20:09

cmbaxter