• 记录一次优化-通过列表合并关联查询降低数据库连接次数


    需求:有一个界面上的列表数据来自两个源头,界面需要将两部分数据合并后显示

    简介:

    源头一(数据库):id(主键),userId(用户编号),menuId(菜单编号),dataType(数据权限)

    源头二(HTTP接口):id(主键),userId(用户编号),menuId(菜单编号)

    界面需要的字段:id(主键),userId(用户编号),menuId(菜单编号),dataType(数据权限)

    说明:数据以接口数据为主,但是接口没有数据权限,所以数据权限要取数据库中的数据.

    优化前的做法:

    在获取到网络数据后,遍历列表,在遍历的过程中根据userId,menuId查询dataType,封装数据

    优化前的弊端:

    多次查询数据库,效率低,浪费资源

    优化策略1:

    1,获取网络数据

    2,获取数据库数据

    3,用流合并两部分数据后返回到界面

    下面是部分代码:

        /**
         * @author: songyan
         * @methodsName: getPermission
         * @description: 流的方式合并两个列表
         * @return: com.kit.api.model.ApiResultModel
         */
        @Override
        public ApiResultModel getPermission() {
            //获取网络数据
            List<Permission> permissionList = getDataList();
            //获取数据库数据
            List<Permission> permissionList1 = testDao.getPermissionList(permissionList);
            //返回合并的数据
            permissionList.stream().forEach(permission -> {
                permissionList1.stream()
                        .filter(item2 -> permission.getUserId().equals(item2.getUserId()) && permission.getMenuId().equals(item2.getMenuId()))
                        .forEach(item2 -> permission.setDataType(item2.getDataType()));
            });
            return ApiResultModelUtil.success(permissionList);
        }
        /**
         * @author: songyan
         * @methodsName: getPermissionList
         * @param: permissionList
         * @description: 查询数据库里的权限信息
         * @return: java.util.List<com.kit.api.test.stream.Permission>
         */
        @Select({"<script>select t.id,t.userId,t.menuId,t.dataType from (select concat(user_id,'-',menu_id) pid,id,user_id userId,menu_id menuId,data_type dataType from test_permission) t where t.pid in",
                "<if test='permissionList != null and permissionList.size() != 0'>(<foreach collection='permissionList' item='item' index='index' separator=','>",
                "#{item.userId}-#{item.menuId}",
                "</foreach>)</if>",
                "</script>"})
        List<Permission> getPermissionList(@Param("permissionList") List<Permission> permissionList);

    优化策略2:

    1,创建临时表(用于存储网络数据)

    2,将网络数据存到临时表

    3,通过表连接的方式合并数据

    4,删除临时表

    说明:需要考虑并发访问创建删除同一张临时表的情况,所以要加同步标识(synchronized),这里也可以创建不同表名的临时表.

    下面是部分代码:

        /**
         * @author: songyan
         * @methodsName: getPermission2
         * @description: 临时表的方式通过表的连接合并数据
         * @return: com.kit.api.model.ApiResultModel
         */
        @Override
        public synchronized ApiResultModel getPermission2() {
            //删除临时表
            testDao.dropTempTable();
            //创建临时表
            testDao.createTempTable();
            //获取网络数据
            List<Permission> permissionList = getDataList();
            //存储网络数据
            testDao.insertTempPermission(permissionList);
            //获取数据
            List<Permission> permissionList1 = testDao.getPermissionList2();
            //删除临时表
            testDao.dropTempTable();
            return ApiResultModelUtil.success(permissionList1);
        }
        /**
         * @author: songyan
         * @methodsName: createTempTable
         * @description: 创建临时表存储网络数据
         * @return: void
         */
        @Update("create temporary table temp_permission " +
                "( " +
                "    id        varchar(36) null, " +
                "    user_id   varchar(36) null, " +
                "    menu_id   varchar(36) null, " +
                "    data_type int         null " +
                ") ")
        void createTempTable();
    
        /**
         * @author: songyan
         * @methodsName: insertTempPermission
         * @param: permissionList
         * @description: 将网路数据存储到临时表
         * @return: void
         */
        @Insert({"<script>insert into temp_permission(id, user_id, menu_id, data_type) VALUES",
                "<if test='permissionList != null and permissionList.size() != 0'><foreach collection='permissionList' item='item' index='index' separator=','>",
                "(#{item.id},#{item.userId},#{item.menuId},#{item.dataType})",
                "</foreach></if>",
                "</script>"})
        void insertTempPermission(@Param("permissionList") List<Permission> permissionList);
    
        /**
         * @author: songyan
         * @methodsName: getPermissionList2
         * @description: 关联权限表, 临时表获取合并后的数据
         * @return: java.util.List<com.kit.api.test.stream.Permission>
         */
        @Select("select a.id, a.user_id userId, a.menu_id menuId, b.data_type dataType  " +
                "from temp_permission a  " +
                "         left join test_permission b on a.user_id = b.user_id and a.menu_id = b.menu_id  ")
        List<Permission> getPermissionList2();
    
        /**
         * @author: songyan
         * @methodsName: dropTempTable
         * @description: 删除临时表
         * @return: void
         */
        @Update("drop temporary table temp_permission")
        void dropTempTable();
  • 相关阅读:
    clickhouse集群部署
    zookeeper集群部署
    linux下安装多路径multipath
    采用xtrabackup部署主从同步(生产)
    部署dg备库同步ogg
    goldengate同步(主库rac从库单节点)
    python3发送邮件
    python2发送邮件
    pip版本过高导致报错
    ERROR 1558 (HY000): Column count of mysql.user is wrong
  • 原文地址:https://www.cnblogs.com/excellencesy/p/14571994.html
Copyright © 2020-2023  润新知