| 会员登录 立即注册

搜索

在 Java 中使用外部库

[复制链接]
3AAA 发表于 2021-9-10 15:45:34 | 显示全部楼层 |阅读模式
3AAA
2021-9-10 15:45:34 1055 0 看全部

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



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

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

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

什么是库?


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

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



单击主面板中的包会显示该包中定义的 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 文件。

要访问外部库提供的功能,有两个主要步骤:
    确保通过类路径(或者命令行中的 -cp参数或者CLASSPATH环境变量),库可用于 Java 编译步骤(javac)和执行步骤(java)。使用恰当的 import语句访问程序源代码中的包和类。

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

示例:连接 PostgreSQL 数据库


在数据库系统中访问数据的典型使用步骤是:
    访问正在使用的特定数据库软件代码。连接到数据库服务器。构建查询字符串。执行查询字符串。针对返回的结果,做需要的处理。断开与数据库服务器的连接。

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

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

访问特定数据库的代码


以下代码使用 Java 类加载器(Class.forName()调用)将 PostgreSQL 驱动程序代码加载到正在执行的虚拟机中:
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.");    }}
因为类加载器可能失败,失败时会抛出异常,所以将对 Class.forName的调用放在try-catch代码块中。

如果你使用 javac编译上面的代码,然后用java运行,会报异常:
me@mymachine:~/Test$ javac Test1.javame@mymachine:~/Test$ java Test1couldn't find driverjava.lang.ClassNotFoundException: org.postgresql.Driverme@mymachine:~/Test$
类加载器要求类路径中有包含 PostgreSQL JDBC 驱动程序实现的 .jar 文件:
me@mymachine:~/Test$ java -cp ~/src/postgresql-42.2.5.jar:. Test1driver loadeddone.me@mymachine:~/Test$

连接到数据库服务器


以下代码实现了加载 JDBC 驱动程序和创建到 PostgreSQL 数据库的连接:
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.");        }}
编译并运行上述代码:
me@mymachine:~/Test$ javac Test2.javame@mymachine:~/Test$ java -cp ~/src/postgresql-42.2.5.jar:. Test2driver loadedconnection createdconnection closeddone.me@mymachine:~/Test$
关于上述的一些注意事项:
    注释 [2]后面的代码使用系统属性来设置连接参数(在本例中参数为 PostgreSQL 用户名和密码)。代码也可以从 Java 命令行获取这些参数并将所有参数作为参数包传递,同时还有一些其他Driver.getConnection选项可用于单独传递参数。JDBC 需要一个用于定义数据库的 URL,它在上述代码中被声明为 String database并与连接参数一起传递给Driver.getConnection方法。代码使用 try-with-resources语句,它会在try-catch块中的代码完成后自动关闭连接。Stack Overflow上对这种方法进行了长期的讨论。try-with-resources语句提供对Connection实例的访问,并可以在其中执行 SQL 语句;所有错误都会被同一个catch语句捕获。


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


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

编译和执行程序会产生以下输出:
me@mymachine:~/Test$ javac Test3.javame@mymachine:~/Test$ java -cp ~/src/postgresql-42.2.5.jar:. Test3driver loadedconnection createdUser name;User ID;Attributesfwa;16395;superuservax;197772;mbe;290995;aca;169248;connection closeddone.me@mymachine:~/Test$
这是在一个简单的 Java 应用程序中使用 PostgreSQL JDBC 库的(非常简单的)示例。要注意的是,由于 java.sql库的设计方式,它不需要在代码中使用像import org.postgresql.jdbc.*;这样的 Java 导入语句,而是使用 Java 类加载器在运行时引入 PostgreSQL 代码的方式,也正因此无需在代码编译时指定类路径。

via: https://opensource.com/article/20/2/external-libraries-java

作者:Chris Hermansen选题:lujun9972译者:unigeorge校对:wxy

本文由 LCTT原创编译,Linux中国荣誉推出
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则 返回列表

3AAA 当前离线
中级会员

查看:1055 | 回复:0

关于我们  |   投诉受理  |   联系我们  |   Archiver  |  
免责声明:邳州信息网所有言论只代表发表者个人观点,与本站无关
Copyright © 2009-2020 pzxxw.com 版权所有:邳州金银杏文化传媒有限公司  

苏公网安备 32038202000401号

快速回复 返回顶部 返回列表