自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何在 Java 中使用外部庫

開發(fā) 后端
外部庫填補了 Java 核心庫中的一些功能空白。Java 自帶有一組核心庫,其中包含了定義常用數(shù)據(jù)類型和相關(guān)行為的庫(例如 String 和 Date)、與主機操作系統(tǒng)交互的實用程序(例如 System 和 File),以及一些用來管理安全性、處理網(wǎng)絡(luò)通信、創(chuàng)建或解析 XML的有用的子系統(tǒng)。

外部庫填補了 Java 核心庫中的一些功能空白。

Java 自帶有一組核心庫,其中包含了定義常用數(shù)據(jù)類型和相關(guān)行為的庫(例如 String 和 Date)、與主機操作系統(tǒng)交互的實用程序(例如 System 和 File),以及一些用來管理安全性、處理網(wǎng)絡(luò)通信、創(chuàng)建或解析 XML的有用的子系統(tǒng)。鑒于核心庫的豐富性,程序員通常很容易在其中找到有用的組件,以減少需要編寫的代碼量。

即便如此,核心庫仍有一些功能上的不足,因此發(fā)現(xiàn)這些不足的程序員們還額外創(chuàng)建了很多有趣的 Java 庫。例如,Apache Commons“是一個專注于可重用 Java 組件所有方面的 Apache 項目”,提供了大約 43 個開源庫的集合(截至撰寫本文時),涵蓋了 Java 核心庫之外的一系列功能 (例如 geometry 或 statistics),并增強或替換了 Java 核心庫中的原有功能(例如 math 或 numbers)。

[[423066]]

另一種常見的 Java 庫類型是系統(tǒng)組件的接口(例如數(shù)據(jù)庫系統(tǒng)接口),本文會著眼于使用此類接口連接到 PostgreSQL 數(shù)據(jù)庫,并得到一些有趣的信息。首先,我們來回顧一下庫的重要部分。

什么是庫?

庫library里自然包含的是一些有用的代碼。但為了發(fā)揮用處,代碼需要以特定方式進(jìn)行組織,特定的方式使 Java 程序員可以訪問其中組件來解決手頭問題。

可以說,一個庫最重要的部分是它的應(yīng)用程序編程接口(API)文檔。這種文檔很多人都熟悉,通常是由 Javadoc 生成的。Javadoc 讀取代碼中的結(jié)構(gòu)化注釋并以 HTML 格式輸出文檔,通常 API 的 包package 在頁面左上角的面板中顯示,類class 在左下角顯示,同時右側(cè)會有庫、包或類級別的詳細(xì)文檔(具體取決于在主面板中選擇的內(nèi)容)。例如,Apache Commons Math 的頂級 API 文檔 如下所示: 

API documentation for Apache Commons Math 

單擊主面板中的包會顯示該包中定義的 Java 類和接口。例如,org.apache.commons.math4.analysis.solvers 顯示了諸如 BisectionSolver 這樣的類,該類用于使用二分算法查找單變量實函數(shù)的零點。單擊 BisectionSolver 鏈接會列出 BisectionSolver 類的所有方法。

這類文檔可用作參考文檔,不適合作為學(xué)習(xí)如何使用庫的教程。比如,如果你知道什么是單變量實函數(shù)并查看包 org.apache.commons.math4.analysis.function,就可以試著使用該包來組合函數(shù)定義,然后使用 org.apache.commons.math4.analysis.solvers 包來查找剛剛創(chuàng)建的函數(shù)的零點。但如果你不知道,就可能需要更多學(xué)習(xí)向的文檔,也許甚至是一個實際例子,來讀懂參考文檔。

這種文檔結(jié)構(gòu)還有助于闡明 包package(相關(guān) Java 類和接口定義的集合)的含義,并顯示特定庫中捆綁了哪些包。

這種庫的代碼通常是在 .jar 文件 中,它基本上是由 Java 的 jar 命令創(chuàng)建的 .zip 文件,其中還包含一些其他有用的信息。.jar 文件通常被創(chuàng)建為構(gòu)建過程的端點,該構(gòu)建過程編譯了所定義包中的所有 .java 文件。

