Java開發筆記(一百四十八)通過JDBC查詢數據記錄

来源:https://www.cnblogs.com/pinlantu/archive/2019/09/09/11494099.html
-Advertisement-
Play Games

前面介紹了通過JDBC如何管理資料庫,當時提到Statement專門提供了executeQuery方法用於查詢操作,為什麼查詢操作這麼特殊呢?這是因為其它語句跑完一次就了事了,頂多像insert、update、delete再返回受影響的記錄數量,但select命令跟它們不一樣,查詢語句可能會返回多條 ...


前面介紹了通過JDBC如何管理資料庫,當時提到Statement專門提供了executeQuery方法用於查詢操作,為什麼查詢操作這麼特殊呢?這是因為其它語句跑完一次就了事了,頂多像insert、update、delete再返回受影響的記錄數量,但select命令跟它們不一樣,查詢語句可能會返回多條記錄,每條記錄又包含多個欄位。似此多條記錄多個欄位的情景,返回值無論定義為哪種類型都不太好辦,故而乾脆給個單獨的executeQuery方法,該方法的返回值也設置成專屬的ResultSet類型,表示查詢方法返回了一個結果集,詳細的記錄結果請到結果集中遍歷獲得。
據此可將記錄查詢的操作過程分成以下四個步驟:
1、獲取資料庫連接:該步驟調用DriverManager類的getConnection方法獲得連接對象。
2、創建該連接的執行報告:該步驟調用Connection對象的createStatement方法獲得執行報告。
3、命令報告執行查詢語句:該步驟調用報告對象的executeQuery方法來執行查詢語句,並返回查詢記錄的結果集。
4、迴圈遍歷結果集裡面的所有記錄:通常該步驟需調用結果集對象的next方法不斷往後遍歷,也就是將結果集的指示游標一步一步向後移動。在遍歷過程當中,可能要調用結果集對象的其它方法進一步操作,ResultSet的常見方法分成三類,說明如下:
1、移動游標
該類方法可將當前游標移動到指定位置,主要包括下列方法:
next:將游標移到後一條記錄。該方法返回true表示尚未移到末尾,返回false表示已經移到末尾。
absolute:將游標移到第幾條記錄,如果參數為負數則表示倒數的第幾條。
first:將游標移到第一條記錄。
last:將游標移到最後一條記錄。
previous:將游標移到前一條記錄。
beforeFirst:將游標移到第一條記錄之前。
afterLast:將游標移到最後一條記錄之後。
2、判斷游標位置
該類方法可判斷當前游標是否處於某個位置,主要包括下列方法:
isFirst:游標是否指向第一條記錄。
isLast:游標是否指向最後一條記錄。
isBeforeFirst:游標是否在第一條記錄之前。
isAfterLast:游標是否在最後一條記錄之後。
3、從當前游標獲取數據
該類方法可從當前游標指向的記錄中獲取欄位值,當方法參數為整型時,表示獲取指定序號的欄位值;當方法參數為字元串時,表示獲取指定名稱的欄位值。相關的獲取方法羅列如下:
getInt:獲取指定序號或者指定名稱的欄位整型值。
getLong:獲取指定序號或者指定名稱的欄位長整值。
getFloat:獲取指定序號或者指定名稱的欄位浮點值。
getDouble:獲取指定序號或者指定名稱的欄位雙精度值。
getString:獲取指定序號或者指定名稱的欄位字元串值。
getDate:獲取指定序號或者指定名稱的欄位日期值。

