使用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 都一堆 這樣的程式碼。