There are many similar dao methods in anorm, is it right?
-
28-10-2019 - |
문제
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?
해결책
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.