如何将json行政区划导入数据库,中国行政区域数据(省市区县镇乡村五级联动)

目前用的是bladeX框架,

sql 复制代码
CREATE TABLE `blade_region_copy1` (
  `code` varchar(12) NOT NULL COMMENT '区划编号',
  `parent_code` varchar(12) DEFAULT NULL COMMENT '父区划编号',
  `ancestors` varchar(255) DEFAULT NULL COMMENT '祖区划编号',
  `name` varchar(128) DEFAULT NULL COMMENT '区划名称',
  `province_code` varchar(12) DEFAULT NULL COMMENT '省级区划编号',
  `province_name` varchar(128) DEFAULT NULL COMMENT '省级名称',
  `city_code` varchar(12) DEFAULT NULL COMMENT '市级区划编号',
  `city_name` varchar(128) DEFAULT NULL COMMENT '市级名称',
  `district_code` varchar(12) DEFAULT NULL COMMENT '区级区划编号',
  `district_name` varchar(128) DEFAULT NULL COMMENT '区级名称',
  `town_code` varchar(12) DEFAULT NULL COMMENT '镇级区划编号',
  `town_name` varchar(128) DEFAULT NULL COMMENT '镇级名称',
  `village_code` varchar(12) DEFAULT NULL COMMENT '村级区划编号',
  `village_name` varchar(128) DEFAULT NULL COMMENT '村级名称',
  `region_level` int(11) DEFAULT NULL COMMENT '层级',
  `sort` int(11) DEFAULT NULL COMMENT '排序',
  `remark` varchar(255) DEFAULT NULL COMMENT '备注',
  PRIMARY KEY (`code`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='行政区划表';

但是对于街道-社区 没有

目前从github找到了 行政区划json数据

中国行政区域数据(省市区县镇乡村五级联动)

https://github.com/657258535/China-Area-Region-Administrative-Divisions

最终效果如图:

数据库最终情况:

代码如下:

java 复制代码
/**
 * 行政区划
 *
 * @author rsz
 * @since 2025-06-13
 */
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/xingzheng")
public class xingzhengController {

	@Resource
	private ObjectMapper objectMapper;


	@Resource
	private IRegionService regionService;

	/**
	 * 上传TXT文件并解析为行政区划对象
	 * @param file 上传的TXT文件(内容为JSON)
	 * @return 解析后的行政区划对象
	 */
	@PostMapping("/api/division/parse")
	public R parseDivisionFile(@RequestParam("file") MultipartFile file) {
		// 1. 校验文件
		if (file.isEmpty()) {
			return R.fail("上传的文件不能为空");
		}


		try {
			// 2. 读取TXT文件内容(转成UTF-8编码的字符串)
			String jsonContent = IOUtils.toString(file.getInputStream(), StandardCharsets.UTF_8);
			log.info("读取到文件内容,长度:{} 字符", jsonContent.length());

			// 3. 用ObjectMapper解析JSON字符串为Division对象
			Division division = objectMapper.readValue(jsonContent, Division.class);

			// 4. 递归转换树形Division为平铺的Region列表
			List<Region> regionList = new ArrayList<>();
			// 初始化递归参数:当前节点、父节点code、层级、区编码/名称(初始为空)
			// 接口中调用递归方法的地方也要同步修改(新增townCode/townName初始值)
			// 初始化递归参数:祖编码初始为"",由1级节点自行拼接为"00"
			convertDivisionToRegion(division, "00", 1,
				null, null,  // 省级编码/名称
				null, null,  // 市级编码/名称
				null, null,  // 区级编码/名称
				null, null,  // 镇级编码/名称
				"",          // 祖编码初始值
				regionList);


			// 6. 保存所有Region到数据库
			regionService.saveBatch(regionList);

			// 5. 返回平铺的Region列表
			return R.success("成功");

		} catch (IOException e) {
			log.error("文件读取或JSON解析失败", e);
			return R.fail("解析失败:" + e.getMessage());
		}
	}
	/**
	 * 优化版递归方法:传递省/市/区/镇编码/名称+祖编码,实现全层级关联
	 */
	private void convertDivisionToRegion(Division division, String parentCode, Integer level,
										 String provinceCode, String provinceName,
										 String cityCode, String cityName,
										 String districtCode, String districtName,
										 String townCode, String townName,
										 String ancestors, // 新增:祖区划编号拼接字符串
										 List<Region> regionList) {
		// 1. 拼接当前节点的祖区划编号
		String currentAncestors;
		if (level == 1) { // 省级:祖编码固定为00
			currentAncestors = "00";
		} else { // 非省级:在父节点祖编码基础上追加父节点code
			currentAncestors = ancestors + "," + parentCode;
		}

		// 2. 创建当前节点的Region对象
		Region region = new Region();
		region.setCode(division.getCode());
		region.setParentCode(parentCode);
		region.setName(division.getName());
		region.setRegionLevel(level);
		region.setAncestors(currentAncestors); // 填充祖区划编号

		// 按层级填充字段
		if (level == 1) { // 省级
			// 填充省级字段
			region.setProvinceCode(division.getCode());
			region.setProvinceName(division.getName());
			provinceCode = division.getCode(); // 更新省级编码,供子节点使用
			provinceName = division.getName(); // 更新省级名称,供子节点使用
			// 市/区/镇/村字段为空
			region.setCityCode(null);
			region.setCityName(null);
			region.setDistrictCode(null);
			region.setDistrictName(null);
			region.setTownCode(null);
			region.setTownName(null);
			region.setVillageCode(null);
			region.setVillageName(null);
		} else if (level == 2) { // 市级
			// 继承省级字段
			region.setProvinceCode(provinceCode);
			region.setProvinceName(provinceName);
			// 填充市级字段
			region.setCityCode(division.getCode());
			region.setCityName(division.getName());
			cityCode = division.getCode(); // 更新市级编码,供子节点使用
			cityName = division.getName(); // 更新市级名称,供子节点使用
			// 区/镇/村字段为空
			region.setDistrictCode(null);
			region.setDistrictName(null);
			region.setTownCode(null);
			region.setTownName(null);
			region.setVillageCode(null);
			region.setVillageName(null);
		} else if (level == 3) { // 区级
			// 继承省/市级字段
			region.setProvinceCode(provinceCode);
			region.setProvinceName(provinceName);
			region.setCityCode(cityCode);
			region.setCityName(cityName);
			// 填充区级字段
			region.setDistrictCode(division.getCode());
			region.setDistrictName(division.getName());
			districtCode = division.getCode(); // 更新区级编码,供子节点使用
			districtName = division.getName(); // 更新区级名称,供子节点使用
			// 镇/村字段为空
			region.setTownCode(null);
			region.setTownName(null);
			region.setVillageCode(null);
			region.setVillageName(null);
		} else if (level == 4) { // 街道/镇级
			// 继承省/市/区级字段
			region.setProvinceCode(provinceCode);
			region.setProvinceName(provinceName);
			region.setCityCode(cityCode);
			region.setCityName(cityName);
			region.setDistrictCode(districtCode);
			region.setDistrictName(districtName);
			// 填充镇级字段
			region.setTownCode(division.getCode());
			region.setTownName(division.getName());
			townCode = division.getCode(); // 更新镇级编码,供子节点使用
			townName = division.getName(); // 更新镇级名称,供子节点使用
			// 村字段为空
			region.setVillageCode(null);
			region.setVillageName(null);
		} else if (level == 5) { // 社区/村级
			// 继承省/市/区/镇级字段
			region.setProvinceCode(provinceCode);
			region.setProvinceName(provinceName);
			region.setCityCode(cityCode);
			region.setCityName(cityName);
			region.setDistrictCode(districtCode);
			region.setDistrictName(districtName);
			region.setTownCode(townCode);
			region.setTownName(townName);
			// 填充村级字段
			region.setVillageCode(division.getCode());
			region.setVillageName(division.getName());
		}

		// 固定填充的字段
		region.setSort(1);
		region.setRemark(null);

		regionList.add(region);

		// 递归处理子节点(传递所有层级编码/名称)
		if (division.getChildren() != null && !division.getChildren().isEmpty()) {
			for (Division child : division.getChildren()) {
				convertDivisionToRegion(child, division.getCode(), level + 1,
					provinceCode, provinceName,
					cityCode, cityName,
					districtCode, districtName,
					townCode, townName,
					currentAncestors, // 传递当前节点的祖编码给子节点
					regionList);
			}
		}
	}


}
相关推荐
陌上丨15 分钟前
Redis的Key和Value的设计原则有哪些?
数据库·redis·缓存
曹牧16 分钟前
Spring Boot:如何测试Java Controller中的POST请求?
java·开发语言
AI_567825 分钟前
AWS EC2新手入门:6步带你从零启动实例
大数据·数据库·人工智能·机器学习·aws
ccecw43 分钟前
Mysql ONLY_FULL_GROUP_BY模式详解、group by非查询字段报错
数据库·mysql
JH30731 小时前
达梦数据库与MySQL的核心差异解析:从特性到实践
数据库·mysql
数据知道1 小时前
PostgreSQL 核心原理:如何利用多核 CPU 加速大数据量扫描(并行查询)
数据库·postgresql
爬山算法1 小时前
Hibernate(90)如何在故障注入测试中使用Hibernate?
java·后端·hibernate
kfyty7251 小时前
集成 spring-ai 2.x 实践中遇到的一些问题及解决方案
java·人工智能·spring-ai
猫头虎1 小时前
如何排查并解决项目启动时报错Error encountered while processing: java.io.IOException: closed 的问题
java·开发语言·jvm·spring boot·python·开源·maven
李少兄1 小时前
在 IntelliJ IDEA 中修改 Git 远程仓库地址
java·git·intellij-idea