当前位置: 首页 > 科技观察

如何在Java中使用外部库

时间:2023-03-14 22:16:18 科技观察

外部库填补了Java核心库中的一些功能空白。Java带有一组核心库,包括定义通用数据类型和相关行为的库(例如String和Date)、用于与主机操作系统交互的实用程序(例如System和File)以及一些用于管理安全性的函数,用于处理网络通信、创建或解析XML的有用子系统。鉴于核心库的丰富性,程序员通常很容易在其中找到有用的组件,从而减少需要编写的代码量。即便如此,核心库仍然存在一些功能上的不足,因此发现这些不足的程序员另外创建了很多有趣的Java库。例如,ApacheCommons“是一个专注于可重用Java组件所有方面的Apache项目”,提供了大约43个开源库的集合(截至撰写本文时),涵盖了核心Java库之外的一系列功能(例如几何或统计),并增强或替换Java核心库中的本机功能(例如数学或数字)。另一种常见的Java库类型是系统组件的接口(例如数据库系统接口),本文将研究使用此类接口连接到PostgreSQL数据库并获得一些有趣的信息。首先,让我们回顾一下库的重要部分。什么是图书馆?库自然包含有用的代码。但要发挥作用,代码的组织方式需要使Java程序员可以访问其组件以解决手头的问题。可以说,库中最重要的部分是它的应用程序编程接口(API)文档。这种文档对很多人来说都很熟悉,通常由Javadoc生成。Javadoc读取代码中的结构化注释并以HTML格式输出文档。通常,API的包显示在页面的左上面板,类类显示在左下角,右侧会有库、包或类级别的详细信息Documentation(取决于选择的是什么在主面板中)。例如,ApacheCommonsMath的顶级API文档如下所示:ApacheCommonsMath的API文档单击主面板中的包会显示该包中定义的Java类和接口。例如,org.apache.commons.math4.analysis.solvers显示了诸如BisectionSolver之类的类,用于使用二分法算法查找单变量实函数的零点。单击BisectionSolver链接会列出BisectionSolver类的所有方法。此类文档旨在用作参考文档,而不是学习如何使用该库的教程。例如,如果您知道什么是单变量实函数并查看包org.apache.commons.math4.analysis.function,您可以尝试使用该包来编写函数定义,然后使用org.apache.commons.math4。分析。solvers包来查找刚刚创建的函数的零点。但如果你不知道,你可能需要更多面向学习的文档,甚至可能需要一个实际的例子,来阅读参考文档。此文档结构还有助于阐明包(相关Java类和接口定义的集合)的含义,并显示哪些包捆绑在特定库中。这种库的代码通常在.jar文件中,它基本上是一个由Java的jar命令创建的.zip文件,其中还包含一些其他有用的信息。.jar文件通常创建为构建过程的端点,该过程编译定义包中的所有.java文件。要访问外部库提供的功能,有两个主要步骤:确保库可通过类路径(命令行上的-cp参数或CLASSPATH环境变量)。使用适当的导入语句访问程序源代码中的包和类。剩下的步骤和使用String等Java核心类一样,使用库提供的类和接口定义来编写代码。简单吧?但这不是那么简单。首先,您需要了解库组件的预期使用模式,然后才能编写代码。示例:连接到PostgreSQL数据库访问数据库系统中数据的典型使用步骤是:访问正在使用的特定数据库软件代码。连接到数据库服务器。构建查询字符串。执行查询字符串。对于返回的结果,做必要的处理。断开与数据库服务器的连接。所有这些面向程序员的部分都由接口包java.sql提供,它独立于数据库并定义核心客户端Java数据库连接(JDBC)API。java.sql包是Java核心库的一部分,因此无需提供.jar文件即可编译。但是每个数据库提供者都会创建自己的java.sql接口(例如Connection接口)的实现,并且必须在运行步骤中提供这些实现。接下来我们使用PostgreSQL看看这个过程是如何工作的。访问特定数据库的代码以下代码使用Java类加载器(Class.forName()调用)将PostgreSQL驱动程序代码加载到正在执行的虚拟机中:importjava.sql.*;publicclassTest1{publicstaticvoidmain(Stringargs[]){//Loadthedriver(jarfilemustbeonclasspath)[1]try{Class.forName("org.postgresql.Driver");System.out.println("driverloaded");}catch(Exceptione1){System.err.println("couldn'tfinddriver");System.err.println(e1);System.exit(1);}//IfwegethereallisOKSystem.out.println("done.");}}因为类加载器可能会失败,失败时会抛出异常,所以把对Class.forName()的调用放在一个try-catch块中。如果用javac编译上面的代码,再用java运行,会报异常:me@mymachine:~/Test$javacTest1.javame@mymachine:~/Test$javaTest1couldn'tfinddriverjava.lang.ClassNotFoundException:org.postgresql.Driverme@mymachine:~/Test$类加载器需要一个包含PostgreSQLJDBC驱动程序实现的.jar文件在类路径中:me@mymachine:~/Test$java-cp~/src/postgresql-42.2.5。jar:.Test1driverloadedone.me@mymachine:~/Test$连接数据库服务器下面的代码实现了加载JDBC驱动和??建立PostgreSQL数据库的连接:importjava.sql.*;publicclassTest2{publicstaticvoidmain(Stringargs[]){//Loadthedriver(jarfilemustbeonclasspath)[1]try{Class.forName("org.postgresql.Driver");System.out.println("driverloaded");}catch(Exceptione1){System.err.println("couldn'tfinddriver");系统。err.println(e1);System.exit(1);}//设置连接属性[2]java.util.Propertiesprops=newjava.util.Properties();props.setProperty("user","me");props.setProperty("密码","我的密码");Stringdatabase="jdbc:postgresql://myhost.org:5432/test";//打开与数据库的连接[3]try(Connectionconn=DriverManager.getConnection(database,props)){System.out.println("connectioncreated");}catch(Exceptione2){System.err.println("sqloperationsfailed");System.err.println(e2);System.exit(2);}System.out.println("connectionclosed");//IfwegethereallisOKSystem.out.println("done.");}}编译运行以上code:me@mymachine:~/Test$javacTest2.javame@mymachine:~/Test$java-cp~/src/postgresql-42.2.5.jar:.Test2driverloadedconnectioncreatedconnectionclosedone.me@mymachine:~/Test$一些关于上面注意:注释[2]后面的代码使用系统属性来设置连接参数(在这种情况下参数是PostgreSQL用户名和密码)代码也可以从Java命令行获取这些参数并将所有参数作为parameterpack,alongwith几个其他Driver.getConnection()optionsareavailabletopassparametersalone.JDBC需要一个URL来定义一个数据库,它被声明为String上面代码中的数据库,并连同连接参数一起传递给Driver.getConnection()方法。代码使用try-with-resources语句,在try-catch块中的代码完成后自动关闭连接。在StackOverflow上对这种方法进行了长时间的讨论。try-with-resources语句提供对Connection实例的访问,并可以在其中执行SQL语句;所有错误都被同一个catch语句捕获。使用数据库连接做一些有趣的事情在我的日常工作中,我经常需要知道为给定的数据库服务器实例定义了哪些用户,这里我使用这个方便的SQL来获取所有用户的列表:importjava.sql.*;publicclassTest3{publicstaticvoidmain(Stringargs[]){//Loadthedriver(jarfilemustbeonclasspath)[1]try{Class.forName("org.postgresql.Driver");System.out.println("driverloaded");}catch(Exceptione1){System.err.println("找不到驱动程序");System.err.println(e1);System.exit(1);}//Setupconnectionproperties[2]java.util.Propertiesprops=newjava.util.Properties();props.setProperty("user","me");props.setProperty("password","mypassword");Stringdatabase="jdbc:postgresql://myhost.org:5432/test";//打开与数据库的连接[3]try(Connectionconn=DriverManager.getConnection(database,props)){System.out.println("connectioncreated");//创建SQL命令字符串[4]Stringqs="SELECT"+"u.usenameAS\"用户名\","+"u.usesysidAS\"用户ID\","+"CASE"+"WHENu.usesuperANDu.usecreatedbTHEN"+"CAST('superuser,createdatabase'ASpg_catalog.text)"+"WHENu.usesuperTHEN"+"CAST('superuser'ASpg_catalog.text)"+"WHENu.usecreatedbTHEN"+"CAST('createdatabase'ASpg_catalog.text)"+"ELSE"+"CAST(''ASpg_catalog.text)"+"ENDAS\"Attributes\""+"FROMpg_catalog.pg_useru"+"ORDERBY1";//使用连接创建语句,executeit,//分析结果并关闭结果集[5]Statementstat=conn.createStatement();ResultSetrs=stat.executeQuery(qs);System.out.println("Username;UserID;Attributes");while(rs.next()){System.out.println(rs.getString("Username")+";"+rs.getLong("UserID")+";"+rs.getString("Attributes"));}rs.close();stat.close();}catch(Exceptione2){System.err.println("connectingfailed");System.err.println(e2);System.exit(1);}System.out.println("connectionclosed");//IfwegethereallisOKSystem.out.println("done.");}}在上面的代码中,一旦有一个Connection实例,它就定义了一个查询字符串(注意[4]上面),创建一个Statement实例并用它来执行查询字符串,然后将结果放入一个ResultSet实例中。程序可以遍历ResultSet实例分析返回的结果,最后关闭ResultSet和Statement实例(注[5])。编译和执行该程序会产生以下输出:16395;superuservax;197772;mbe;290995;aca;169248;connectionclosedone.me@mymachine:~/Test$这是在简单Java应用程序中使用PostgreSQLJDBC库的(非常简单的)示例。请注意,由于java.sql库的设计方式,它不需要像importorg.postgresql.jdbc.*;这样的Java导入语句。在代码中,而是使用Java类加载器在运行时引入PostgreSQL代码,这就是代码编译时不需要指定类路径的原因。