Question

I'm using Play2 with anorm. I think the spirit of anorm is write plain sqls, no magic behind.

But I quickly found I have write a lot of similar dao methods. For example:

case class User(id:Pk[String], username:String, email:String, realname:String, city:String, website:String)

object User {
  val simple = get[Pk[String]]("id") ~ get[String]("username") ~ ... get[String]("website") map {
    case id ~ username ~ ... ~ website = User(id, username, ..., website)
  }
  def findByUsername(username:String) = DB.withConnection { implicit connection =>
     SQL("select * from users where username={username}").on('username->username).as(simple.singleOpt)
  }
  def findByEmail(email:String) = DB.withConnection { implicit connection =>
     SQL("select * from users where email={email}").on('email->email).as(simple.singleOpt)
  }
  def findById(id:String) = DB.withConnection { implicit connection =>
     SQL("select * from users where id={id}").on('id->id).as(simple.singleOpt)
  }
  def findByRealname(keyword:String) = DB.withConnection { implicit connection =>
     SQL("select * from users where realname like {keyword}").on('keyword->"%"+keyword+"%").as(simple *)
  }
  // more similar methods
}

There methods are almost the same, exception the where clause has small difference.

So I created a findWhere() method as:

def findWhere(conditon, values:Any*) = ...

That I can call it in actions:

User.findWhere("id=?", id)
User.findWhere("username=?", username)

It works, but I don't think it's recommended by anorm.

What's the best way to solve this problem?

Was it helpful?

Solution

Why do you believe it is not recommended or ok?

Anorm only cares of receiving a SQL query and parsing the result into a case class. If due to your constraints/design you generate that SQL request dinamically, that makes no difference.

The only issue I see is witht he '?' char, which is nto the way Anorm works. I believe it would me more like:

User.findWhere("username", username)

def findWhere(field: String, value: String) = {
  SQL("select * from users where "+ field +"={"+ field +"}").on(Symbol(field)->value).as(simple.singleOpt)
}

This is a simple example, extend as required.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top