省市二级联动数据库生成代码(JAVA)

最近在给一客户做网站,用的是php,现在需要有一个下拉框选择省市,并且需要保存省市的简拼,如“河北 HB”。我在网上找了半天,发现基本没有符合要求的代码,于是自己顶着浪费巨大时间的风险,动手写了一个自动生成省市二级联动insert语句的代码。由于时间仓促,自己的水平也有限,所以写的代码基本谈不上是合理的,可维护,可扩展的。我在此仅提供一个具体的思路,想把它写的漂亮点,还请广大朋友们跟据自己的需要进行重构。^o^ 还有,最后结果直接输出到了控制台,请大家直接复制到一个文本文件中,并把扩展名改为.sql。在源代码里,我用到了LinkedHashMap这个集合类,目的是为了保持集合元素的顺序。

所用工具:Eclipse,汉字转拼音工具包:pinyin4j 2.5 可点击下载,也可在我的源代码包里找到

所用语言:java

相关文件:CSDN博客不能上传附件,所以我传到百度网盘了,请大家费些心下载,不能下载的请留言告知。

数据来源于谷歌地图

省市列表(无省、市、区字样)

省市列表(带省、市、区)

源代码

注意:由于我不想把省、市、区这样的字也转换成拼音,如河北省转换为HBS,北京市转换为BJS,我把省、市、区相关字样已删除,但我也保留了原文件,有需要的可以下载。

表结构:

