zoukankan      html  css  js  c++  java
  • 【分享】(性能优化)思考数据列表中“特殊的列”

      数据列表在应用程序中十分常见和普遍,尤其是管理类的软件操作界面,如:一个待办列表,邮件列表,用户列表等。数据列表的数据源是由我们通过数据查询,逻辑运算,最终展示为列表。

      我们来看一种需求场景,假设列表中有一个“特殊的列“,它的数据不直接对应为数据库的列,或者是视图中的列,而是需要通过查询另外的关联表,通过计算得出,那么在绑定数据的时候,如何绑定上去呢?

    假如:有一张表单表(tab_FormData),列如下:

          Id,FormId(表单Id),Title(标题),Content(内容)。。。

    和一张任务表(tab_TaskInfo),列如下:

          Id,FormId(外键与tab_FormData的FormId),UserId(任务所有者Id),UserName(用户姓名),Comment(批示),Status(办理状态),CreateTime(任务创建时间)。。。

      当流程走到一个节点B时,一个表单可能对应着多个该节点的任务。如:该节点为【领导审批】节点,有三个领导做了批示(对应着任务表中三条记录),批示的内容分别为(圈阅,请张三领导阅,圈阅),当流转到下一节点【分发】时,需要补充张三领导,然后再回到【领导审批】节点,让张三领导去审批。那么在待办【分发】列表中,需要提示某一条公文是否有领导批示的不是圈阅的意见。如果存在,就在列表上标记出来,不存在就不标记。要显示的列表如下:有4列

      FormId,Title,Content,提醒()

       001      公文的标题   公文的内容  是

    最后一列,是通过表单Id从任务表中查询得出。伪linq代码:

    public static bool IsExist(string formId)

    {

      var query=from t in ObjectContext.tab_TaskInfo

            where t.FormId=formId && t.NodeId=领导节点 && t.Comment!="圈阅"

            select t;

      return query.Count()>0;

    }

    在循环绑定列表的时候,每一行数据都需要去做上面的查询,以便绑定最后一列。

    提问:有没有更好的解决方法,去绑定像上面这种情况的“特殊列”呢?

    如果把”特殊列“的逻辑封装成一个方法,是比较直观的做法。在上述情况下,则带来的是多次查询数据库,性能有所损失。

    解决方法:

      1.如果只查询一次数据库,就能得到所有的列,这样最好了。做表连接查询

      2.将特殊列的逻辑放在一个函数中,这样便于复杂逻辑处理,直观。这样这个”特殊列“就需要多次查询数据库。有些情况下,可能需要连接多张表才能得到结果。

    给出另外一种思路:列表中除”特殊列“之外的进行(第一次查询),在把(第一次查询)相关的数据进行第二次查询,然后在内存中把这两次的查询结果处理拼接起来。

    当然这个列表是需要分页显示的。给出linq伪代码:           

    //获取和当前页相关的数据列表(第二次查询),第一个参数当前页的列表,返回当前页相关的任务列表
    Func<IEnumerable<tab_FormData>, IEnumerable<tab_TaskInfo>> getGridContext = rows =>
    {
    return FormDataBLL.GetLeaderTasks(rows.Select(p => p.Formid).ToArray());//这里查询出符合条件的结果(t.NodeId=领导节点 && t.Comment!="圈阅")
    };
    //列筛选表达式
    Func<tab_FormData, IEnumerable<tab_TaskInfo>, object> selector = (row, gridContext) =>//row表示当前行,gridContext表示当前页的相关数据列表
    {
    var hasLeaderComment = gridContext.Where(p => p.formid == row.formid)
    .Count() > 0;//内存处理
    return new
    {
    id = row.id,
    formid = row.formid,
    Title = row.Title,
    Content = row.Content,
    HasComment = hasLeaderComment
                    };
    };


    页面绑定伪代码:

    JQueryUI.GridRender<tab_FormData, tab_TaskInfo>(source, getGridContext, selector, context.Request, context.Response);

    实现的关键代码:

    var  viewPageList = pageData.ToList();//一页的数据,(第一次查询)
    //重写行
    if (viewPageList.Count > 0)
    {
    tempList = new List<object>();
    foreach (var item in viewPageList)
    {
    var model = selector(item, viewPageList);
    tempList.Add(model);
    }
    }

    string jsonData = DataConvertUtility.ToJson(tempList);//得到最终的所有列,用于显示

    总结:这样带有“特殊列”的列表,只需要查询两次数据库,就可以得到需要的结果,当然这是取一个平衡点,上述的当前页的相关的任务列表数据量不大。

    好了,时间有点晚了,睡觉,下次再补充下,请各位同学谅解,如有疑问,提出来我们一起讨论,共同进步,谢谢!

  • 相关阅读:
    使用JavaWeb实现文件的上传和下载
    IDEA使用Maven创建Web项目的两种方式
    Window10系统下联想笔记本进入BIOS界面方法
    MarkDown语法
    PV-UV-QPS
    expect 安装 salt 客户端
    fg、bg、jobs、&、nohup、ctrl+z、ctrl+c 命令
    查看CPU 内存 硬盘 网络 查看进程使用的文件 uptime top ps -aux vmstat iostat iotop nload iptraf nethogs
    rpm 命令使用 和 lsof -p 1406 使用
    salt 执行shell 脚本 修改名字
  • 原文地址:https://www.cnblogs.com/skysoft001/p/2313859.html
Copyright © 2011-2022 走看看