通过数据库获取省份城市区县的名字

转载请注明出处,谢谢http://blog.csdn.net/harryweasley/article/details/46557807

本篇博客的主要目的,是介绍怎样将数据库文件保存到手机系统文件,并且可以显示各个省市地的名字。

数据库一共有三个表,他们分别是(后面我将上传整个文件和数据库文件)

省表

CREATE TABLE IF NOT EXISTS `fs_province` (
  `ProvinceID` bigint(20) NOT NULL,
  `ProvinceName` varchar(50) DEFAULT NULL,
  `DateCreated` datetime DEFAULT NULL,
  `DateUpdated` datetime DEFAULT NULL,
  PRIMARY KEY (`ProvinceID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

城市表

CREATE TABLE IF NOT EXISTS `fs_city` (
  `CityID` bigint(20) NOT NULL,
  `CityName` varchar(50) DEFAULT NULL,
  `ZipCode` varchar(50) DEFAULT NULL,
  `ProvinceID` bigint(20) DEFAULT NULL,
  `DateCreated` datetime DEFAULT NULL,
  `DateUpdated` datetime DEFAULT NULL,
  PRIMARY KEY (`CityID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

县区表

CREATE TABLE IF NOT EXISTS `fs_district` (
  `DistrictID` bigint(20) NOT NULL,
  `DistrictName` varchar(50) DEFAULT NULL,
  `CityID` bigint(20) DEFAULT NULL,
  `DateCreated` datetime DEFAULT NULL,
  `DateUpdated` datetime DEFAULT NULL,
  PRIMARY KEY (`DistrictID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

注意:

省份表和城市表中,都有北京,上海,重庆,天津这四个城市,所以要自己判断一下。


先看下效果图:


我们将二进制的数据库文件放入工程的res/raw下面,如图所示:



整个程序的主要功能,我都封装在了CityInfoDataSupport2这个类中。

package com.example.province;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Environment;

public class CityInfoDataSupport2 {
	private static CityInfoDataSupport2 cityInfoDataSupport;
	public static final String PACKAGE_NAME = "com.example.province";
	/**
	 * 数据库在手机系统内存里的路径
	 */
	private static String DATABASE_PATH = "/data"
			+ Environment.getDataDirectory() + "/"+PACKAGE_NAME + "/databases/";
	/**
	 * 数据库的名称
	 */
	public static final String dbName = "mzk_db";
	private SQLiteDatabase mSDB;

	public static CityInfoDataSupport2 getInstance(Context context) {
		initDataBase(context);
		if (cityInfoDataSupport == null) {
			cityInfoDataSupport = new CityInfoDataSupport2();
		}
		return cityInfoDataSupport;

	}

	/**
	 * 初试化数据库
	 */
	private static void initDataBase(Context context) {
		boolean dbExist = checkDataBase();
		if (dbExist) {

		} else {
			// 如果不存在,则将raw里的数据存入手机sd卡
			copyDataBase(context);
		}
	}

	/**
	 * 复制数据库到手机指定文件夹下
	 * 
	 * @throws IOException
	 */
	private static void copyDataBase(Context context) {
		String databaseFilenames = DATABASE_PATH + dbName;
		File dir = new File(DATABASE_PATH);
		FileOutputStream os = null;
		InputStream is = null;
		// 判断文件夹是否存在,不存在就创建一个
		if (!dir.exists()) {
			dir.mkdirs();
		}
		try {
			// 得到数据库的输出流
			os = new FileOutputStream(databaseFilenames);
			// 得到数据文件的输入流
			is = context.getResources().openRawResource(R.raw.mzk_db);
			byte[] buffer = new byte[8192];
			int count = 0;
			while ((count = is.read(buffer)) != -1) {
				os.write(buffer, 0, count);
				os.flush();
			}
			// 之所以不在这里初始化,是因为这边是静态的方法,而mSDB并没有设置为静态的,也不推荐设为静态的
			// mSDB = SQLiteDatabase.openOrCreateDatabase(DATABASE_PATH +
			// dbName, null);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				os.close();
				is.close();
			} catch (IOException e) {
				e.printStackTrace();
			}

		}

	}

	/**
	 * 判断数据库是否存在
	 * 
	 * @return
	 */
	private static boolean checkDataBase() {
		SQLiteDatabase checkDB = null;
		String databaseFilename = DATABASE_PATH + dbName;
		// 要自己加上try catch方法
		try {
			// 返回最新的数据库
			checkDB = SQLiteDatabase.openDatabase(databaseFilename, null,
					SQLiteDatabase.OPEN_READONLY);
		} catch (SQLiteException e) {
			// TODO: handle exception
		}

		if (checkDB != null) {
			checkDB.close();
		}
		// 如果checkDB为null,则没有数据库,返回false
		return checkDB == null ? false : true;
	}

	/**
	 * 查询所有省份的信息
	 * 
	 * @return 省份信息
	 */
	public ArrayList<City> queryProvince() {
		// 创建数据库
		mSDB = SQLiteDatabase
				.openOrCreateDatabase(DATABASE_PATH + dbName, null);
		ArrayList<City> list = new ArrayList<City>();
		String sql = "select * from fs_province";
		Cursor cursor = mSDB.rawQuery(sql, null);
		while (cursor.moveToNext()) {
			City city = new City();
			String id = cursor.getString(cursor.getColumnIndex("ProvinceID"));
			String name = cursor.getString(cursor
					.getColumnIndex("ProvinceName"));
			city.setName(name);
			city.setId(id);
			list.add(city);
		}
		if (cursor != null) {
			cursor.close();
		}
		return list;
	}

	/**
	 * 通过省份来查找城市
	 * 
	 * @param provinceId
	 *            省份的id
	 * @return 该省的所有城市
	 */
	public ArrayList<City> queryCityByProvince(String provinceId) {

		// 创建数据库
		mSDB = SQLiteDatabase
				.openOrCreateDatabase(DATABASE_PATH + dbName, null);
		ArrayList<City> list = new ArrayList<City>();
		String sql = "select * from fs_city where ProvinceID=" + provinceId;
		Cursor cursor = mSDB.rawQuery(sql, null);
		while (cursor.moveToNext()) {
			City city = new City();
			String id = cursor.getString(cursor.getColumnIndex("CityID"));
			String name = cursor.getString(cursor.getColumnIndex("CityName"));
			city.setName(name);
			city.setId(id);
			list.add(city);
		}
		if (cursor != null) {
			cursor.close();
		}
		return list;

	}

	/**
	 * 通过城市来查找县区
	 * 
	 * @param provinceId
	 *            省份的id
	 * @return 该省的所有城市
	 */
	public ArrayList<City> queryDistrictByCity(String cityId) {

		// 创建数据库
		mSDB = SQLiteDatabase
				.openOrCreateDatabase(DATABASE_PATH + dbName, null);
		ArrayList<City> list = new ArrayList<City>();
		String sql = "select * from fs_district where CityID=" + cityId;
		Cursor cursor = mSDB.rawQuery(sql, null);
		while (cursor.moveToNext()) {
			City city = new City();
			String id = cursor.getString(cursor.getColumnIndex("DistrictID"));
			String name = cursor.getString(cursor
					.getColumnIndex("DistrictName"));
			city.setName(name);
			city.setId(id);
			list.add(city);
		}
		if (cursor != null) {
			cursor.close();
		}
		return list;

	}

	public void closeDataBase() {
		if (mSDB != null) {
			mSDB.close();
		}
	}
}

这个类中,将程序中的数据库二进制文件复制到了手机系统内存中。代码中都有很详细的注释,我在这里就不多说了。


接下来就是各个Activity的内容了,都很简单,我就贴一个吧,之后我将上传整个程序。

package com.example.province;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;

/**
 * 省份的名字,其中北京,上海,天津,重庆,香港,澳门这六个是特殊的例子
 * @author lgx
 *
 */
public class MainActivity extends Activity {

	ArrayList<City> province;
	ListView province_list;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		province_list = (ListView) findViewById(R.id.province_list);
		province = CityInfoDataSupport2.getInstance(this).queryProvince();
		TestAdapter adapter = new TestAdapter(this, province);
		province_list.setAdapter(adapter);
		province_list.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				String ProviceId = province.get(position).getId();
				String proviceName = province.get(position).getName();
				if (proviceName.equals("北京") || proviceName.equals("天津")
						|| proviceName.equals("上海") || proviceName.equals("重庆")) {
					Intent intent = new Intent(MainActivity.this,
							DistrictActivity.class);
					intent.putExtra("pcode", ProviceId);
					startActivity(intent);
				} else {
					Intent intent = new Intent(MainActivity.this,
							CityActivity.class);
					intent.putExtra("pcode", ProviceId);
					startActivity(intent);
				}

			}
		});
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		// CityInfoDataSupport.getInstance(this).close();
	}

}


项目下载地址:http://download.csdn.net/detail/harryweasley/8807143


以下是一个基于Spring Boot框架的Java代码示例,用于根据国家、省份城市区县实现联动: 1. 在前端页面,可以使用以下HTML代码创建4个下拉框: ```html <select name="hrmcountry" id="hrmcountry"> <option value="">请选择国家</option> </select> <select name="hrmprovince" id="hrmprovince"> <option value="">请选择省份</option> </select> <select name="hrmcity" id="hrmcity"> <option value="">请选择城市</option> </select> <select name="hrmcitytwo" id="hrmcitytwo"> <option value="">请选择区县</option> </select> ``` 2. 在后端,我们可以使用Spring Boot框架提供的JPA来管理数据库,并创建4个实体类,分别对应国家、省份城市区县的信息: ```java @Entity public class HrmCountry { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; // getter和setter方法 } @Entity public class HrmProvince { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; @ManyToOne @JoinColumn(name = "country_id") private HrmCountry country; // getter和setter方法 } @Entity public class HrmCity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; @ManyToOne @JoinColumn(name = "province_id") private HrmProvince province; // getter和setter方法 } @Entity public class HrmCityTwo { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; @ManyToOne @JoinColumn(name = "city_id") private HrmCity city; // getter和setter方法 } ``` 3. 在后端,我们可以创建一个控制器类,用于接收前端页面发来的请求,并返回相应的数据: ```java @RestController public class HrmController { @Autowired private HrmCountryRepository countryRepository; @Autowired private HrmProvinceRepository provinceRepository; @Autowired private HrmCityRepository cityRepository; @Autowired private HrmCityTwoRepository cityTwoRepository; @GetMapping("/countries") public List<HrmCountry> getCountries() { return countryRepository.findAll(); } @GetMapping("/provinces") public List<HrmProvince> getProvinces(@RequestParam Long countryId) { return provinceRepository.findByCountryId(countryId); } @GetMapping("/cities") public List<HrmCity> getCities(@RequestParam Long provinceId) { return cityRepository.findByProvinceId(provinceId); } @GetMapping("/cityTwos") public List<HrmCityTwo> getCityTwos(@RequestParam Long cityId) { return cityTwoRepository.findByCityId(cityId); } } ``` 4. 在前端页面的JavaScript代码,我们可以监听选择事件,向后端发起请求,获取下一级别的数据,并动态更新下拉框: ```javascript $(document).ready(function () { // 加载国家数据 $.get("/countries", function (data) { var options = "<option value=''>请选择国家</option>"; for (var i = 0; i < data.length; i++) { options += "<option value='" + data[i].id + "'>" + data[i].name + "</option>"; } $("#hrmcountry").html(options); }); // 监听国家下拉框的选择事件 $("#hrmcountry").change(function () { var countryId = $(this).val(); // 加载省份数据 if (countryId) { $.get("/provinces?countryId=" + countryId, function (data) { var options = "<option value=''>请选择省份</option>"; for (var i = 0; i < data.length; i++) { options += "<option value='" + data[i].id + "'>" + data[i].name + "</option>"; } $("#hrmprovince").html(options); }); } else { $("#hrmprovince").html("<option value=''>请选择省份</option>"); $("#hrmcity").html("<option value=''>请选择城市</option>"); $("#hrmcitytwo").html("<option value=''>请选择区县</option>"); } }); // 监听省份下拉框的选择事件 $("#hrmprovince").change(function () { var provinceId = $(this).val(); // 加载城市数据 if (provinceId) { $.get("/cities?provinceId=" + provinceId, function (data) { var options = "<option value=''>请选择城市</option>"; for (var i = 0; i < data.length; i++) { options += "<option value='" + data[i].id + "'>" + data[i].name + "</option>"; } $("#hrmcity").html(options); }); } else { $("#hrmcity").html("<option value=''>请选择城市</option>"); $("#hrmcitytwo").html("<option value=''>请选择区县</option>"); } }); // 监听城市下拉框的选择事件 $("#hrmcity").change(function () { var cityId = $(this).val(); // 加载区县数据 if (cityId) { $.get("/cityTwos?cityId=" + cityId, function (data) { var options = "<option value=''>请选择区县</option>"; for (var i = 0; i < data.length; i++) { options += "<option value='" + data[i].id + "'>" + data[i].name + "</option>"; } $("#hrmcitytwo").html(options); }); } else { $("#hrmcitytwo").html("<option value=''>请选择区县</option>"); } }); }); ``` 通过以上代码,就可以实现Java根据国家、省份城市区县实现联动的功能了。需要注意的是,以上代码仅供参考,具体实现可能因项目需求和实际情况而异。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值