CREATE TABLE IF NOT EXISTS `city` (
  `id` varchar(50) NOT NULL,
  `type` varchar(50) NOT NULL,
  `parent_id` varchar(50) NOT NULL,
  `name` varchar(50) NOT NULL,
  `short` varchar(50) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

具体实现请看以下代码:

package com.zxq.pinyin;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;

public class Covert {
	
	/**
	 * 汉字转拼音,并将结果保存到省或市的map中
	 * @param words 需要转换的字符串
	 * @param provinceOrCity 省或市的Map
	 */
	public static void wordToPinYinSZM(String words, Map<String, String> provinceOrCity) {
		//调用Pinyin4J的方法
		
		//定义拼音输出格式
		HanyuPinyinOutputFormat hof = new HanyuPinyinOutputFormat();
		//大写
		hof.setCaseType(HanyuPinyinCaseType.UPPERCASE);
		//不包含声调
		hof.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
		//u用V表示
		hof.setVCharType(HanyuPinyinVCharType.WITH_V);
		
		//由于只能对单字转换,所以需要把字符串转换为字符数组
		char[] characters = words.toCharArray();
		try {
			//StringBuilder存放结果
			StringBuilder sb = new StringBuilder();
			for(int i = 0; i < characters.length; i++) {
				//调用汉字转拼音核心方法,大家可以看到返回的是一个数组,因为有的汉字有多音字,所以可能返回多个
				//拼音结果,对此,我只取第一个,pinyinArray[0],这样做不好的地方就是可能有的简拼不准确,例如
				//“重庆”我得到的是ZQ,zhong qing,这一点有待完善
				String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(characters[i], hof);
				//substring(0, 1)则表示只取首字母
				sb.append(pinyinArray[0].substring(0, 1));
			}
			//放入省或市的Map中
			provinceOrCity.put(words, sb.toString());
		} catch (BadHanyuPinyinOutputFormatCombination e) {
			e.printStackTrace();
		}
	}
	

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		//读取事先定义好的省市文本文件,第一行为省/直辖市,第二行为各地级市
		File provinceFile = new File("F:\\province_city\\province.txt");
		
		//定义保存省、市数据的数据结构。从里向外看,Map<String, String>保存的是 “省=>简拼” 这样的数据
		//如“河北=>HB”。List里面的Map<String, String>则保存着“市=>简拼”的数据,如“保定=>BD”,而list集合
		//保存该省下所有市的集合。最外层的Map就是“省=>各市集合”的关联集合,这样省市关系就确定了。
		Map<Map<String, String>, List<Map<String, String>>> provinceCity = new LinkedHashMap<Map<String, String>, List<Map<String, String>>>();
		try {
			//定义输入流,可以使用readline()读取一行
			BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(provinceFile), "UTF-8"));
			String provinceName = "";
			while ((provinceName = br.readLine()) != null) { //先读第一行,省的名字
				//定义保存“省=>简拼”的Map
				Map<String, String> province = new LinkedHashMap<String, String>(); 
				//定义保存“市=>简拼”Map的List集合,结构为[{保定=>BD}, {沧州=>CZ},……]
				List<Map<String, String>> citiesArray = new ArrayList<Map<String, String>>();
				
				//调用汉字转拼音方法
				wordToPinYinSZM(provinceName.trim(), province);
				//读取第二行,该省下的所有市区
				String cityNames = br.readLine();
				//文件中的每个市区用两个空格格开,所以以两个空格分隔成市区的数组
				String[] cities = cityNames.split("  ");
				for(int j = 0; j < cities.length; j++) {
					//定义保存“市=>简拼”Map
					Map<String, String> city = new LinkedHashMap<String, String>();
					String cityName = cities[j].trim();
					//调用汉字转拼音方法
					wordToPinYinSZM(cityName, city);
					//添加到list集合中
					citiesArray.add(city);
				}
				//添加到“省=>市的集合”的Map中
				provinceCity.put(province, citiesArray);
			}
			//调用转换为sql语句的代码
			convertMapToSql(provinceCity);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
	
	/**
	 * 把“省=>市的集合”Map转换为SQL语句
	 * @param provinceCity
	 */
	public static void convertMapToSql(Map<Map<String, String>, List<Map<String, String>>> provinceCity) {
		//获取最外层Map的EntrySet 结构为[{河北=>HB, [{保定=>BD}, {石家庄=>sjz},{……}]},{……}]
		Set<Entry<Map<String, String>, List<Map<String, String>>>> provinceEnties = provinceCity.entrySet();
		//获取迭代器
		Iterator<Entry<Map<String, String>, List<Map<String, String>>>> itPE = provinceEnties.iterator();
		//定义数据库中,省的ID从1000000开始
		long provinceId = 1000000;
		while(itPE.hasNext()) {
			//获取一个Entry键-值对
			Entry<Map<String, String>, List<Map<String, String>>> proviceEntry = itPE.next();
			//Key为省,Value为市的List集合
			Map<String, String> provinces = proviceEntry.getKey();
			
			//获取省份的Entry,结构为[{河北=>HB}, {北京=>BJ}] key为中文,value为简拼
			Set<Entry<String, String>> proEntries = provinces.entrySet();
			Iterator<Entry<String, String>> proIt = proEntries.iterator();
			while(proIt.hasNext()) {
				Entry<String, String> proEntry = proIt.next();
				String provinceName = proEntry.getKey();
				String provincePinYin = proEntry.getValue();
				
				//组合sql语句
				StringBuilder sb = new StringBuilder();
				//定义的表结构为:id, type, name, short,分别为id,类型(1为1级,如省,2为2级,如市),父ID即市的所属省份, 名字, 简拼
				sb.append("insert into city values ('");
				sb.append(provinceId).append("','").append("1','','").append(provinceName).append("', '").append(provincePinYin).append("');");
				//我没有生成sql文件,而是直接显示在console里面,大家可以直接从里面复制
				System.out.println(sb.toString());
			}
			
			
			//获取当前省下所有市区,迭代方法与上面类似,请注意这里面的循环比较多,请大家注意分辨。
			List<Map<String, String>> cities = proviceEntry.getValue();
			
			Iterator<Map<String, String>> citiesIt = cities.iterator();
			long cityId = provinceId;//市的ID直接从省的ID开始递增,每次递增50
			while (citiesIt.hasNext()) {
				Map<String, String> city = citiesIt.next();
				Set<Entry<String, String>> cityEntries = city.entrySet();
				Iterator<Entry<String, String>> cityIt = cityEntries.iterator();
				cityId += 50;//市的ID,先递增50,避免与省份ID相同
				while(cityIt.hasNext()) {
					Entry<String, String> cityEntry = cityIt.next();
					String cityName = cityEntry.getKey();
					String cityPinYin = cityEntry.getValue();
					
					StringBuilder sb = new StringBuilder();
					sb.append("insert into city values ('");
					sb.append(cityId).append("','").append("2','").append(provinceId).append("','").append(cityName).append("', '").append(cityPinYin).append("');");
					System.out.println(sb.toString());
				}
			}
			//省份ID以10000递增
			provinceId += 10000;
		}
		
	}

}
生成的sql语句为:

