对应的sql脚本 :

[ SQL脚本 ](https://gitee.com/liurunyong/address-sql)

一、流程

1、先把对应的SpringBoot 工程创建起来;
2、让你创建的工程连接对应的数据库,Redis服务;
3、开始编写代码,(此次我只提供对应的类、方法、和sql文件)
4、因为我使用的MyBatisPlus,所以mapper接口我就不展示了;

二、开始

1、model类:

ProvinceModel:

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;

/**
 * @Author: battery
 * @Date: 2021/03/26
 * @Description:
 */

@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
@ApiModel(description = "省")
@TableName(value = "province")
public class ProvinceModel implements Serializable {

    private Long provinceCode;

    private String provinceName;

    @TableField(exist=false)
    private CityModel cityModel;
}

CityModel
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;

/**
 * @Author: battery
 * @Date: 2021/03/26
 * @Description:
 */

@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
@ApiModel(description = "市")
@TableName(value = "city")
public class CityModel implements Serializable {

    private Long cityCode;

    private String cityName;

    private Long superiorCode;
}

AreaModel

import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;

/**
 * @Author: battery
 * @Date: 2021/03/26
 * @Description:
 */

@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
@ApiModel(description = "区/县")
@TableName(value = "area")
public class AreaModel implements Serializable {

    private Long areaCode;

    private String areaName;

    private Long superiorCode;
}
SubDistirct
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;

/**
 * @Author: battery
 * @Date: 2021/03/26
 * @Description:
 */

@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
@ApiModel(description = "街道办")
@TableName(value = "sub_district")
public class SubDistrictModel implements Serializable {

    private Long subDistrictCode;

    private String subDistrictName;

    private Long superiorCode;
}

2、Mapper

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.liu.health.model.dictionary.ProvinceModel;

/**
 * @Author: battery
 * @Date: 2021/03/26
 * @Description:
 */
public interface ProvinceMapper extends BaseMapper<ProvinceModel> {
}


import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.liu.health.model.dictionary.CityModel;
/**
 * @Author: battery
 * @Date: 2021/03/26
 * @Description:
 */
public interface CityMapper extends BaseMapper<CityModel> {
}

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.liu.health.model.dictionary.AreaModel;
/**
 * @Author: battery
 * @Date: 2021/03/26
 * @Description:
 */
public interface AreaMapper extends BaseMapper<AreaModel> {
}


import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.liu.health.model.dictionary.SubDistrictModel;
/**
 * @Author: battery
 * @Date: 2021/03/26
 * @Description:
 */
public interface SubDistrictMapper extends BaseMapper<SubDistrictModel> {
}

3、Service

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.liu.health.model.dictionary.ProvinceModel;

import java.util.List;

/**
 * @Author: battery
 * @Date: 2021/03/26
 * @Description:
 */
public interface ProvinceService extends IService<ProvinceModel> {
    /**
     * 获取所有的省份
     * @param queryWrapper 查询条件
     * @return list
     */
    List<ProvinceModel> selectAllData(QueryWrapper<ProvinceModel> queryWrapper);
}


import com.baomidou.mybatisplus.extension.service.IService;
import com.liu.health.model.dictionary.CityModel;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;

/**
 * @Author: battery
 * @Date: 2021/03/26
 * @Description:
 */
public interface CityService extends IService<CityModel> {

    /**
     * 根据省份编号查询城市信息
     * @param provinceCode 省份编号
     * @return list
     */
    List<CityModel> selectCityDataByProvinceCode(Long provinceCode);
}

import com.baomidou.mybatisplus.extension.service.IService;
import com.liu.health.model.dictionary.AreaModel;
import java.util.List;

/**
 * @Author: battery
 * @Date: 2021/03/26
 * @Description:
 */

public interface AreaService extends IService<AreaModel> {

    /**
     * 根据城市编号查询区县信息
     * @param cityCode 城市编号
     * @return
     */
    List<AreaModel> selectAreaDataByCityCode(Long cityCode);
}

import com.baomidou.mybatisplus.extension.service.IService;
import com.liu.health.model.dictionary.SubDistrictModel;
import java.util.List;

/**
 * @Author: battery
 * @Date: 2021/03/26
 * @Description:
 */
public interface SubDistrictService extends IService<SubDistrictModel> {

    /**
     * 根据区县编号查询乡镇街道信息
     * @param areaCode 区县编号
     * @return
     */
    List<SubDistrictModel> selectSubDistrictDataByAreaCode(Long areaCode);
}

4、ServiceImpl (redis核心)

ProvinceServiceImpl
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liu.health.dao.dictionary.ProvinceMapper;
import com.liu.health.model.dictionary.ProvinceModel;
import com.liu.health.service.dictionary.ProvinceService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
 * @Author: battery
 * @Date:  2021/03/26
 * @Description:
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class ProvinceServiceImpl extends ServiceImpl<ProvinceMapper, ProvinceModel> implements ProvinceService {

    final ProvinceMapper provinceMapper;

    final RedisTemplate redisTemplate;

    ProvinceServiceImpl(ProvinceMapper provinceMapper, RedisTemplate redisTemplate) {
        this.provinceMapper = provinceMapper;
        this.redisTemplate = redisTemplate;
    }


    @Override
    public List<ProvinceModel> selectAllData(QueryWrapper<ProvinceModel> queryWrapper) {
        List<ProvinceModel> provinceList = redisTemplate.opsForList().range("provinceList", 0, 30);
        if (provinceList.size() == 0) {
            provinceList = provinceMapper.selectList(queryWrapper);
            redisTemplate.opsForList().rightPushAll("provinceList", provinceList);
        }
        return provinceList;
    }
}
CityServiceImpl
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liu.health.dao.dictionary.CityMapper;
import com.liu.health.model.dictionary.CityModel;
import com.liu.health.service.dictionary.CityService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Author: battery
 * @Date: 2021/03/26
 * @Description:
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class CityServiceImpl extends ServiceImpl<CityMapper, CityModel> implements CityService {

    final RedisTemplate redisTemplate;

    final CityMapper cityMapper;

    CityServiceImpl(RedisTemplate redisTemplate, CityMapper cityMapper) {
        this.redisTemplate = redisTemplate;
        this.cityMapper = cityMapper;
    }

    @Override
    public List<CityModel> selectCityDataByProvinceCode(Long provinceCode) {
        // 获取redis中的数据
        List<CityModel> cityModelList = getRedisCityData(provinceCode);
        if (cityModelList.size() == 0) {
            cityModelList = cityMapper.selectList(new QueryWrapper<CityModel>().in("superior_code", provinceCode));
        }
        // 可以在这里将数据同步上redis
        return cityModelList;
    }

    /**
     * 获取redis的城市数据
     *
     * @param provinceCode 省份代码
     */
    private List<CityModel> getDataBaseCityData(Long provinceCode) {
        List<CityModel> cityModelList = cityMapper.selectList(new QueryWrapper<CityModel>().in("superior_code", provinceCode));
        return cityModelList;
    }

    /**
     * 获取redis的城市数据
     *
     * @param provinceCode 省份代码
     */
    private List<CityModel> getRedisCityData(Long provinceCode) {
        Map<Long, CityModel> cityData = redisTemplate.opsForHash().entries("cityData");
        List<CityModel> cityModelList = new ArrayList<>(cityData.size());
        CityModel cityModel = null;
        for (Map.Entry<Long, CityModel> data : cityData.entrySet()) {
            if (StringUtils.equals(provinceCode.toString(), data.getValue().getSuperiorCode().toString())) {
                cityModel = data.getValue();
                cityModelList.add(new CityModel().setCityCode(cityModel.getCityCode()).setCityName(cityModel.getCityName())
                        .setSuperiorCode(cityModel.getSuperiorCode()));
            }
        }
        return cityModelList;
    }

}
AreaServiceImpl
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liu.health.dao.dictionary.AreaMapper;
import com.liu.health.model.dictionary.AreaModel;
import com.liu.health.service.dictionary.AreaService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Author: battery
 * @Date: 2021/03/26
 * @Description:
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class AreaServiceImpl extends ServiceImpl<AreaMapper, AreaModel> implements AreaService {

    final RedisTemplate redisTemplate;

    final AreaMapper areaMapper;

    AreaServiceImpl(RedisTemplate redisTemplate, AreaMapper areaMapper) {
        this.areaMapper = areaMapper;
        this.redisTemplate = redisTemplate;
    }

    @Override
    public List<AreaModel> selectAreaDataByCityCode(Long cityCode) {
        // 先获取redis中的区县 数据
        List<AreaModel> redisAreaData = getRedisAreaData(cityCode);
        if (redisAreaData.size() == 0) {
            redisAreaData= getDataBaseAreaData(cityCode);
        }
        return redisAreaData;
    }

    /**
     * 获取redis的区县数据
     *
     * @param cityCode 城市代码
     */
    private List<AreaModel> getDataBaseAreaData(Long cityCode) {
        List<AreaModel> areaModelList = areaMapper.selectList(new QueryWrapper<AreaModel>().in("superior_code", cityCode));
        return areaModelList;
    }

    /**
     * 获取redis的区县数据
     *
     * @param cityCode 城市代码
     */
    private List<AreaModel> getRedisAreaData(Long cityCode) {
        Map<Long, AreaModel> areaData = redisTemplate.opsForHash().entries("areaData");
        List<AreaModel> areaModelList = new ArrayList<>(areaData.size());
        AreaModel areaModel = null;
        for (Map.Entry<Long, AreaModel> data : areaData.entrySet()) {
            if (StringUtils.equals(cityCode.toString(), data.getValue().getSuperiorCode().toString())) {
                areaModel = data.getValue();
                areaModelList.add(new AreaModel().setAreaCode(areaModel.getAreaCode()).setAreaName(areaModel.getAreaName())
                        .setSuperiorCode(areaModel.getSuperiorCode()));
            }
        }
        return areaModelList;
    }
}
SubDistrictServiceImpl
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liu.health.dao.dictionary.AreaMapper;
import com.liu.health.dao.dictionary.SubDistrictMapper;
import com.liu.health.model.dictionary.AreaModel;
import com.liu.health.model.dictionary.SubDistrictModel;
import com.liu.health.service.dictionary.SubDistrictService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Author: battery
 * @Date: 2021/03/26
 * @Description:
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class SubDistrictServiceImpl extends ServiceImpl<SubDistrictMapper, SubDistrictModel> implements SubDistrictService {

    final RedisTemplate redisTemplate;
    final SubDistrictMapper subDistrictMapper;

    SubDistrictServiceImpl(RedisTemplate redisTemplate, SubDistrictMapper subDistrictMapper) {
        this.subDistrictMapper = subDistrictMapper;
        this.redisTemplate = redisTemplate;
    }

    @Override
    public List<SubDistrictModel> selectSubDistrictDataByAreaCode(Long areaCode) {
        // 先获取redis中的区县 数据
        List<SubDistrictModel> subDistrictModelList = getRedisSubDistrictData(areaCode);
        if (subDistrictModelList.size() == 0) {
            subDistrictModelList= getDataBaseSubDistrictData(areaCode);
        }
        return subDistrictModelList;
    }


    /**
     * 获取redis的乡镇、街道数据
     *
     * @param areaCode 区、县代码
     */
    private List<SubDistrictModel> getDataBaseSubDistrictData(Long areaCode) {
        List<SubDistrictModel> subDistrictModelList = subDistrictMapper.selectList(new QueryWrapper<SubDistrictModel>().in("superior_code", areaCode));
        return subDistrictModelList;
    }

    /**
     * 获取redis的乡镇、街道数据
     *
     * @param areaCode 区县代码
     */
    private List<SubDistrictModel> getRedisSubDistrictData(Long areaCode) {
        Map<Long, SubDistrictModel> subDistrictData = redisTemplate.opsForHash().entries("subDistrictData");
        List<SubDistrictModel> subDistrictModelList = new ArrayList<>(subDistrictData.size());
        SubDistrictModel subDistrictModel = null;
        for (Map.Entry<Long, SubDistrictModel> data : subDistrictData.entrySet()) {
            if (StringUtils.equals(areaCode.toString(), data.getValue().getSuperiorCode().toString())) {
                subDistrictModel = data.getValue();
                subDistrictModelList.add(new SubDistrictModel().setSubDistrictCode(subDistrictModel.getSubDistrictCode())
                        .setSubDistrictName(subDistrictModel.getSubDistrictName())
                        .setSuperiorCode(subDistrictModel.getSuperiorCode()));
            }
        }
        return subDistrictModelList;
    }

}

5、Controller

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.liu.health.common.response.ServerResponse;
import com.liu.health.model.dictionary.AreaModel;
import com.liu.health.model.dictionary.CityModel;
import com.liu.health.model.dictionary.ProvinceModel;
import com.liu.health.model.dictionary.SubDistrictModel;
import com.liu.health.service.dictionary.AreaService;
import com.liu.health.service.dictionary.CityService;
import com.liu.health.service.dictionary.ProvinceService;
import com.liu.health.service.dictionary.SubDistrictService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: battery
 * @Date:  2021/03/26
 * @Description:
 */

@RestController
@RequestMapping("/address/")
@Api(tags = "地址模块")
public class AddressController {

    final ProvinceService provinceService;

    final CityService cityService;

    final AreaService areaService;

    final SubDistrictService subDistrictService;

    final RedisTemplate redisTemplate;

    public AddressController(ProvinceService provinceService, CityService cityService,
                             AreaService areaService, SubDistrictService subDistrictService,
                             RedisTemplate redisTemplate) {
        this.provinceService = provinceService;
        this.cityService = cityService;
        this.areaService = areaService;
        this.subDistrictService = subDistrictService;
        this.redisTemplate = redisTemplate;
    }

    @GetMapping(value = "selectProvince")
    @ApiOperation(value = "获取所有省份")
    public ServerResponse getProvinceData() {
        QueryWrapper<ProvinceModel> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByAsc("province_code");
        return ServerResponse.createBySuccess(provinceService.selectAllData(queryWrapper));
    }

    @GetMapping(value = "selectCity")
    @ApiOperation(value = "根据省份获取城市")
    @ApiImplicitParam(value = "省份code", name = "provinceCode", paramType = "Long", required = true)
    public ServerResponse getCityData(Long provinceCode) {
        if (provinceCode <= 0L) {
            ServerResponse.createByErrorMessage("请选择省份");
        }
        return ServerResponse.createBySuccess(cityService.selectCityDataByProvinceCode(provinceCode));
    }

    @GetMapping(value = "selectArea")
    @ApiOperation(value = "根据城市获取区县")
    @ApiImplicitParam(value = "城市code", name = "cityCode", paramType = "Long", required = true)
    public ServerResponse getAreaData(Long cityCode) {
        if (cityCode <= 0L) {
            ServerResponse.createByErrorMessage("请选择城市");
        }
        return ServerResponse.createBySuccess(areaService.selectAreaDataByCityCode(cityCode));
    }


    @GetMapping(value = "selectSubDistrict")
    @ApiOperation(value = "根据区县获取乡镇、街道")
    @ApiImplicitParam(value = "区县code", name = "areaCode", paramType = "Long", required = true)
    public ServerResponse getSubDistrictData(Long areaCode) {
        if (areaCode <= 0L) {
            ServerResponse.createByErrorMessage("请选择区/县");
        }
        return ServerResponse.createBySuccess(subDistrictService.selectSubDistrictDataByAreaCode(areaCode));
    }

    @GetMapping(value = "initAddress")
    @ApiOperation(value = "初始化地址信息")
    public ServerResponse initAddressData() {
        // 所有的城市
        List<CityModel> newData = cityService.list(new QueryWrapper<CityModel>().orderByAsc("city_code"));
        Map<Long, CityModel> cityMap = new HashMap<>();
        for (CityModel cityModel : newData) { cityMap.put(cityModel.getCityCode(), cityModel); }
        redisTemplate.opsForHash().putAll("cityData", cityMap);

        // 所有的区县
        List<AreaModel> areaData = areaService.list(new QueryWrapper<AreaModel>().orderByAsc("area_code"));
        Map<Long, AreaModel> areaMap = new HashMap<>();
        for (AreaModel areaModel : areaData) { areaMap.put(areaModel.getAreaCode(), areaModel); }
        redisTemplate.opsForHash().putAll("areaData", areaMap);

        // 所有的乡镇、街道
        List<SubDistrictModel> subDistrictData = subDistrictService.list(new QueryWrapper<SubDistrictModel>().orderByAsc("sub_district_code"));
        Map<Long, SubDistrictModel> subDistrictMap = new HashMap<>();
        for (SubDistrictModel subDistrictModel : subDistrictData) { subDistrictMap.put(subDistrictModel.getSubDistrictCode(), subDistrictModel); }
        redisTemplate.opsForHash().putAll("subDistrictData", subDistrictMap);
        return ServerResponse.createBySuccess();
    }
}

演示结果:
在这里插入图片描述

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