我有两个sql语句要执行并进行有效性检查。我需要的是,我执行第一个查询并将响应存储在一个对象中并检查对象是否为空,如果它不为空,则执行第二个查询。 所以,我尝试过像
这样的东西在rolerepository.scala =>
中 override val allQuery = s"""
select UserRoles.* from
(select CASE rbac.roleTypeID
ELSE rbac.name JOIN dirNetworkInfo ni
ON UserRoles.PersonID = ni.PersonID
where ni.Loginname = {loginName}
and UserRoles.roleName in ( 'Business User ','Administrator')"""
(这只是查询的一些示例 - 这里没有完全写出来。) 然后我将它映射到一个模型类写在
之外的对象 override def map2Object(implicit map: Map[String, Any]):
HierarchyEntryBillingRoleCheck = {
HierarchyEntryBillingRoleCheck(str("roleName"), oint("PersonID")) }
然后我编写了getall方法来执行查询
override def getAll(implicit loginName: String):
Future[Seq[HierarchyEntryBillingRoleCheck]] = {
doQueryIgnoreRowErrors(allQuery, "loginName" -> loginName) }
然后我编写了方法来检查第一个sql的响应是否为空。这是我被困住了,无法继续前进。
def method1()= {
val getallresponse = HierarchyEntryBillingRoleCheck
getallresponse.toString
if (getallresponse != " ")
billingMonthCheckRepository.getrepo()
}
我在最后一个右大括号中遇到错误(类型不匹配),我不知道这里可以使用哪些其他逻辑。 你们中的任何一个人都可以解释并给我一些解决方案吗?
我也尝试在控制器中使用for循环,但没有得到如何做到这一点。
我试过了 - >
def getAll(implicit queryParams: QueryParams,
billingMonthmodel:Seq[HierarchyEntryBillingRoleCheck]):
Action[AnyContent] = securityService.authenticate() { implicit request
=> withErrorRecovery { req =>
toJson {
repository.getAll(request.user.loginName)
for {
rolenamecheck <- billingMonthmodel
}yield rolenamecheck
}}}}
答案 0 :(得分:1)
哇我不知道这里的格式化是怎么回事,我真的试图在工具栏上使用代码格式化程序,但我不知道为什么它不会格式化,即使多次按下也是如此。我邀请社区编辑我的代码格式,因为我无法弄明白。向OP道歉。
因为我发现如果你不熟悉Play的文档很难跋涉,我不会仅仅留下链接。
@Singleton class LoginRegController @Inject()(**myDB: Database**, cc: ControllerComponents ) { // do stuff }
但是,在控制器中实际使用此连接是不好的做法,因为JDBC是一个阻塞操作,因此您需要创建一个Model,它将db作为方法的参数。不要将对象的构造函数设置为获取DB并将其存储为字段。由于某种原因,这会导致连接泄漏,并且在完成查询后连接将不会释放。不知道为什么,但就是这样。
创建一个用于执行查询的Model对象。不是通过对象的构造函数传递DB,而是将其传递给您将创建的方法:
对象DBChecker { def attemptLogin(db:Database,password:String):String = {
}}
在您的方法中,使用方法.withConnection { conn =>
来访问JDBC连接。所以,像这样:
对象DBChecker {
def attemptLogin(db:Database,password:String):String = {
var username:String =“”
db.withConnection {conn =&gt;
val query:String = s"SELECT uploaded_by, date_added FROM tableName where PASSWORD = $password ;"
val stmt = conn.createStatement()
val qryResult:ResultSet = stmt.executeQuery(query)
// then iterate over your ResultSet to get the results from the query
if (qryResult.next()) {
userName = qryResult.getString("uploaded_by")
} } } 返回用户名 }
//请注意,请查看PreparedStatement对象的使用,这样做会让您容易受到SQL注入攻击。
在Controller中,只要导入对象,就可以从步骤1中创建的控制器中调用该对象的方法。
import com.path.to.object.DBChecker
@Singleton
class LoginRegController @Inject()( myDB:Database ,cc:ControllerComponents){def attemptLogin(pass:String)= Action {
隐式请求:请求[AnyContent] =&gt; {
val result:String = DbChecker.attemptLogin(pass)
// do your work with the results here
}
答案 1 :(得分:1)
您不会说出您正在使用的数据库访问方法。 (我假设是anorm)。解决这个问题的一种方法是:
例如,也许你有:
case class UserRole (id:Int, loginName:String, roleName:String)
然后
object UserRole {
val sqlFields = "ur.id, ur.loginName, ur.roleName"
val userRoleParser = {
get[Int]("id") ~
get[String]("loginName") ~
get[String]("roleName") map {
case id ~ loginName ~ roleName => {
UserRole(id, loginName, roleName)
}
}
}
...
解析器将行映射到您的case类。下一步是创建单行方法,如findById
或findByLoginName
和多行方法,可能是allForRoleName
或其他通用过滤方法。在您的情况下,可能(假设每个loginName有一个角色)类似于:
def findByLoginName(loginName:String):Option[UserRole) = DB.withConnection { implicit c =>
SQL(s"select $sqlFields from userRoles ur ...")
.on('loginName -> loginName)
.as(userRoleParser.singleOpt)
}
.as(parser...
是关键。通常,您至少需要:
as(parser.singleOpt)
返回您的案例类的Option
as(parser *)
返回您的案例类List
(如果登录可能存在多个角色,则您需要此as(scalar[Long].singleOpt)
返回Option[Long]
,方便返回counts
或exists
值然后,为了最终直接回到你的问题,你可以调用你的find方法,如果它返回一些东西,继续第二个方法调用,也许是这样:
val userRole = findByLoginName(loginName)
if (userRole.isDefined)
billingMonthCheckRepository.getrepo()
或者,更加惯用
findByLoginName(loginName).map { userRole =>
billingMonthCheckRepository.getrepo()
...
我已经看到find方法返回Option
,但实际上我们发现返回Either[String,(your case class)]
更有用,然后字符串包含失败的原因。 Either
很酷。
在我的游戏版本(2.3.x)中,上面的导入是:
import play.api.db._
import play.api.Play.current
import anorm._
import anorm.SqlParser._
你将会做很多这样的事情,所以值得找一套适合你的模式。