insert into city values ('1000000','1','','北京', 'BJ');
insert into city values ('1000050','2','1000000','东城', 'DC');
insert into city values ('1000100','2','1000000','西城', 'XC');
insert into city values ('1000150','2','1000000','朝阳', 'CY');
insert into city values ('1000200','2','1000000','丰台', 'FT');
insert into city values ('1000250','2','1000000','石景山', 'SJS');
insert into city values ('1000300','2','1000000','海淀', 'HD');
insert into city values ('1000350','2','1000000','门头沟', 'MTG');
insert into city values ('1000400','2','1000000','房山', 'FS');
insert into city values ('1000450','2','1000000','通州', 'TZ');
insert into city values ('1000500','2','1000000','顺义', 'SY');
insert into city values ('1000550','2','1000000','昌平', 'CP');
insert into city values ('1000600','2','1000000','大兴', 'DX');
insert into city values ('1000650','2','1000000','怀柔', 'HR');
insert into city values ('1000700','2','1000000','平谷', 'PG');
insert into city values ('1000750','2','1000000','密云县', 'MYX');
insert into city values ('1000800','2','1000000','延庆县', 'YQX');
insert into city values ('1010000','1','','天津', 'TJ');
insert into city values ('1010050','2','1010000','和平', 'HP');
insert into city values ('1010100','2','1010000','河东', 'HD');
insert into city values ('1010150','2','1010000','河西', 'HX');
insert into city values ('1010200','2','1010000','南开', 'NK');
insert into city values ('1010250','2','1010000','河北', 'HB');
insert into city values ('1010300','2','1010000','红桥', 'HQ');
insert into city values ('1010350','2','1010000','东丽', 'DL');
insert into city values ('1010400
  • 11
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论
以下是一个简单的 Java 省市二级联动的示例代码: ``` import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import java.util.Scanner; public class ProvinceCitySelector { private static final Map<String, Map<String, String>> map = new LinkedHashMap<>(); public static void main(String[] args) { initMap(); Scanner scanner = new Scanner(System.in); String province; String city; do { System.out.println("请输入省份:"); province = scanner.next(); } while (!map.containsKey(province)); do { System.out.println("请输入城市:"); city = scanner.next(); } while (!map.get(province).containsKey(city)); System.out.println("您选择的省份和城市是:" + province + "," + city); } private static void initMap() { Map<String, String> beijing = new HashMap<>(); beijing.put("东城区", "010"); beijing.put("西城区", "010"); beijing.put("崇文区", "010"); beijing.put("宣武区", "010"); beijing.put("朝阳区", "010"); beijing.put("丰台区", "010"); beijing.put("石景山区", "010"); beijing.put("海淀区", "010"); beijing.put("门头沟区", "010"); beijing.put("房山区", "010"); beijing.put("通州区", "010"); beijing.put("顺义区", "010"); beijing.put("昌平区", "010"); beijing.put("大兴区", "010"); beijing.put("怀柔区", "010"); beijing.put("平谷区", "010"); beijing.put("密云县", "010"); beijing.put("延庆县", "010"); map.put("北京市", beijing); Map<String, String> shanghai = new HashMap<>(); shanghai.put("黄浦区", "021"); shanghai.put("徐汇区", "021"); shanghai.put("长宁区", "021"); shanghai.put("静安区", "021"); shanghai.put("普陀区", "021"); shanghai.put("闸北区", "021"); shanghai.put("虹口区", "021"); shanghai.put("杨浦区", "021"); shanghai.put("闵行区", "021"); shanghai.put("宝山区", "021"); shanghai.put("嘉定区", "021"); shanghai.put("浦东新区", "021"); shanghai.put("金山区", "021"); shanghai.put("松江区", "021"); shanghai.put("青浦区", "021"); shanghai.put("奉贤区", "021"); shanghai.put("崇明县", "021"); map.put("上海市", shanghai); } } ``` 这个示例程序中,我们通过一个嵌套的 LinkedHashMap 来存储城市信息。键是省份名称,值是一个 LinkedHashMap,它的键是城市名称,值是城市对应的电话区号(仅作为示例,实际上并不准确)。在 `main` 方法中,我们先读入用户输入的省份名称,然后再读入城市名称。如果用户输入的省份或城市不在我们的数据中,就一直提示用户重新输入,直到输入正确为止。最后,我们输出用户选择的省份和城市。 尽管这个示例程序非常简单,但是它的要点是数据的结构和读取。我们可以通过更复杂的数据结构来支持更多的选项,并使用更复杂的算法来搜索和过滤数据。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

峰华前端工程师

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

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

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

打赏作者

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

抵扣说明:

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

余额充值