要訪問外部庫提供的功能,有兩個主要步驟:

  • 確保通過類路徑(或者命令行中的 -cp 參數(shù)或者 CLASSPATH 環(huán)境變量),庫可用于 Java 編譯步驟(javac)和執(zhí)行步驟(java)。
  • 使用恰當(dāng)?shù)?import 語句訪問程序源代碼中的包和類。

其余的步驟就與使用 String 等 Java核心類相同,使用庫提供的類和接口定義來編寫代碼。很簡單對吧?不過也沒那么簡單。首先,你需要了解庫組件的預(yù)期使用模式,然后才能編寫代碼。

示例:連接 PostgreSQL 數(shù)據(jù)庫

在數(shù)據(jù)庫系統(tǒng)中訪問數(shù)據(jù)的典型使用步驟是:

  1. 訪問正在使用的特定數(shù)據(jù)庫軟件代碼。
  2. 連接到數(shù)據(jù)庫服務(wù)器。
  3. 構(gòu)建查詢字符串。
  4. 執(zhí)行查詢字符串。
  5. 針對返回的結(jié)果,做需要的處理。
  6. 斷開與數(shù)據(jù)庫服務(wù)器的連接。

所有這些面向程序員的部分由接口包 java.sql 提供,它獨立于數(shù)據(jù)庫,定義了核心客戶端 Java 數(shù)據(jù)庫連接(JDBC)API。java.sql 包是 Java 核心庫的一部分,因此無需提供 .jar 文件即可編譯。但每個數(shù)據(jù)庫提供者都會創(chuàng)建自己的 java.sql 接口實現(xiàn)(例如 Connection 接口),并且必須在運行步驟中提供這些實現(xiàn)。

接下來我們使用 PostgreSQL,看看這一過程是如何進(jìn)行的。

訪問特定數(shù)據(jù)庫的代碼

以下代碼使用 Java 類加載器(Class.forName() 調(diào)用)將 PostgreSQL 驅(qū)動程序代碼加載到正在執(zhí)行的虛擬機中:

  1. import java.sql.*; 
  2. public class Test1 { 
  3.     public static void main(String args[]) { 
  4.         // Load the driver (jar file must be on class path) [1] 
  5.         try { 
  6.             Class.forName("org.postgresql.Driver"); 
  7.             System.out.println("driver loaded"); 
  8.         } catch (Exception e1) { 
  9.             System.err.println("couldn't find driver"); 
  10.             System.err.println(e1); 
  11.             System.exit(1); 
  12.         } 
  13.         // If we get here all is OK 
  14.         System.out.println("done."); 
  15.     } 

因為類加載器可能失敗,失敗時會拋出異常,所以將對 Class.forName() 的調(diào)用放在 try-catch 代碼塊中。

如果你使用 javac 編譯上面的代碼,然后用 java 運行,會報異常:

  1. me@mymachine:~/Test$ javac Test1.java 
  2. me@mymachine:~/Test$ java Test1 
  3. couldn't find driver 
  4. java.lang.ClassNotFoundException: org.postgresql.Driver 
  5. me@mymachine:~/Test$ 

類加載器要求類路徑中有包含 PostgreSQL JDBC 驅(qū)動程序?qū)崿F(xiàn)的 .jar 文件:

  1. me@mymachine:~/Test$ java -cp ~/src/postgresql-42.2.5.jar:. Test1 
  2. driver loaded 
  3. done. 
  4. me@mymachine:~/Test$ 

連接到數(shù)據(jù)庫服務(wù)器

