1. 程式人生 > >使用JDBC獲取資料庫資料,並生成json格式檔案(省市區三級聯動)

使用JDBC獲取資料庫資料,並生成json格式檔案(省市區三級聯動)

前言:

轉眼已經2018年了, 17年有點忙,出差將近三個月,部落格也停更了好久。 一直都是不停的修復bug,和做一些業務需要的提示和互動。主要是因為和硬體有關係所以比較麻煩,開發週期也很長,而且還不穩定,硬體先行,然後在是除錯,互動。不過也有好處,學到的東西自然不是簡簡單單的 程式碼了。

然後在轉換這個資料之前我啥真的是一臉懵逼啊,連jsbc都不知道是啥,也不知道怎麼用,總感覺是陌生的東西,然後獲取到資料後也是沒一點頭緒,不知道怎麼劃分資料,分成一層一層,雖然知道是用迴圈,但是怎麼把一個數據集合迴圈出幾層?

廢話不多說,來今天的正題!


任務:

 1.需求:民航局給了你一個sql(省市區)檔案,需要你對應的轉換成你需要的格式方便解析。

 2.原因:網上有諸多類似的 province.json資料 ,但是不行,因為此SQL表中 是定製的 所有的城市的ID 號是定製的,①請求引數需要ID號,②顯示UI 需要 文字

 3.目的:為了 到達效果就是三級聯動,同時根據對應的城市索引到對應的城市ID,並執行下一步操作

