在anorm中有许多类似的dao方法,这是正确的吗?

4
我将使用Play2与anorm进行翻译。我认为anorm的精神是编写简单的SQL语句,没有任何魔法。
但我很快发现我需要编写许多类似的dao方法。例如:
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
}

这些方法几乎相同,唯一的区别是where子句有细微差别。

因此,我创建了一个名为findWhere()的方法:

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

我可以在操作中调用它:

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

它可以工作,但我认为anorm不建议使用这种方法。

解决这个问题的最佳方法是什么?

1个回答

3

你为什么认为不推荐或可以呢?

Anorm只关心接收SQL查询并将结果解析为case class。如果由于你的约束/设计需要动态生成SQL请求,那么这没有任何区别。

我唯一看到的问题是问号'?'的字符,这不是Anorm工作的方式。我相信更像是这样:

User.findWhere("username", username)

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

这是一个简单的例子,根据需要进行扩展。


1
它使用SQL字符串,但是如何创建这些字符串对它来说并不重要。或者我没有理解你的观点! :) - Pere Villega

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接