以下代碼實現(xiàn)了加載 JDBC 驅(qū)動程序和創(chuàng)建到 PostgreSQL 數(shù)據(jù)庫的連接:

  1. import java.sql.*; 
  2. public class Test2 { 
  3.         public static void main(String args[]) { 
  4.                 // Load the driver (jar file must be on class path) [1] 
  5.                 try { 
  6.                         Class.forName("org.postgresql.Driver"); 
  7.                         System.out.println("driver loaded"); 
  8.                 } catch (Exception e1) { 
  9.                         System.err.println("couldn't find driver"); 
  10.                         System.err.println(e1); 
  11.                         System.exit(1); 
  12.                 } 
  13.                 // Set up connection properties [2] 
  14.                 java.util.Properties props = new java.util.Properties(); 
  15.                 props.setProperty("user","me"); 
  16.                 props.setProperty("password","mypassword"); 
  17.                 String database = "jdbc:postgresql://myhost.org:5432/test"
  18.                 // Open the connection to the database [3] 
  19.                 try (Connection conn = DriverManager.getConnection(database, props)) { 
  20.                         System.out.println("connection created"); 
  21.                 } catch (Exception e2) { 
  22.                         System.err.println("sql operations failed"); 
  23.                         System.err.println(e2); 
  24.                         System.exit(2); 
  25.                 } 
  26.                 System.out.println("connection closed"); 
  27.                 // If we get here all is OK 
  28.                 System.out.println("done."); 
  29.         } 

編譯并運行上述代碼:

  1. me@mymachine:~/Test$ javac Test2.java 
  2. me@mymachine:~/Test$ java -cp ~/src/postgresql-42.2.5.jar:. Test2 
  3. driver loaded 
  4. connection created 
  5. connection closed 
  6. done. 
  7. me@mymachine:~/Test$ 

關(guān)于上述的一些注意事項:

  • 注釋 [2] 后面的代碼使用系統(tǒng)屬性來設(shè)置連接參數(shù)(在本例中參數(shù)為 PostgreSQL 用戶名和密碼)。代碼也可以從 Java 命令行獲取這些參數(shù)并將所有參數(shù)作為參數(shù)包傳遞,同時還有一些其他 Driver.getConnection() 選項可用于單獨傳遞參數(shù)。
  • JDBC 需要一個用于定義數(shù)據(jù)庫的 URL,它在上述代碼中被聲明為 String database 并與連接參數(shù)一起傳遞給 Driver.getConnection() 方法。
  • 代碼使用 try-with-resources 語句,它會在 try-catch 塊中的代碼完成后自動關(guān)閉連接。Stack Overflow 上對這種方法進(jìn)行了長期的討論。
  • try-with-resources 語句提供對 Connection 實例的訪問,并可以在其中執(zhí)行 SQL 語句;所有錯誤都會被同一個 catch 語句捕獲。

用數(shù)據(jù)庫的連接處理一些有趣的事情

日常工作中,我經(jīng)常需要知道為給定的數(shù)據(jù)庫服務(wù)器實例定義了哪些用戶,這里我使用這個 簡便的 SQL 來獲取所有用戶的列表:

  1. import java.sql.*; 
  2. public class Test3 { 
  3.         public static void main(String args[]) { 
  4.                 // Load the driver (jar file must be on class path) [1] 
  5.                 try { 
  6.                         Class.forName("org.postgresql.Driver"); 
  7.                         System.out.println("driver loaded"); 
  8.                 } catch (Exception e1) { 
  9.                         System.err.println("couldn't find driver"); 
  10.                         System.err.println(e1); 
  11.                         System.exit(1); 
  12.                 } 
  13.                 // Set up connection properties [2] 
  14.                 java.util.Properties props = new java.util.Properties(); 
  15.                 props.setProperty("user","me"); 
  16.                 props.setProperty("password","mypassword"); 
  17.                 String database = "jdbc:postgresql://myhost.org:5432/test"
  18.                 // Open the connection to the database [3] 
  19.                 try (Connection conn = DriverManager.getConnection(database, props)) { 
  20.                         System.out.println("connection created"); 
  21.                         // Create the SQL command string [4] 
  22.                         String qs = "SELECT " + 
  23.                                 "       u.usename AS \"User name\", " + 
  24.                                 "       u.usesysid AS \"User ID\", " + 
  25.                                 "       CASE " + 
  26.                                 "       WHEN u.usesuper AND u.usecreatedb THEN " + 
  27.                                 "               CAST('superuser, create database' AS pg_catalog.text) " + 
  28.                         "       WHEN u.usesuper THEN " + 
  29.                                 "               CAST('superuser' AS pg_catalog.text) " + 
  30.                                 "       WHEN u.usecreatedb THEN " + 
  31.                                 "               CAST('create database' AS pg_catalog.text) " + 
  32.                                 "       ELSE " + 
  33.                                 "               CAST('' AS pg_catalog.text) " + 
  34.                                 "       END AS \"Attributes\" " + 
  35.                                 "FROM pg_catalog.pg_user u " + 
  36.                                 "ORDER BY 1"
  37.                         // Use the connection to create a statement, execute it, 
  38.                         // analyze the results and close the result set [5] 
  39.                         Statement stat = conn.createStatement(); 
  40.                         ResultSet rs = stat.executeQuery(qs); 
  41.                         System.out.println("User name;User ID;Attributes"); 
  42.                         while (rs.next()) { 
  43.                                 System.out.println(rs.getString("User name") + ";" + 
  44.                                                 rs.getLong("User ID") + ";" + 
  45.                                                 rs.getString("Attributes")); 
  46.                         } 
  47.                         rs.close(); 
  48.                         stat.close(); 
  49.                 
  50.                 } catch (Exception e2) { 
  51.                         System.err.println("connecting failed"); 
  52.                         System.err.println(e2); 
  53.                         System.exit(1); 
  54.                 } 
  55.                 System.out.println("connection closed"); 
  56.                 // If we get here all is OK 
  57.                 System.out.println("done."); 
  58.         } 

在上述代碼中,一旦有了 Connection 實例,它就會定義一個查詢字符串(上面的注釋 [4]),創(chuàng)建一個 Statement 實例并用其來執(zhí)行查詢字符串,然后將其結(jié)果放入一個 ResultSet 實例。程序可以遍歷該 ResultSet 實例來分析返回的結(jié)果,并以關(guān)閉 ResultSet 和 Statement 實例結(jié)束(上面的注釋 [5])。

編譯和執(zhí)行程序會產(chǎn)生以下輸出:

  1. me@mymachine:~/Test$ javac Test3.java 
  2. me@mymachine:~/Test$ java -cp ~/src/postgresql-42.2.5.jar:. Test3 
  3. driver loaded 
  4. connection created 
  5. User name;User ID;Attributes 
  6. fwa;16395;superuser 
  7. vax;197772; 
  8. mbe;290995; 
  9. aca;169248; 
  10. connection closed 
  11. done. 
  12. me@mymachine:~/Test$ 

這是在一個簡單的 Java 應(yīng)用程序中使用 PostgreSQL JDBC 庫的(非常簡單的)示例。要注意的是,由于 java.sql 庫的設(shè)計方式,它不需要在代碼中使用像 import org.postgresql.jdbc.*; 這樣的 Java 導(dǎo)入語句,而是使用 Java 類加載器在運行時引入 PostgreSQL 代碼的方式,也正因此無需在代碼編譯時指定類路徑。

 

責(zé)任編輯:未麗燕 來源: Linux中國
相關(guān)推薦

2023-12-01 09:18:27

AxiosAxios 庫

2023-01-28 17:41:07

Java代碼

2009-01-19 09:14:31

.NETMySQLMySql驅(qū)動包

2019-09-16 19:00:48

Linux變量

2020-11-30 11:55:07

Docker命令Linux

2014-07-02 09:47:06

SwiftCocoaPods

2024-09-06 11:34:15

RustAI語言

2020-04-09 10:18:51

Bash循環(huán)Linux

2011-08-10 09:31:41

Hibernateunion

2021-03-09 07:27:40

Kafka開源分布式

2015-08-27 09:46:09

swiftAFNetworkin

2021-06-09 09:36:18

DjangoElasticSearLinux

2022-05-17 08:25:10

TypeScript接口前端

2024-01-18 08:37:33

socketasyncio線程

2022-06-23 08:00:53

PythonDateTime模塊

2011-08-25 09:55:27

2012-03-08 10:18:33

JavaOracle

2024-12-03 08:00:00

2015-08-31 13:42:06

IDEDockerdoclipser

2018-05-16 10:32:06

Linux命令find
點贊
收藏

51CTO技術(shù)棧公眾號