Scala Slick 3.1.x如何实现多对多连接?
在Scala Slick 3.1.x如何实现多对多连接?,scala,slick,Scala,Slick,在UserDao中,我试图定义一个方法,给定一个用户将获得分配给它的所有安全角色。这是一个多对多关系,这里是伪数据库设计(): 因此,我尝试如下定义我的getRoles函数: def getRoles(user: UserRow) : Future[List[SecurityRoleRow]] = { val action = for { role <- SecurityRole join UserSecurityRole on (_.id === _.securityRoleId
UserDao
中,我试图定义一个方法,给定一个用户将获得分配给它的所有安全角色。这是一个多对多关系,这里是伪数据库设计():
因此,我尝试如下定义我的getRoles
函数:
def getRoles(user: UserRow) : Future[List[SecurityRoleRow]] = {
val action = for {
role <- SecurityRole join UserSecurityRole on (_.id === _.securityRoleId)
join User on (_.userId === _.id)
} yield role
db.run(action)
}
def getRoles(user: UserRow) : Future[List[SecurityRoleRow]] = {
val action = for {
role <- SecurityRole join (UserSecurityRole join User on (_.userId === _.id)) on (_.id === _.securityRoleId)
} yield role
db.run(action)
}
就这样。然后,如果我想将此SQL平滑化到我的UserDao
中,我可以:
def getRoles(user: UserRow) : Future[List[SecurityRoleRow]] = {
val action = sql"""SELECT t1.* " +
"FROM SecurityRole t1, " +
"UserSecurityRole t2, " +
"WHERE t1.id = t2.securityRoleId " +
"AND ${user.id} = t2.userId""".as[SecurityRoleRow]
db.run(action)
}
您基本上是对的(嗯,有点像,它们并没有被删除,而是元组得到了扩展)。与此相反:
def getRoles(user: UserRow) : Future[List[SecurityRoleRow]] = {
val action = for {
role <- SecurityRole join UserSecurityRole on (_.id === _.securityRoleId)
join User on (_.userId === _.id)
} yield role
db.run(action)
}
每个新连接都会添加新的嵌套元组。请看我在这里的演示文稿中的这张幻灯片(我用模式匹配来解构每种类型的元组,但都是一样的):(特别是,请看下一张幻灯片,它通过使用外键使其更加整洁;在您的情况下,这将是一个完美的解决方案)
编辑:
即使不定义外键(我认为您应该这样做),也可以将版本更改为一元形式,从而避免所有元组嵌套:
val action = (for {
role <- SecurityRole
userRole <- UserSecurityRole if role.id === userRole.securityRoleId
user <- User if userRole.userId === user.id
} yield role).result
db.run(action)
val action=(用于{
role@giovanni azua基本上我建议你看一下演示文稿和相关的回购协议。这是对Slick 3.x基础知识的一种快速介绍。在参考资料部分,你还可以链接到Dave Gurnell主持的非常好的研讨会录音()感谢您的详尽回答!使用pure slick与SQL版本的性能比较如何?我将找到如何获取生成的SQL以获得想法。非常感谢!您已经在我链接的幻灯片上生成了SQL。此外,要轻松查看生成的内容,只需将这组记录器添加到logback.xml
:
def getRoles(user: UserRow) : Future[List[SecurityRoleRow]] = {
val action = for {
role <- SecurityRole join UserSecurityRole on (_.id === _.securityRoleId)
join User on (_.userId === _.id)
} yield role
db.run(action)
}
def getRoles(user: UserRow) : Future[List[SecurityRoleRow]] = {
val action = (for {
role <- SecurityRole join UserSecurityRole on (_.id === _.securityRoleId)
join User on (_._2.userId === _.id) // here is the change!!
} yield role).result
db.run(action)
}
val action = (for {
role <- SecurityRole
userRole <- UserSecurityRole if role.id === userRole.securityRoleId
user <- User if userRole.userId === user.id
} yield role).result
db.run(action)