新聞中心
外部庫(kù)填補(bǔ)了 Java 核心庫(kù)中的一些功能空白。

創(chuàng)新互聯(lián)專(zhuān)注為客戶(hù)提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都做網(wǎng)站、網(wǎng)站設(shè)計(jì)、魚(yú)臺(tái)網(wǎng)絡(luò)推廣、小程序制作、魚(yú)臺(tái)網(wǎng)絡(luò)營(yíng)銷(xiāo)、魚(yú)臺(tái)企業(yè)策劃、魚(yú)臺(tái)品牌公關(guān)、搜索引擎seo、人物專(zhuān)訪(fǎng)、企業(yè)宣傳片、企業(yè)代運(yùn)營(yíng)等,從售前售中售后,我們都將竭誠(chéng)為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供魚(yú)臺(tái)建站搭建服務(wù),24小時(shí)服務(wù)熱線(xiàn):13518219792,官方網(wǎng)址:www.cdcxhl.com
Java 自帶有一組核心庫(kù),其中包含了定義常用數(shù)據(jù)類(lèi)型和相關(guān)行為的庫(kù)(例如 String 和 Date)、與主機(jī)操作系統(tǒng)交互的實(shí)用程序(例如 System 和 File),以及一些用來(lái)管理安全性、處理網(wǎng)絡(luò)通信、創(chuàng)建或解析 XML的有用的子系統(tǒng)。鑒于核心庫(kù)的豐富性,程序員通常很容易在其中找到有用的組件,以減少需要編寫(xiě)的代碼量。
即便如此,核心庫(kù)仍有一些功能上的不足,因此發(fā)現(xiàn)這些不足的程序員們還額外創(chuàng)建了很多有趣的 Java 庫(kù)。例如,Apache Commons“是一個(gè)專(zhuān)注于可重用 Java 組件所有方面的 Apache 項(xiàng)目”,提供了大約 43 個(gè)開(kāi)源庫(kù)的集合(截至撰寫(xiě)本文時(shí)),涵蓋了 Java 核心庫(kù)之外的一系列功能 (例如 geometry 或 statistics),并增強(qiáng)或替換了 Java 核心庫(kù)中的原有功能(例如 math 或 numbers)。
另一種常見(jiàn)的 Java 庫(kù)類(lèi)型是系統(tǒng)組件的接口(例如數(shù)據(jù)庫(kù)系統(tǒng)接口),本文會(huì)著眼于使用此類(lèi)接口連接到 PostgreSQL 數(shù)據(jù)庫(kù),并得到一些有趣的信息。首先,我們來(lái)回顧一下庫(kù)的重要部分。
什么是庫(kù)?
庫(kù)library里自然包含的是一些有用的代碼。但為了發(fā)揮用處,代碼需要以特定方式進(jìn)行組織,特定的方式使 Java 程序員可以訪(fǎng)問(wèn)其中組件來(lái)解決手頭問(wèn)題。
可以說(shuō),一個(gè)庫(kù)最重要的部分是它的應(yīng)用程序編程接口(API)文檔。這種文檔很多人都熟悉,通常是由 Javadoc 生成的。Javadoc 讀取代碼中的結(jié)構(gòu)化注釋并以 HTML 格式輸出文檔,通常 API 的 包package 在頁(yè)面左上角的面板中顯示,類(lèi)class 在左下角顯示,同時(shí)右側(cè)會(huì)有庫(kù)、包或類(lèi)級(jí)別的詳細(xì)文檔(具體取決于在主面板中選擇的內(nèi)容)。例如,Apache Commons Math 的頂級(jí) API 文檔 如下所示:
API documentation for Apache Commons Math
單擊主面板中的包會(huì)顯示該包中定義的 Java 類(lèi)和接口。例如,org.apache.commons.math4.analysis.solvers 顯示了諸如 BisectionSolver 這樣的類(lèi),該類(lèi)用于使用二分算法查找單變量實(shí)函數(shù)的零點(diǎn)。單擊 BisectionSolver 鏈接會(huì)列出 BisectionSolver 類(lèi)的所有方法。
這類(lèi)文檔可用作參考文檔,不適合作為學(xué)習(xí)如何使用庫(kù)的教程。比如,如果你知道什么是單變量實(shí)函數(shù)并查看包 org.apache.commons.math4.analysis.function,就可以試著使用該包來(lái)組合函數(shù)定義,然后使用 org.apache.commons.math4.analysis.solvers 包來(lái)查找剛剛創(chuàng)建的函數(shù)的零點(diǎn)。但如果你不知道,就可能需要更多學(xué)習(xí)向的文檔,也許甚至是一個(gè)實(shí)際例子,來(lái)讀懂參考文檔。
這種文檔結(jié)構(gòu)還有助于闡明 包package(相關(guān) Java 類(lèi)和接口定義的集合)的含義,并顯示特定庫(kù)中捆綁了哪些包。
這種庫(kù)的代碼通常是在 .jar 文件 中,它基本上是由 Java 的 jar 命令創(chuàng)建的 .zip 文件,其中還包含一些其他有用的信息。.jar 文件通常被創(chuàng)建為構(gòu)建過(guò)程的端點(diǎn),該構(gòu)建過(guò)程編譯了所定義包中的所有 .java 文件。
要訪(fǎng)問(wèn)外部庫(kù)提供的功能,有兩個(gè)主要步驟:
- 確保通過(guò)類(lèi)路徑(或者命令行中的 -cp 參數(shù)或者 CLASSPATH 環(huán)境變量),庫(kù)可用于 Java 編譯步驟(javac)和執(zhí)行步驟(java)。
- 使用恰當(dāng)?shù)?import 語(yǔ)句訪(fǎng)問(wèn)程序源代碼中的包和類(lèi)。
其余的步驟就與使用 String 等 Java核心類(lèi)相同,使用庫(kù)提供的類(lèi)和接口定義來(lái)編寫(xiě)代碼。很簡(jiǎn)單對(duì)吧?不過(guò)也沒(méi)那么簡(jiǎn)單。首先,你需要了解庫(kù)組件的預(yù)期使用模式,然后才能編寫(xiě)代碼。
示例:連接 PostgreSQL 數(shù)據(jù)庫(kù)
在數(shù)據(jù)庫(kù)系統(tǒng)中訪(fǎng)問(wèn)數(shù)據(jù)的典型使用步驟是:
- 訪(fǎng)問(wèn)正在使用的特定數(shù)據(jù)庫(kù)軟件代碼。
- 連接到數(shù)據(jù)庫(kù)服務(wù)器。
- 構(gòu)建查詢(xún)字符串。
- 執(zhí)行查詢(xún)字符串。
- 針對(duì)返回的結(jié)果,做需要的處理。
- 斷開(kāi)與數(shù)據(jù)庫(kù)服務(wù)器的連接。
所有這些面向程序員的部分由接口包 java.sql 提供,它獨(dú)立于數(shù)據(jù)庫(kù),定義了核心客戶(hù)端 Java 數(shù)據(jù)庫(kù)連接(JDBC)API。java.sql 包是 Java 核心庫(kù)的一部分,因此無(wú)需提供 .jar 文件即可編譯。但每個(gè)數(shù)據(jù)庫(kù)提供者都會(huì)創(chuàng)建自己的 java.sql 接口實(shí)現(xiàn)(例如 Connection 接口),并且必須在運(yùn)行步驟中提供這些實(shí)現(xiàn)。
接下來(lái)我們使用 PostgreSQL,看看這一過(guò)程是如何進(jìn)行的。
訪(fǎng)問(wèn)特定數(shù)據(jù)庫(kù)的代碼
以下代碼使用 Java 類(lèi)加載器(Class.forName() 調(diào)用)將 PostgreSQL 驅(qū)動(dòng)程序代碼加載到正在執(zhí)行的虛擬機(jī)中:
- import java.sql.*;
- public class Test1 {
- public static void main(String args[]) {
- // Load the driver (jar file must be on class path) [1]
- try {
- Class.forName("org.postgresql.Driver");
- System.out.println("driver loaded");
- } catch (Exception e1) {
- System.err.println("couldn't find driver");
- System.err.println(e1);
- System.exit(1);
- }
- // If we get here all is OK
- System.out.println("done.");
- }
- }
因?yàn)轭?lèi)加載器可能失敗,失敗時(shí)會(huì)拋出異常,所以將對(duì) Class.forName() 的調(diào)用放在 try-catch 代碼塊中。
如果你使用 javac 編譯上面的代碼,然后用 java 運(yùn)行,會(huì)報(bào)異常:
- me@mymachine:~/Test$ javac Test1.java
- me@mymachine:~/Test$ java Test1
- couldn't find driver
- java.lang.ClassNotFoundException: org.postgresql.Driver
- me@mymachine:~/Test$
類(lèi)加載器要求類(lèi)路徑中有包含 PostgreSQL JDBC 驅(qū)動(dòng)程序?qū)崿F(xiàn)的 .jar 文件:
- me@mymachine:~/Test$ java -cp ~/src/postgresql-42.2.5.jar:. Test1
- driver loaded
- done.
- me@mymachine:~/Test$
連接到數(shù)據(jù)庫(kù)服務(wù)器
以下代碼實(shí)現(xiàn)了加載 JDBC 驅(qū)動(dòng)程序和創(chuàng)建到 PostgreSQL 數(shù)據(jù)庫(kù)的連接:
- import java.sql.*;
- public class Test2 {
- public static void main(String args[]) {
- // Load the driver (jar file must be on class path) [1]
- try {
- Class.forName("org.postgresql.Driver");
- System.out.println("driver loaded");
- } catch (Exception e1) {
- System.err.println("couldn't find driver");
- System.err.println(e1);
- System.exit(1);
- }
- // Set up connection properties [2]
- java.util.Properties props = new java.util.Properties();
- props.setProperty("user","me");
- props.setProperty("password","mypassword");
- String database = "jdbc:postgresql://myhost.org:5432/test";
- // Open the connection to the database [3]
- try (Connection conn = DriverManager.getConnection(database, props)) {
- System.out.println("connection created");
- } catch (Exception e2) {
- System.err.println("sql operations failed");
- System.err.println(e2);
- System.exit(2);
- }
- System.out.println("connection closed");
- // If we get here all is OK
- System.out.println("done.");
- }
- }
編譯并運(yùn)行上述代碼:
- me@mymachine:~/Test$ javac Test2.java
- me@mymachine:~/Test$ java -cp ~/src/postgresql-42.2.5.jar:. Test2
- driver loaded
- connection created
- connection closed
- done.
- me@mymachine:~/Test$
關(guān)于上述的一些注意事項(xiàng):
- 注釋 [2] 后面的代碼使用系統(tǒng)屬性來(lái)設(shè)置連接參數(shù)(在本例中參數(shù)為 PostgreSQL 用戶(hù)名和密碼)。代碼也可以從 Java 命令行獲取這些參數(shù)并將所有參數(shù)作為參數(shù)包傳遞,同時(shí)還有一些其他 Driver.getConnection() 選項(xiàng)可用于單獨(dú)傳遞參數(shù)。
- JDBC 需要一個(gè)用于定義數(shù)據(jù)庫(kù)的 URL,它在上述代碼中被聲明為 String database 并與連接參數(shù)一起傳遞給 Driver.getConnection() 方法。
- 代碼使用 try-with-resources 語(yǔ)句,它會(huì)在 try-catch 塊中的代碼完成后自動(dòng)關(guān)閉連接。Stack Overflow 上對(duì)這種方法進(jìn)行了長(zhǎng)期的討論。
- try-with-resources 語(yǔ)句提供對(duì) Connection 實(shí)例的訪(fǎng)問(wèn),并可以在其中執(zhí)行 SQL 語(yǔ)句;所有錯(cuò)誤都會(huì)被同一個(gè) catch 語(yǔ)句捕獲。
用數(shù)據(jù)庫(kù)的連接處理一些有趣的事情
日常工作中,我經(jīng)常需要知道為給定的數(shù)據(jù)庫(kù)服務(wù)器實(shí)例定義了哪些用戶(hù),這里我使用這個(gè) 簡(jiǎn)便的 SQL 來(lái)獲取所有用戶(hù)的列表:
- import java.sql.*;
- public class Test3 {
- public static void main(String args[]) {
- // Load the driver (jar file must be on class path) [1]
- try {
- Class.forName("org.postgresql.Driver");
- System.out.println("driver loaded");
- } catch (Exception e1) {
- System.err.println("couldn't find driver");
- System.err.println(e1);
- System.exit(1);
- }
- // Set up connection properties [2]
- java.util.Properties props = new java.util.Properties();
- props.setProperty("user","me");
- props.setProperty("password","mypassword");
- String database = "jdbc:postgresql://myhost.org:5432/test";
- // Open the connection to the database [3]
- try (Connection conn = DriverManager.getConnection(database, props)) {
- System.out.println("connection created");
- // Create the SQL command string [4]
- String qs = "SELECT " +
- " u.usename AS \"User name\", " +
- " u.usesysid AS \"User ID\", " +
- " CASE " +
- " WHEN u.usesuper AND u.usecreatedb THEN " +
- " CAST('superuser, create database' AS pg_catalog.text) " +
- " WHEN u.usesuper THEN " +
- " CAST('superuser' AS pg_catalog.text) " +
- " WHEN u.usecreatedb THEN " +
- " CAST('create database' AS pg_catalog.text) " +
- " ELSE " +
- " CAST('' AS pg_catalog.text) " +
- " END AS \"Attributes\" " +
- "FROM pg_catalog.pg_user u " +
- "ORDER BY 1";
- // Use the connection to create a statement, execute it,
- // analyze the results and close the result set [5]
- Statement stat = conn.createStatement();
- ResultSet rs = stat.executeQuery(qs);
- System.out.println("User name;User ID;Attributes");
- while (rs.next()) {
- System.out.println(rs.getString("User name") + ";" +
- rs.getLong("User ID") + ";" +
- rs.getString("Attributes"));
- }
- rs.close();
- stat.close();
- } catch (Exception e2) {
- System.err.println("connecting failed");
- System.err.println(e2);
- System.exit(1);
- }
- System.out.println("connection closed");
- // If we get here all is OK
- System.out.println("done.");
- }
- }
在上述代碼中,一旦有了 Connection 實(shí)例,它就會(huì)定義一個(gè)查詢(xún)字符串(上面的注釋 [4]),創(chuàng)建一個(gè) Statement 實(shí)例并用其來(lái)執(zhí)行查詢(xún)字符串,然后將其結(jié)果放入一個(gè) ResultSet 實(shí)例。程序可以遍歷該 ResultSet 實(shí)例來(lái)分析返回的結(jié)果,并以關(guān)閉 ResultSet 和 Statement 實(shí)例結(jié)束(上面的注釋 [5])。
編譯和執(zhí)行程序會(huì)產(chǎn)生以下輸出:
- me@mymachine:~/Test$ javac Test3.java
- me@mymachine:~/Test$ java -cp ~/src/postgresql-42.2.5.jar:. Test3
- driver loaded
- connection created
- User name;User ID;Attributes
- fwa;16395;superuser
- vax;197772;
- mbe;290995;
- aca;169248;
- connection closed
- done.
- me@mymachine:~/Test$
這是在一個(gè)簡(jiǎn)單的 Java 應(yīng)用程序中使用 PostgreSQL JDBC 庫(kù)的(非常簡(jiǎn)單的)示例。要注意的是,由于 java.sql 庫(kù)的設(shè)計(jì)方式,它不需要在代碼中使用像 import org.postgresql.jdbc.*; 這樣的 Java 導(dǎo)入語(yǔ)句,而是使用 Java 類(lèi)加載器在運(yùn)行時(shí)引入 PostgreSQL 代碼的方式,也正因此無(wú)需在代碼編譯時(shí)指定類(lèi)路徑。
分享標(biāo)題:如何在Java中使用外部庫(kù)
網(wǎng)站路徑:http://m.5511xx.com/article/cdisjdd.html


咨詢(xún)
建站咨詢(xún)
