Hay muchos métodos DAO similares en Anorm, ¿es correcto?
-
28-10-2019 - |
Pregunta
Estoy usando Play2 con Anorm. Creo que el espíritu de Anorm es escribir SQLS simple, sin magia detrás.
Pero rápidamente descubrí que he escribido muchos métodos DAO similares. Por ejemplo:
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
}
Los métodos son casi los mismos, excepción de la where
La cláusula tiene una pequeña diferencia.
Entonces creé un findWhere()
Método AS:
def findWhere(conditon, values:Any*) = ...
Que puedo llamarlo en acciones:
User.findWhere("id=?", id)
User.findWhere("username=?", username)
Funciona, pero no creo que sea recomendado por Anorm.
¿Cuál es la mejor manera de resolver este problema?
Solución
¿Por qué crees que no se recomienda o está bien?
Anorma solo se preocupa de recibir una consulta SQL y analizar el resultado en una clase de caso. Si se debe a sus restricciones/diseño, genera esa solicitud de SQL dinámicamente, eso no hace ninguna diferencia.
El único problema que veo es con él '?' Char, que es así como funciona Anorm. Creo que sería más como:
User.findWhere("username", username)
def findWhere(field: String, value: String) = {
SQL("select * from users where "+ field +"={"+ field +"}").on(Symbol(field)->value).as(simple.singleOpt)
}
Este es un ejemplo simple, se extiende según sea necesario.