4.需要用到的工具 :①Navicat 12 for MySQL (為什麼不用MySql Workbench,當然這個只是為了建個表格,你要是會用,

但是還是用最簡單的視覺化的還是比較方便的  ② Eclipse +  驅動包(mysql-connector-java-5.1.27.jar) ③百度 json 格式轉換.

先上幾個gif圖和格式吧!





第一步就是先將SQL 資料轉換成類似圖二的格式,

第二步:然後在將圖二解析 實現如下的效果,

第三步:gif圖確定後 介面顯示是文字,Toast提示是所對應的 城市ID

先匯入表格,

然後

然後在Eclipse中建立程式,

下面匯入的2個jar包 分別是 用來將String 轉換為 json 資料,和jdbc的驅動包

第一步:先打通和資料庫的連結。

import java.sql.*;

public class GetConnection {
	
	public static void main(String[] args) {
		try {
			// 呼叫Class.forName()方法載入驅動程式
			Class.forName("com.mysql.jdbc.Driver");
			System.out.println("成功載入MySQL驅動!");
		} catch (ClassNotFoundException e1) {
			System.out.println("找不到MySQL驅動!");
			e1.printStackTrace();
		}
		
		//String url = "jdbc:mysql://localhost:3306/beibei"; // JDBC的URL
		String url = "jdbc:mysql://localhost:3306/splname"; // 這裡splname 是你的表的名字,例如我上邊的是beibei
		// 呼叫DriverManager物件的getConnection()方法,獲得一個Connection物件
		Connection conn;
		try {
			//conn = DriverManager.getConnection(url, "root", "123456");
			conn = DriverManager.getConnection(url, "root", "password");//這裡password 是密碼 建立服務時候的密碼
			// 建立一個Statement物件
			Statement stmt = conn.createStatement(); // 建立Statement物件
			System.out.print("成功連線到資料庫!");
			stmt.close();
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}
第二步:如果執行結果是成功連線資料庫,我們就可以進行下一步,讀取資料了。

	public static void main(String[] args) {
		try {
			// 呼叫Class.forName()方法載入驅動程式
			Class.forName("com.mysql.jdbc.Driver");
			System.out.println("成功載入MySQL驅動!");

			String url = "jdbc:mysql://localhost:3306/beibei"; // JDBC的URL
			Connection conn;

			conn = DriverManager.getConnection(url, "root", "211314");
			Statement stmt = conn.createStatement(); // 建立Statement物件
			System.out.println("成功連線到資料庫!");

			String sql = "select * from theaty_area"; // 要執行的SQL
			ResultSet rs = stmt.executeQuery(sql);// 建立資料物件
			
			 System.out.println("索引ID" + "\t\t" + "地區名稱" + "\t\t" + "地區父ID"
			 + "\t\t" + "排序" + "\t\t" + "地區深度");
			
			 while (rs.next()) {
			 System.out.print(rs.getInt(1) + "\t\t");
			 System.out.print(rs.getString(2) + "\t\t");
			 System.out.print(rs.getInt(3) + "\t\t");
			 System.out.print(rs.getInt(4) + "\t\t");
			 System.out.print(rs.getInt(5) + "\t\t");
			 System.out.print(rs.getString(6) + "\t\t");
			 System.out.println();
			 }
                 saveListData(rs);//分類存資料
                       rs.close();
			stmt.close();
			conn.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
執行列印成功便是成功了一半,成功讀取出資料了。下面就是要分類了

第三步:之前我在讀取資料後,我把所有的資料存到同一個集合中,然後根本沒有思路在進行下去了,我發現我無論怎麼迴圈都很麻煩,後來問了一個朋友,他經驗比我豐富,一句話就讓我明白了。也是同樣的:第一步讀取資料 第二步:分類,需要幾層分成幾層,然後每一層迴圈遍歷 。第三步:在統一存到同一個集合中並遍歷生成json格式在輸出。

我是豁然開朗,對啊,沒說非要存到一個集合中 ,可以先分在合。怎麼方便,怎麼邏輯清楚怎麼來啊。

於是乎:

/**
	 * 儲存資料
	 * 
	 * @param rs
	 */
	public static void saveListData(ResultSet rs) {
		try {
			ArrayList<TheatyBean> beanlist01 = new ArrayList();
			ArrayList<TheatyBean> beanlist02 = new ArrayList();
			ArrayList<TheatyBean> beanlist03 = new ArrayList();

			while (rs.next()) {
				int area_deep = rs.getInt(5);//此處是spl資料中的地區深度(1,2,3-->省市區)
				if (area_deep == 1) {
					TheatyBean theatyBean = new TheatyBean();
					theatyBean.name_id = rs.getInt(1);
					theatyBean.name = rs.getString(2);
					theatyBean.parent_area_id = rs.getInt(3);
					beanlist01.add(theatyBean);
				} else if (area_deep == 2) {
					TheatyBean theatyBean = new TheatyBean();
					theatyBean.name_id = rs.getInt(1);
					theatyBean.name = rs.getString(2);
					theatyBean.parent_area_id = rs.getInt(3);
					beanlist02.add(theatyBean);
				} else if (area_deep == 3) {
					TheatyBean theatyBean = new TheatyBean();
					theatyBean.name_id = rs.getInt(1);
					theatyBean.name = rs.getString(2);
					theatyBean.parent_area_id = rs.getInt(3);
					beanlist03.add(theatyBean);
				}

			}
			RankBeanList(beanlist01, beanlist02, beanlist03);
			// Arrayprintln(beanlist01);
			// Arrayprintln(beanlist02);
			// Arrayprintln(beanlist03);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
TheatyBean.java

public class TheatyBean {

	public int name_id;// 城市id

	public String name;//城市名字

	public int parent_area_id;// 父ID

}
第四步:就是邏輯的分類了。相信都能看懂。

/**
	 * 通過三個級別資料,迴圈遍歷
	 * 
	 * @param beanlist01
	 * @param beanlist02
	 * @param beanlist03
	 */
	private static void RankBeanList(ArrayList<TheatyBean> beanlist01,
			ArrayList<TheatyBean> beanlist02, ArrayList<TheatyBean> beanlist03) {

		LinkedList<LinkedHashMap<String, Object>> jsonList = new LinkedList<LinkedHashMap<String, Object>>();// 省集合
		for (int i = 0; i < beanlist01.size(); i++) {
			LinkedHashMap<String, Object> prMap = new LinkedHashMap<String, Object>();
			prMap.put("name", beanlist01.get(i).name);
			prMap.put("name_id", String.valueOf(beanlist01.get(i).name_id));
			List<LinkedHashMap<String, Object>> citylist = new ArrayList<LinkedHashMap<String, Object>>();// 市集合
			for (int j = 0; j < beanlist02.size(); j++) {

				if (beanlist01.get(i).name_id == beanlist02.get(j).parent_area_id) {
					LinkedHashMap<String, Object> cityMap = new LinkedHashMap<String, Object>();
					
					cityMap.put("name", String.valueOf(beanlist02.get(j).name));
					cityMap.put("name_id", String.valueOf(beanlist02.get(j).name_id));
					ArrayList<String> list_area = new ArrayList<String>();// 區名字集合
					ArrayList<String> list_area_id = new ArrayList<String>();// 區編號集合

					for (int k = 0; k < beanlist03.size(); k++) {
						if (beanlist02.get(j).name_id == beanlist03.get(k).parent_area_id) {
							String area = beanlist03.get(k).name;
							String area_id = String.valueOf(beanlist03.get(k).name_id);
							list_area.add(area);
							list_area_id.add(area_id);
						}
					}
					cityMap.put("area", list_area);
					cityMap.put("area_id", list_area_id);

					citylist.add(cityMap);
							
				}
			}
			prMap.put("city", citylist);// 省下面的市集合

			jsonList.add(prMap);
			
		}
		mapPrintln(jsonList);// 輸出

	}
這裡使用LinkedHashMap 用來排序,畢竟本身給的sql資料庫是亂的。根據父ID迴圈找到歸屬的城市。並裝入map中。

第五步:就是生成json 並輸出

	/**
	 * <P>
	 * 列印map集合和資料
	 * </p>
	 * 
	 * @param list
	 */
	private static void mapPrintln(List<LinkedHashMap<String, Object>> list) {
		// TODO Auto-generated method stub
		if (list == null && list.size() == 0) {
			return;
		}
		System.out.println(list.size()
				+ "-----------------------------------------------------");
		// System.out.println(list.toString());
		Gson gson = new Gson();
		String jsonString = gson.toJson(list);
		inputFile(jsonString);// json檔案
		System.out.println(jsonString);// 列印
	}
開啟執行緒並指定輸出路徑:

/**
	 * 開啟執行緒
	 * 
	 * @param jsonString
	 */
	private static void inputFile(final String jsonString) {
		// TODO Auto-generated method stub
		new Thread(new Runnable() {

			public void run() {
				// TODO Auto-generated method stub
				WriteConfigJson(jsonString);
			}
		}).start();
	}

	/**
	 * 輸出json檔案
	 * 
	 * @param args
	 */
	public static void WriteConfigJson(String args) {
		String src = "D:\\province.json";// 自定義檔案路徑

		File file = new File(src);

		if (!file.getParentFile().exists()) {
			file.getParentFile().mkdirs();
		}
		try {
			file.delete();
			file.createNewFile();
		} catch (IOException e) {
			e.printStackTrace();
		}

		try {
			FileWriter fw = new FileWriter(file, true);
			fw.write(args);
			fw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

最後拿到json資料後,他可能是這樣的


百度json格式 就OK 了。 並匯入自己的assets 資原始檔夾中 使用。

 


 最後一步就是解析過程了:

首先獲取資原始檔:也是要開啟執行緒的,執行緒內執行解析過程。

獲取:

/***
     * <P>解析JSon資料</P>
     */
    private void initJsonData() {

        /**
         * 注意:assets 目錄下的Json檔案僅供參考,實際使用可自行替換檔案
         * 關鍵邏輯在於迴圈體
         *
         * */
        String JsonData = new GetJsonDataUtil().getJson(this, "city/province.json");//獲取assets目錄下的json檔案資料

        ArrayList<JsonBean> jsonBean = parseData(JsonData);//用Gson 轉成實體
}
解析:
 /**
     * <P>使用gson 解析</P>
     *
     * @param result
     * @return
     */
    public ArrayList<JsonBean> parseData(String result) {//Gson 解析
        ArrayList<JsonBean> detail = new ArrayList<>();
        try {
            //含ID 的解析
            Gson gson = new Gson();
            ArrayList<JsonBean> jsonBeen = gson.fromJson(result, new TypeToken<ArrayList<JsonBean>>() {
            }.getType());
            detail = jsonBeen;

        } catch (Exception e) {
            e.printStackTrace();
            handler.sendEmptyMessage(MSG_LOAD_FAILED);
        }
        return detail;
    }
通過Gson 的反射原理解析json中的引數。

最後就是分類成不同的集合:並各取所需。再次我建立了 6個集合 分別是省,市,區 和對應的ID 集合。因為清楚明瞭。

    private ArrayList<JsonBean> options1Items = new ArrayList<>();
    private ArrayList<ArrayList<String>> options2Items = new ArrayList<>();
    private ArrayList<ArrayList<ArrayList<String>>> options3Items = new ArrayList<>();

    private ArrayList<JsonBean> index1Items = new ArrayList<>();
    private ArrayList<ArrayList<String>> index2Items = new ArrayList<>();
    private ArrayList<ArrayList<ArrayList<String>>> index3Items = new ArrayList<>();

/***
     * <P>解析JSon資料</P>
     */
    private void initJsonData() {

        /**
         * 注意:assets 目錄下的Json檔案僅供參考,實際使用可自行替換檔案
         * 關鍵邏輯在於迴圈體
         *
         * */
        String JsonData = new GetJsonDataUtil().getJson(this, "city/province.json");//獲取assets目錄下的json檔案資料

        ArrayList<JsonBean> jsonBean = parseData(JsonData);//用Gson 轉成實體

        /**
         * 新增省份資料
         *
         * 注意:如果是新增的JavaBean實體,則實體類需要實現 IPickerViewData 介面,
         * PickerView會通過getPickerViewText方法獲取字串顯示出來。
         */
        options1Items = jsonBean;
        index1Items = jsonBean;
        for (int i = 0; i < jsonBean.size(); i++) {//遍歷省份
            // 這裡是顯示 在UI 上的引數
            ArrayList<String> CityList = new ArrayList<>();//該省的城市列表(第二級)
            ArrayList<ArrayList<String>> Province_AreaList = new ArrayList<>();//該省的所有地區列表(第三極)
            //下面是 需要呼叫的ID 引數
            ArrayList<String> CityID = new ArrayList<>();//該省的城市列表(第二級)
            ArrayList<ArrayList<String>> Province_AreaID = new ArrayList<>();//該省的所有地區列表(第

            for (int c = 0; c < jsonBean.get(i).getCityList().size(); c++) {//遍歷該省份的所有城市
                // 城市 name add
                String CityName = jsonBean.get(i).getCityList().get(c).getName();
                CityList.add(CityName);//新增城市
                // 城市 ID  add
                String cityid = jsonBean.get(i).getCityList().get(c).getName_id();
                CityID.add(cityid);

                // 地區 name
                ArrayList<String> City_AreaList = new ArrayList<>();//該城市的所有地區列表
                // 地區 ID
                ArrayList<String> City_AreaID = new ArrayList<>();//該城市的所有地區列表

                //如果無地區資料,建議新增空字串,防止資料為null 導致三個選項長度不匹配造成崩潰
                if (jsonBean.get(i).getCityList().get(c).getArea() == null
                        || jsonBean.get(i).getCityList().get(c).getArea().size() == 0) {
                    City_AreaList.add("");
                    City_AreaID.add("");
                } else {
                    for (int d = 0; d < jsonBean.get(i).getCityList().get(c).getArea().size(); d++) {//該城市對應地區所有資料
                        // 地區 name add
                        String AreaName = jsonBean.get(i).getCityList().get(c).getArea().get(d);
                        City_AreaList.add(AreaName);//新增該城市所有地區資料
                        // 地區 id add
                        String AreaID = jsonBean.get(i).getCityList().get(c).getArea_id().get(d);
                        City_AreaID.add(AreaID);//新增該城市所有地區資料
                    }
                }
                Province_AreaList.add(City_AreaList);//新增該省所有地區資料
                Province_AreaID.add(City_AreaID);//新增該省所有地區資料
            }

            /**
             * 新增城市資料
             */
            options2Items.add(CityList);
            index2Items.add(CityID);
            /**
             * 新增地區資料
             */
            options3Items.add(Province_AreaList);
            index3Items.add(Province_AreaID);
        }

        handler.sendEmptyMessage(MSG_LOAD_SUCCESS);//通知解析成功。為防止呼叫的時候空指標

    }
最後,可能有人想要三級聯動的程式碼,其實GitHub 上你一搜索 WheelView 都一堆 這樣的程式碼。