接下來舉幾個具體應用的例子,首先要從teacher表中查詢所有記錄,則依次連接資料庫、創建連接的報告、執行查詢語句,再迴圈遍歷結果集獲取每條記錄的欄位信息。這一連串的查詢代碼示例如下:

	// 查詢所有記錄(預設排序)
	private static void showAllRecord() {
		String sql = "select * from teacher";
		// 連接資料庫、創建連接的報告、執行查詢語句
		try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword);
				Statement stmt = conn.createStatement();
				ResultSet rs = stmt.executeQuery(sql)) {
			while (rs.next()) { // 迴圈遍歷結果集裡面的所有記錄
				int gonghao = rs.getInt("gonghao"); // 獲取指定欄位的整型值
				String name = rs.getString("name"); // 獲取指定欄位的字元串值
				Date birthday = rs.getDate("birthday"); // 獲取指定欄位的日期值
				int sex = rs.getInt("sex"); // 獲取指定欄位的整型值
				String course = rs.getString("course"); // 獲取指定欄位的字元串值
				String desc = String.format("工號為%d,姓名為%s,出生日期為%s,性別為%s,任教課程為%s。", 
						gonghao, name, getFormatDate(birthday), sex==0 ? "男性" : "女性", course);
				System.out.println("當前教師信息為:"+desc);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

 

註意MySQL未提供將日期轉成字元串的to_char函數,因而只能先取到Date類型的欄位值,再將其通過Java代碼轉為字元串。日期類型轉換為字元串類型的方法代碼如下所示:

	// 獲取指定格式的日期字元串
	public static String getFormatDate(Date date) {
		// 創建一個日期格式化的工具
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		// 將當前日期時間按照指定格式輸出格式化後的日期時間字元串
		return sdf.format(date);
	}

 

接著運行上面的查詢方法showAllRecord,觀察到日誌視窗完整輸出瞭如下的五條記錄信息。

當前教師信息為:工號為1,姓名為張老師,出生日期為1983-03-03,性別為女性,任教課程為語文。
當前教師信息為:工號為2,姓名為李老師,出生日期為1984-04-04,性別為男性,任教課程為數學。
當前教師信息為:工號為3,姓名為王老師,出生日期為1985-05-05,性別為女性,任教課程為英語。
當前教師信息為:工號為4,姓名為趙老師,出生日期為1986-06-06,性別為男性,任教課程為物理。
當前教師信息為:工號為5,姓名為劉老師,出生日期為1987-07-07,性別為女性,任教課程為化學。

然後在原語句增加排序條件,讓所有記錄按照生日欄位降序排列,則修改後的查詢代碼如下所示:

	// 查詢所有記錄(按照生日倒序)
	private static void showAllRecordByBirthday() {
		String sql = "select * from teacher order by birthday desc";
		// 連接資料庫、創建連接的報告、執行查詢語句
		try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword);
				Statement stmt = conn.createStatement();
				ResultSet rs = stmt.executeQuery(sql)) {
			while (rs.next()) { // 迴圈遍歷結果集裡面的所有記錄
				int gonghao = rs.getInt("gonghao"); // 獲取指定欄位的整型值
				String name = rs.getString("name"); // 獲取指定欄位的字元串值
				Date birthday = rs.getDate("birthday"); // 獲取指定欄位的日期值
				int sex = rs.getInt("sex"); // 獲取指定欄位的整型值
				String course = rs.getString("course"); // 獲取指定欄位的字元串值
				String desc = String.format("工號為%d,姓名為%s,出生日期為%s,性別為%s,任教課程為%s。", 
						gonghao, name, getFormatDate(birthday), sex==0 ? "男性" : "女性", course);
				System.out.println("當前教師信息為:"+desc);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

 

增加了showAllRecordByBirthday方法之後,再次運行測試程式,從日誌視窗可見這次的記錄結果以生日欄位降序顯示了。

當前教師信息為:工號為5,姓名為劉老師,出生日期為1987-07-07,性別為女性,任教課程為化學。
當前教師信息為:工號為4,姓名為趙老師,出生日期為1986-06-06,性別為男性,任教課程為物理。
當前教師信息為:工號為3,姓名為王老師,出生日期為1985-05-05,性別為女性,任教課程為英語。
當前教師信息為:工號為2,姓名為李老師,出生日期為1984-04-04,性別為男性,任教課程為數學。
當前教師信息為:工號為1,姓名為張老師,出生日期為1983-03-03,性別為女性,任教課程為語文。

排序條件僅僅調整返回記錄的順序,然而分組條件就不一樣了。因為分組條件存在統計操作,像count、sum、max這些函數只返回運算結果,但從結果集中取數據有賴於欄位名稱,所以需要在統計函數之後加個別名,相當於該函數的運算結果暫存於該別名變數。比如表達式“count(sex) count”說的就是計數結果以count命名,游標從count欄位獲取到的即為計數值。下麵是對teacher表按照性別欄位分組統計的查詢代碼例子:

	// 查詢性別分組。註意要給count之類的函數結果分配別名
	private static void showRecordGroupBySex() {
		String sql = "select sex,count(sex) count from teacher group by sex order by sex asc";
		// 連接資料庫、創建連接的報告、執行查詢語句
		try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword);
				Statement stmt = conn.createStatement();
				ResultSet rs = stmt.executeQuery(sql)) {
			while (rs.next()) { // 迴圈遍歷結果集裡面的所有記錄
				int sex = rs.getInt("sex"); // 獲取指定欄位的整型值
				int count = rs.getInt("count"); // 獲取指定欄位的整型值
				String desc = String.format("%s老師有%d位;", sex==0 ? "男" : "女", count);
				System.out.print(desc);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

 

運行包含showRecordGroupBySex方法的測試程式,果然正確輸出了預期的統計日誌如下所示。

男老師有2位;女老師有3位;  



更多Java技術文章參見《Java開發筆記(序)章節目錄


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 這個月公司的項目有點忙,我又生病了,美術同事和我又有幾個周末都有事所以沒有來給我做資源 而我這邊也又遇到了瓶頸,目前是開始攻關飛行道具的部分 UE4的4.23在經歷了8個預覽版之後終於出正式版了,我也第一時間更新下來並且升級了工程 可破壞建築什麼的聽起來可能是不錯的效果,以後做戰爭游戲可能會大量用到 ...
  • isinstance() 判斷isinstance(obj,cls)中obj是否是cls類的對象 issubclass() 判斷issubclass(sub,super)中sub是否是super類的派生類 反射 反射就是用字元串類型的名字去操作變數,python中的一切事物皆為對象(都可以使用反射) ...
  • 今日所學: /* 2019.08.19開始學習,此為補檔。 */ 1.String類 實例化:①String name1 = "張三" ; ②String name2 = new String("李四") ; 2.==比較的是引用,equals比較的是具體內容。 String name3 = nam ...
  • 力爭清晰完整準確(逐步完善,持續更新) 1、String類為什麼是final的 首先分析String的源碼: 類被final關鍵字限定,說明它不可以被繼承,沒有子類。即持有一個String對象的引用,它必然是String類,而不會是其他的類。 value[]是用來存儲值的,被final關鍵字修飾,說 ...
  • 之前看過《深入瞭解Java虛擬機》感覺容易忘,今天寫一篇博客加深一下印象。 JVM的記憶體分配和垃圾回收(GC)主要發生在Java堆中。而Java堆根據對象的存活時間可以分為新生代和老年代,而新生代又細分為Eden區、From Survivor區、To Survivor區,這是由於新生代中的垃圾回收算 ...
  • 前言 這個周末被幾個技術博主的同一篇公眾號文章 "fastjson又被髮現漏洞,這次危害可導致服務癱瘓!" 刷屏,離之前漏洞事件沒多久,fastjson 又出現嚴重 Bug。目前項目中不少使用了 fastjson 做對象與JSON數據的轉換,又需要更新版本重新部署,可以說是費時費力。與此同時,也帶給 ...
  • 0909自我總結 drf框架中jwt 一.模塊的安裝 :http://getblimp.github.io/django rest framework jwt/ 他是個第三方的開源項目 :`pip install djangorestframework jwt` 使用 設定好的jwt 測試介面:po ...
  • 異常處理(Throwable)和繼承Exception類是Throwable類的子類Throwable類的主要方法自定義異常類繼承於Exception類,通過throw new Exception手動拋出異常Java不支持多繼承繼承的特性:繼承調用父子類構造函數順序問題 異常處理(Throwable ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...