首页 > 其他分享 >golang中员工分组分页获取的一种方案

golang中员工分组分页获取的一种方案

时间:2024-03-01 18:33:43浏览次数:25  
标签:node Name 组分 Pid 员工 golang data Id append

在业务中,有一个场景,A系统需要提供一个接口,返回组织架构信息,供B系统入库,即B系统的组织架构是从A系统中同步过来的。

这个场景下存在一个小问题,B系统期望A系统按照组织树层序遍历分页返回。这样B系统就不需要担心新增组织时找不到父级组织了。


那么A系统要怎么做呢?


方案1:在数据库查询时,从根节点递归查询。

方案2:获取全部组织数据后,构建形成多叉树,常驻内存,然后从根节点层序遍历。


如果既不能直接查询数据库,又不想维护多叉树,怎么办呢?


下面的方案也许可以参考:

1、分页获取无序的组织list,并整合成golang的切片

2、从根节点出发,通过程序实现数据库的递归查询

示例如下:


package tree

import "fmt"

type node struct {
    Id   string `json:"id"`
    Name string `json:"name"`
    Pid  string `json:"pid"`
}

var data = make([]node, 0, 10)

func SliceTreeSort() {
    makeSliceTreeData()

    // 输出排好序的结果
    fmt.Println("排序前:")
    for _, v := range data {
       fmt.Println(v.Id, v.Name, v.Pid)
    }

    // 记录元素的索引的顺序
    IdxSort := make([]int, 0, len(data))
    // IdxSort的辅助变量,帮助判断索引是否已经在IdxSort存在
    idxSet := make(map[int]bool, len(data))
    // 记录已经处理过的Pid集合
    pidSet := make(map[string]bool, len(data))
    // 根节点默认已经处理过了
    pidSet[`-1`] = true

    // 遍历寻找
    for i := 0; i < len(data); i++ {
       // 如果IdxSort已经满了,说明已经排好序了
       if len(idxSet) == len(data) {
          break
       }
       for k, v := range data {
          // 已记录的节点,不需要处理了
          if _, ok := idxSet[k]; ok {
             continue
          }
          // 判断当前节点的父节点是否在pidSet,在说明可以取v.Pid下所有的子节点,孙子、曾孙等节点还不能取
          if _, ok := pidSet[v.Pid]; ok {
             pidSet[v.Id] = true          // 取子节点,为下次判断子节点的子节点做准备
             IdxSort = append(IdxSort, k) // 记录子节点的索引
             idxSet[k] = true             // 标记子节点已经记录
          }
       }
    }

    // 按照上边idxSort计算的切片key顺序,重新排序
    outData := make([]node, 0, len(data))
    for _, v := range IdxSort {
       outData = append(outData, data[v])
    }

    // 如果是分页对外提供接口,则可以讲切片缓存下来。
    // 根据分页信息截切

    fmt.Println("排序后:")
    fmt.Println(outData)
}

func makeSliceTreeData() {
    var n node

    n = node{Id: "0", Name: "公司", Pid: "-1"}
    data = append(data, n)

    n = node{Id: "1000131", Name: "部门1-3-1", Pid: "100013"}
    data = append(data, n)
    n = node{Id: "1000132", Name: "部门1-3-2", Pid: "100013"}
    data = append(data, n)
    n = node{Id: "1000133", Name: "部门1-3-3", Pid: "100013"}
    data = append(data, n)

    n = node{Id: "10001", Name: "部门1", Pid: "0"}
    data = append(data, n)
    n = node{Id: "10002", Name: "部门2", Pid: "0"}
    data = append(data, n)
    n = node{Id: "10003", Name: "部门3", Pid: "0"}
    data = append(data, n)

    n = node{Id: "1000121", Name: "部门1-2-1", Pid: "100012"}
    data = append(data, n)
    n = node{Id: "1000122", Name: "部门1-2-2", Pid: "100012"}
    data = append(data, n)
    n = node{Id: "1000123", Name: "部门1-2-3", Pid: "100012"}
    data = append(data, n)

    n = node{Id: "1000111", Name: "部门1-1-1", Pid: "100011"}
    data = append(data, n)
    n = node{Id: "1000112", Name: "部门1-1-2", Pid: "100011"}
    data = append(data, n)
    n = node{Id: "1000113", Name: "部门1-1-3", Pid: "100011"}
    data = append(data, n)

    n = node{Id: "100011", Name: "部门1-1", Pid: "10001"}
    data = append(data, n)
    n = node{Id: "100012", Name: "部门1-2", Pid: "10001"}
    data = append(data, n)
    n = node{Id: "100013", Name: "部门1-3", Pid: "10001"}
    data = append(data, n)

}

