需求:有一个界面上的列表数据来自两个源头,界面需要将两部分数据合并后显示
简介:
源头一(数据库):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();