加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 使用Slick进行递归树状表查询

发布时间:2020-12-16 18:28:00 所属栏目:安全 来源:网络整理
导读:我的表数据形成一个树结构,其中一行可以引用同一个表中的父行. 我试图使用Slick实现的是编写一个返回行和所有子行的查询.此外,我想做同样的事情,但写一个将返回一个孩子及其所有祖先的查询. 换一种说法: findDown(1)应该返回 List(Group(1,"1"),Group(3,1,"
我的表数据形成一个树结构,其中一行可以引用同一个表中的父行.

我试图使用Slick实现的是编写一个返回行和所有子行的查询.此外,我想做同样的事情,但写一个将返回一个孩子及其所有祖先的查询.

换一种说法:

findDown(1)应该返回

List(Group(1,"1"),Group(3,1,"3 (Child of 1)"))

findUp(5)应该返回

List(Group(5,2,"5 (Child of 2)"),Group(2,"2"))

这是一个功能齐全的工作表(除了缺少的解决方案;-).

package com.exp.worksheets

import scala.slick.driver.H2Driver.simple._

object ParentChildTreeLookup {

  implicit val session = Database.forURL("jdbc:h2:mem:test1;",driver = "org.h2.Driver").createSession()

  session.withTransaction {
    Groups.ddl.create
  }

  Groups.insertAll(
    Group(1,"2"),"3 (Child of 1)"),Group(4,3,"4 (Child of 3)"),Group(5,Group(6,"6 (Child of 2)"))

  case class Group(
    id: Long = -1,id_parent: Long = -1,label: String = "")

  object Groups extends Table[Group]("GROUPS") {
    def id = column[Long]("ID",O.PrimaryKey,O.AutoInc)
    def id_parent = column[Long]("ID_PARENT")
    def label = column[String]("LABEL")
    def * = id ~ id_parent ~ label <> (Group,Group.unapply _)
    def autoInc = id_parent ~ label returning id into {
      case ((_,_),id) => id
    }

    def findDown(groupId: Long)(implicit session: Session) = { ??? }

    def findUp(groupId: Long)(implicit session: Session) = { ??? }
  }

}

一个非常糟糕的静态尝试findDown可能是这样的:

private def groupsById = for {
  group_id <- Parameters[Long]
  g <- Groups; if g.id === group_id
} yield g

private def childrenByParentId = for {
  parent_id <- Parameters[Long]
  g <- Groups; if g.id_parent === parent_id
} yield g


def findDown(groupId: Long)(implicit session: Session) = { groupsById(groupId).list union childrenByParentId(groupId).list }

但是,我正在寻找一种方法让Slick使用id和id_parent链接以递归方式搜索同一个表.任何其他解决问题的好方法都非常受欢迎.但请记住,最好尽量减少数据库往返次数.

解决方法

您可以尝试从光滑调用SQL.上层次结构的SQL调用看起来像这样(这适用于SQL Server):

WITH org_name AS 
(
    SELECT DISTINCT
        parent.id AS parent_id,parentname.label as parent_label,child.id AS child_id,childname.ConceptName as child_label
    FROM
        Group parent RIGHT OUTER JOIN 
        Group child ON child.parent_id = parent.id
),jn AS 
(   
    SELECT
        parent_id,parent_label,child_id,child_label
    FROM
        org_name 
    WHERE
        parent_id = 5
    UNION ALL 
        SELECT
            C.parent_id,C.parent_label,C.child_id,C.child_label 
        FROM
            jn AS p JOIN 
            org_name AS C ON C.child_id = p.parent_id
) 
SELECT DISTINCT
    jn.parent_id,jn.parent_label,jn.child_id,jn.child_label
FROM
    jn 
ORDER BY
    1;

如果您想要进入层次结构,请更改以下行:

org_name AS C ON C.child_id = p.parent_id

org_name AS C ON C.parent_id = p.child_id

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读