文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

如何在 Java 中使用外部库

2024-12-14 00:22

关注

Java 自带有一组核心库,其中包含了定义常用数据类型和相关行为的库(例如 String 和 Date)、与主机操作系统交互的实用程序(例如 System 和 File),以及一些用来管理安全性、处理网络通信、创建或解析 XML的有用的子系统。鉴于核心库的丰富性,程序员通常很容易在其中找到有用的组件,以减少需要编写的代码量。

即便如此,核心库仍有一些功能上的不足,因此发现这些不足的程序员们还额外创建了很多有趣的 Java 库。例如,Apache Commons“是一个专注于可重用 Java 组件所有方面的 Apache 项目”,提供了大约 43 个开源库的集合(截至撰写本文时),涵盖了 Java 核心库之外的一系列功能 (例如 geometry 或 statistics),并增强或替换了 Java 核心库中的原有功能(例如 math 或 numbers)。

[[423066]]

另一种常见的 Java 库类型是系统组件的接口(例如数据库系统接口),本文会着眼于使用此类接口连接到 PostgreSQL 数据库,并得到一些有趣的信息。首先,我们来回顾一下库的重要部分。

什么是库?

库library里自然包含的是一些有用的代码。但为了发挥用处,代码需要以特定方式进行组织,特定的方式使 Java 程序员可以访问其中组件来解决手头问题。

可以说,一个库最重要的部分是它的应用程序编程接口(API)文档。这种文档很多人都熟悉,通常是由 Javadoc 生成的。Javadoc 读取代码中的结构化注释并以 HTML 格式输出文档,通常 API 的 包package 在页面左上角的面板中显示,类class 在左下角显示,同时右侧会有库、包或类级别的详细文档(具体取决于在主面板中选择的内容)。例如,Apache Commons Math 的顶级 API 文档 如下所示: 

API documentation for Apache Commons Math 

单击主面板中的包会显示该包中定义的 Java 类和接口。例如,org.apache.commons.math4.analysis.solvers 显示了诸如 BisectionSolver 这样的类,该类用于使用二分算法查找单变量实函数的零点。单击 BisectionSolver 链接会列出 BisectionSolver 类的所有方法。

这类文档可用作参考文档,不适合作为学习如何使用库的教程。比如,如果你知道什么是单变量实函数并查看包 org.apache.commons.math4.analysis.function,就可以试着使用该包来组合函数定义,然后使用 org.apache.commons.math4.analysis.solvers 包来查找刚刚创建的函数的零点。但如果你不知道,就可能需要更多学习向的文档,也许甚至是一个实际例子,来读懂参考文档。

这种文档结构还有助于阐明 包package(相关 Java 类和接口定义的集合)的含义,并显示特定库中捆绑了哪些包。

这种库的代码通常是在 .jar 文件 中,它基本上是由 Java 的 jar 命令创建的 .zip 文件,其中还包含一些其他有用的信息。.jar 文件通常被创建为构建过程的端点,该构建过程编译了所定义包中的所有 .java 文件。

要访问外部库提供的功能,有两个主要步骤:

其余的步骤就与使用 String 等 Java核心类相同,使用库提供的类和接口定义来编写代码。很简单对吧?不过也没那么简单。首先,你需要了解库组件的预期使用模式,然后才能编写代码。

示例:连接 PostgreSQL 数据库

在数据库系统中访问数据的典型使用步骤是:

  1. 访问正在使用的特定数据库软件代码。
  2. 连接到数据库服务器。
  3. 构建查询字符串。
  4. 执行查询字符串。
  5. 针对返回的结果,做需要的处理。
  6. 断开与数据库服务器的连接。

所有这些面向程序员的部分由接口包 java.sql 提供,它独立于数据库,定义了核心客户端 Java 数据库连接(JDBC)API。java.sql 包是 Java 核心库的一部分,因此无需提供 .jar 文件即可编译。但每个数据库提供者都会创建自己的 java.sql 接口实现(例如 Connection 接口),并且必须在运行步骤中提供这些实现。

接下来我们使用 PostgreSQL,看看这一过程是如何进行的。

访问特定数据库的代码

以下代码使用 Java 类加载器(Class.forName() 调用)将 PostgreSQL 驱动程序代码加载到正在执行的虚拟机中:

  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() 的调用放在 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 驱动程序实现的 .jar 文件:

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

连接到数据库服务器

以下代码实现了加载 JDBC 驱动程序和创建到 PostgreSQL 数据库的连接:

  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$ 

关于上述的一些注意事项:

用数据库的连接处理一些有趣的事情

日常工作中,我经常需要知道为给定的数据库服务器实例定义了哪些用户,这里我使用这个 简便的 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]),创建一个 Statement 实例并用其来执行查询字符串,然后将其结果放入一个 ResultSet 实例。程序可以遍历该 ResultSet 实例来分析返回的结果,并以关闭 ResultSet 和 Statement 实例结束(上面的注释 [5])。

编译和执行程序会产生以下输出:

  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 应用程序中使用 PostgreSQL JDBC 库的(非常简单的)示例。要注意的是,由于 java.sql 库的设计方式,它不需要在代码中使用像 import org.postgresql.jdbc.*; 这样的 Java 导入语句,而是使用 Java 类加载器在运行时引入 PostgreSQL 代码的方式,也正因此无需在代码编译时指定类路径。

 

来源:Linux中国内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