标签:node,Name,组分,Pid,员工,golang,data,Id,append
From: https://www.cnblogs.com/zhimajiang/p/18047711

相关文章

  • golang wire依赖注入
    安装gogetgithub.com/google/wire/cmd/wire@latest一.假设需要定义多个有依赖的启动项,新建main.gopackagemainimport("fmt")typeMessagestringfuncNewMessage()Message{returnMessage("Hithere!")}typeEventstruct{GreeterGreeter}......
  • golang中关于map的value类型定义为函数类型时(方法值)的一点点思考
    文章的内容仅仅是自己关于map的value类型定义为函数类型时的一点点思考,如有不对的地方,请不吝赐教。学习过后才知道叫做方法值。1、起因最近在看老项目代码时,看到了一段类似于下面的定义,最开始看到的时候,对于LotMap的用法比较疑惑,为什么mapvalue定义的函数类型是func(r......
  • Golang面试
    slice扩容机制GO1.17版本及之前当新切片需要的容量cap大于两倍扩容的容量,则直接按照新切片需要的容量扩容;当原slice容量<1024的时候,新slice容量变成原来的2倍;当原slice容量>1024,进入一个循环,每次容量变成原来的1.25倍,直到大于期望容量。GO1.18之后当新切片......
  • golang dlv程序调试
    安装dlv执行goinstall安装dlvgoinstallgithub.com/go-delve/delve/cmd/dlv@latest执行dlvversion查看是否安装成功$dlvversionDelveDebuggerVersion:1.22.0Build:$Id:61ecdbbe1b574f0dd7d7bad8b6a5d564cce981e9$断点调试dlv有以下三种方式进行断点调试:......
  • 针对员工的"摸鱼"行为,如何确保数据安全和工作效率?
    在现代职场,"摸鱼"行为已经成为一个无法忽视的问题。员工能够通过各种在线平台进行社交聊天、购物、炒股、看电影等活动,这无疑对企业的数据安全和工作效率产生了影响。针对这一问题,我们需要从以下几个方面进行思考和采取措施。我们需要对员工的在线行为进行有限度的监控。利用华......
  • golang文件和目录操作
    读取文件通过Read方法读取import( "fmt" "os")funcmain(){ /* 打开文件 */ //以只读的方式打开文件,返回一个文件指针类型的对象和error file,err:=os.Open("./test.txt") //文件打开操作完之后必须关闭文件流,可以使用defer延迟关闭 deferfile.Close()......
  • golang反射
    反射有时我们需要写一个函数,这个函数有能力统一处理各种值类型,而这些类型可能无法共享同一个接口,也可能布局未知,也有可能这个类型在我们设计函数时还不存在,这个时候我们就可以用到反射反射是指在程序运行期间对程序本身进行访问和修改的能力。正常情况程序在编译时,变量被转换......
  • golang 系统调用与阻塞处理
    所有在UNIX系统上运行的程序最终都会通过C系统调用来和内核打交道。用其他语言编写程序进行系统调用,方法不外乎两个:一是自己封装,二是依赖glibc、或者其他的运行库。Go语言选择了前者,把系统调用都封装到了syscall包。封装时也同样得通过汇编实现。当M一旦进入系统调用后,会......
  • golang io优化
    如果想兼顾开发效率,又能保证高并发,协程就是最好的选择。它可以在保持异步化运行机制的同时,用同步方式写代码(goroutine-per-connection),这在实现高并发的同时,缩短了开发周期,是高性能服务未来的发展方向。CPU和IO设备是不同的设备,能并行运行。合理调度程序,充分利用硬件,就能跑出......
  • golang性能优化
    性能优化流程理清待优化代码的常用逻辑与场景根据实际场景编写压测用例使用pprof或者火焰图等工具取得数据找到热点代码重点优化Profilingpprof是用于可视化和分析性能分析数据的工具。为什么pprof可以帮助我们分析Go程序性能呢?因为它可以采集程序运行时数据:比如说协程栈,这样服......