通过递归查询省-市-区信息给前端-接口返回速度从1.5秒,优化到0.01s;从LambdaQueryWrapper查询--->sql编写查询->redis缓存

一、提出疑问-为什么要从数据库中把省市区信息返回给前端

1、本项目是一个商城项目-在进行计算运费价格的时候,需要知道用户所填地址信息,是否在包邮地区,并且根据距离、地区、包裹件数、重量等计算邮费,所以需要通过一个city_id来唯一区分城市id;

2、在全国范围内,存在同名的区名情况下,我不能根据简单的名称查询区查询城市的id,那么只能通过省份名称、市级名称、县级名称来唯一确定城市的id

3、因为地方名称的更改-数据库中的信息-可能和前端静态信息不匹配等,所以需要从数据中查询省市-区信息。
在这里插入图片描述

第一版本代码-

1、通过LambdaQueryWrapper 查询

2、通过封装响应类

3、通过递归查询

控制器代码

在这里插入图片描述

  @Operation(summary = "获取地址导航")
    @RequestMapping(value = "/getAddressHead", method = RequestMethod.GET)
    public List<CityInfoResponse> getAddressHead() {
        return systemCityService.getCityInfo();
    }

Service层代码

在这里插入图片描述

   @Override
    public  List<CityInfoResponse> getCityInfo() {
        LambdaQueryWrapper<SystemCity> lqwProvince=new LambdaQueryWrapper<>();
        lqwProvince.eq(SystemCity::getLevel,0);
        //获取所有城市省级城市信息
        List<SystemCity> systemCities0 = dao.selectList(lqwProvince);
        List<CityInfoResponse> cityInfoResponses = new ArrayList<>();
        for (SystemCity systemCity0 : systemCities0) {
            CityInfoResponse cityInfoResponse = new CityInfoResponse();
            BeanUtils.copyProperties(systemCity0,cityInfoResponse);
            //根据当前省级城市id,获取下辖的市信息
            Integer cityId0 = systemCity0.getCityId();
            List<CityInfoResponse> citys = getCityId(cityId0);
            cityInfoResponse.setCityInfoResponses(citys);
            cityInfoResponses.add(cityInfoResponse);
        }
        return cityInfoResponses;
    }
 /**
     * @Author luozhao
     * @Description 根据当前城市id,查询下级城市信息集合
     * @Date 11:32 2023/3/25
     * @param cityId
     **/
    List<CityInfoResponse> getCityId(Integer cityId){
        LambdaQueryWrapper<SystemCity> lqw=new LambdaQueryWrapper<>();
        lqw.eq(SystemCity::getParentId,cityId);
        List<SystemCity> systemCities1 = dao.selectList(lqw);
        List<CityInfoResponse> cityInfoResponses = new ArrayList<>();
        //第一次市级城市遍历
        for (SystemCity systemCity : systemCities1) {
            CityInfoResponse cityInfoResponse = new CityInfoResponse();
            if (systemCity.getLevel()!=2){
                Integer cityId1 = systemCity.getCityId();
                List<CityInfoResponse> citys2 = getCityId(cityId1);
                cityInfoResponse.setCityInfoResponses(citys2);
            }
            BeanUtils.copyProperties(systemCity,cityInfoResponse);
            cityInfoResponses.add(cityInfoResponse);
        }
        return cityInfoResponses;
    }

数据库基本结构-

在这里插入图片描述
在这里插入图片描述

第二版代码-去掉 拷贝对象,-直接返回响应类封装集合、

在这里插入图片描述

    @Override
    public  List<CityInfoResponse> getCityInfo1() {
        //获取所有城市省级城市信息
        List<CityInfoResponse> cityInfoResponses = dao.queryCityInfo(0,null);
        for (CityInfoResponse response : cityInfoResponses) {
            //根据当前省级城市id,获取下辖的市信息
            Integer cityId0 = response.getCityId();
            List<CityInfoResponse> citys = getCityId1(cityId0);
            response.setCityInfoResponses(citys);
        }
        return cityInfoResponses;
    }
    /**
     * @Author luozhao
     * @Description 根据当前城市id,查询下级城市信息集合
     * @Date 11:32 2023/3/25
     * @param cityId
     **/
    List<CityInfoResponse> getCityId1(Integer cityId){
        List<CityInfoResponse> cityInfoResponses = dao.queryCityInfo(null,cityId);
        //第一次市级城市遍历
        for (CityInfoResponse cityInfoResponse : cityInfoResponses) {
            if (cityInfoResponse.getLevel()!=2){
                //当前市级城市id
                Integer cityId1 = cityInfoResponse.getCityId();
                List<CityInfoResponse> citys2 = getCityId1(cityId1);
                cityInfoResponse.setCityInfoResponses(citys2);
            }
        }
        return cityInfoResponses;
    }

在这里插入图片描述
在这里插入图片描述

package com.fangzhou.service.vo.response;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

import java.util.List;

/**
 * @Classname CityInfoResponse
 * @Description TODO
 * @Version 1.0.0
 * @Date 2023/3/25 11:05
 * @Created by luozhao
 */
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@Tag(name="CityInfoResponse", description="")
public class CityInfoResponse {

    @Schema(title = "城市id")
    private Integer cityId;

    @Schema(title = "名称")
    private String name;

    @Schema(title = "上级城市id")
    private Integer parentId;

    @Schema(title = "城市等级",description = "0 、为省级、直辖市、特别行政区等; 1为市、0为县或者区等")
    private Integer level;

    private List<CityInfoResponse> cityInfoResponses;

}

在这里插入图片描述

    <select id="queryCityInfo" resultType="com.fangzhou.service.vo.response.CityInfoResponse">
        select city_id,
               `name`,
               parent_id,
               `level`
        from mh_system_city where 1=1

        <if test="parentId != null">
            AND  parent_id=#{parentId}
        </if>

        <if test="level != null">
            AND  level=#{level}
        </if>
    </select>

第三版本代码-通过redis存储,因为省-市-区很少变动

在这里插入图片描述

@Override
public  List<CityInfoResponse> getCityInfo1() {
    boolean cityInfo = redisCache.exists(RedisConstants.MH_SYSTEM_CITY_INFO);
    if (cityInfo) return  redisCache.get(RedisConstants.MH_SYSTEM_CITY_INFO);
    //获取所有城市省级城市信息
    List<CityInfoResponse> cityInfoResponses = dao.queryCityInfo(0,null);
    for (CityInfoResponse response : cityInfoResponses) {
        //根据当前省级城市id,获取下辖的市信息
        Integer cityId0 = response.getCityId();
        List<CityInfoResponse> citys = getCityId1(cityId0);
        response.setCityInfoResponses(citys);
    }
    redisCache.set(RedisConstants.MH_SYSTEM_CITY_INFO,cityInfoResponses);
    return cityInfoResponses;
}

第一版本 响应时间-平均1.5秒左右
在这里插入图片描述
第二版本响应时间-0.5秒左右
在这里插入图片描述
第三版本响应时间-0.01秒左右
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Code攻城狮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值