Chapter 5. JDBC 接口
Table of Contents
5.1. 设置 JDBC 驱动
5.1.1. 获取驱动
5.1.2. 设置类路径
5.1.3. 为 JDBC准备数据库
5.2. 使用驱动
5.2.1. 装入 JDBC
5.2.2. 装载驱动
5.2.3. 与数据库联接
5.2.4. 关闭联接
5.3. 发出查询和处理结果
5.3.1. 使用 Statement或 PreparedStatement 接口
5.3.2. 使用ResultSet(结果集)接口
5.4. 执行更新
5.5. 创建和更改数据库对象
5.6. 存储二进制数据
5.7. PostgreSQL 对 JDBC API的扩展
5.7.1. 访问这些扩展
5.7.2. 几何数据类型
5.7.3. 大对象
5.8. 在一个多 Threaded (线程) 或 Servlet (服务器小应用)环境里使用驱动
5.9. 连接池和 DataSources
5.9.1. JDBC,JDK 版本支持
5.9.2. JDBC 连接池 API
5.9.3. 应用服务器:ConnectionPoolDataSource
5.9.4. 应用:DataSource
5.9.5. DataSources 和 JNDI
5.9.6. 特定的应用服务器配置
5.10. 深入阅读
作者: 最初由 Peter T. Mount (<peter@retep.org.uk>)执笔,他是 JDBC 驱动最初的作者.
JDBC 是 Java 1.1 及以后的核心 API. 它为 SQL 兼容的数据库提供了一个标准的接口集合.
PostgreSQL 提供了 类型 4 JDBC 驱动. 类型 4 表明该驱动是用纯 Java 书写的,并且与数据库之间使用数据库自己的网 络协议通讯.因此,驱动是平台无关的.一旦编译,该驱动可以用于任意平台.
本章并不想作为完整的 JDBC 编程的指导,但应该能帮你走出第一步. 更多信息请参考标准 JDBC API 文档. 同样,读一下包含在源代码里的例子.其中的基本例子在这里使用.
5.1. 设置 JDBC 驱动
5.1.1. 获取驱动
预编译好的驱动通常可以在 PostgreSQL JDBC 站点 找到.
另外你可以直接从源程序中制作驱动.尽管你只有在自己改动了驱动的代码 情况下才需要这么做。 相关的细节请参考PostgreSQL安装指导。在安装完成后,驱动应该在 PREFIX/share/java/postgresql.jar。 生成的驱动应该是为你运行的 Java 版本制作的。如果你用 1.1 JDK 制作, 那么你制作了一愕支持 JDBC 1 规范的驱动,如果你用 Java 2 JDK(比如, JDK 1.2 或者 JDK 1.3),你将制作一个支持 JDBC 2 规范的版本。
5.1.2. 设置类路径
要使用驱动,它的 JAR 归档 (如果你从源程序制作,那么名字叫 postgresql.jar,否则它很可能叫 jdbc7.2-1.1.jar 或 jdbc7.2-1.2.jar -- 分别用于 jdbc1 和 jdbc2) 必须包含在类路径里,你要么是把路径放到 CLASSPATH 环境变量里,要么是使用 java 命令行上的标记.
比如,我有一个使用 JDBC 驱动的应用,该应用访问一个存有天文对象的大数据库. 我的应用已经写好了,并且 JDBC 驱动 安装在 /usr/local/lib 目录,而 Java JDK 安装在 /usr/local/jdk1.3.1.要运行应用, 我可以用∶
export CLASSPATH=/usr/local/lib/finder.jar(1):/usr/local/pgsql/share/java/postgresql.jar:.
java uk.org.retep.finder.Main
(1)
finder.jar 里面包含 Finder 应用.
在应用里装载驱动的内容在 Section 5.2 里介绍.
5.1.3. 为 JDBC准备数据库
因为 Java 只使用 TCP/IP 联接, 所以 PostgreSQL服务器 必须配置成接受 TCP/IP 联接,我们可以通过在 postgresql.conf 文件里设置 tcpip_socket = true 或者启动 postmaster 的时候 带-i参数实现这个目地.
同样,在 pg_hba.conf 文件里的 客户端认证设置也要配置好. 请参考管理员手册获取细节. JDBC 驱动支持 trust,ident,password, md5 和 crypt 认证方式.
5.2. 使用驱动
5.2.1. 装入 JDBC
任何使用 JDBC 的源程序 都需要输入 java.sql 包,用:
import java.sql.*;
Important: 不要输入 postgresql 包.如果这样做,你的源码将不能编译, 因为 javac 会被你搞糊涂。
5.2.2. 装载驱动
在你试图与数据库连接之前,你需要装载驱动. 有两种方法,那种更好取决于你使用的代码.
在第一种方法里,你的代码用 Class.forName() 方法显式装载驱动.对于 PostgreSQL,你要用:
Class.forName("org.postgresql.Driver");
这样将装载驱动,并且在装载时,驱动将自动与 JDBC 注册自己.
注意: forName() 方法可能抛出一个 ClassNotFoundException ,所以如果驱动不可获得时你需要捕获它.
这是最常用的方法,但是把你的代码限制于 PostgreSQL 专用. 如果你的代码以后还要访问其他数据库,并且你不想使用 任何 PostgreSQL 相关的扩展, 那么还有第二种方法可用.
第二种方法把驱动做为参数在 JVM启动时传递给它,使用 -D参数.比如:
java -Djdbc.drivers=org.postgresql.Driver example.ImageViewer
在这个例子里, JVM将试图把驱动作为它的初始化的一部分装载. 一旦完成,启动ImageViewer。
现在这个方法更好一点,因为它允许你的代码用于其他数据库, 而不用重新编译代码.唯一要修改的东西是 URL,我们下面要提到.
最后一件事情.当你的代码试图打开一个Connection, 而你收到一个抛出的 No driver available SQLException 例外,这可能是因为驱动不在 class path (类路径)里,或者参数值不正确.
5.2.3. 与数据库联接
在 JDBC 里,数据库是用URL (Uniform Resource Locator)(统一资源定位器)表示的. 在 PostgreSQL里, 这可以由下面几种格式之一表示:
*
jdbc:postgresql:database
*
jdbc:postgresql://host/database
*
jdbc:postgresql://host:port/database
这里:
host
服务器的主机名.缺省是 "localhost".
port
服务器监听的端口号. 缺省时是PostgreSQL标准的端口号(5432).
database
数据库名.
要联接(数据库),你需要从 JDBC获取一个 Connection 实例. 要做这些,你要使用 DriverManager.getConnection()方法:
Connection db = DriverManager.getConnection(url, username, password);
5.2.4. 关闭联接
要关闭数据库联接,只需要对 Connection 调用 close()方法:
db.close();
5.3. 发出查询和处理结果
在任何你想向数据库运行一个SQL语句的时候, 你都需要一个Statement 或 PreparedStatement 实例. 一旦你拥有了一个Statement 或 PreparedStatement,你就可以 发出一个查询. 这样将返回一个ResultSet 实例, 在其内部包含整个结果. Example 5-1 演示了这个过程.
Example 5-1. 在 JDBC 里处理一个简单的查询
这个例子将发出一个简单的查询然后用一个 Statement打印出每行的第一个字段.
Statement st = db.createStatement();
ResultSet rs = st.executeQuery("SELECT * FROM mytable where columnfoo = 500");
while(rs.next()) {
System.out.print("Column 1 returned ");
System.out.println(rs.getString(1));
}
rs.close();
st.close();
这个例子将使用 PreparedStatement 发出和前面一样的查询,并且在查询中制作数值.
int foovalue = 500;
PreparedStatement st = db.prepareStatement("SELECT * FROM mytable where columnfoo = ?");
st.setInt(1, foovalue);
ResultSet rs = st.executeQuery();
while(rs.next()) {
System.out.print("Column 1 returned ");
System.out.println(rs.getString(1));
}
rs.close();
st.close();
5.3.1. 使用 Statement或 PreparedStatement 接口
在使用Statement或 PreparedStatement接口时必须考虑下面的问题:
*
你可以将一个Statement或 PreparedStatement实例使用任意次. 你可以在打开一个联接后马上创建一个Statement 实例, 并且在联接的生存期里使用之. 你必须记住每个Statement或 PreparedStatement只能存在一个 ResultSet.
*
如果你需要在处理一个ResultSet的时候执行一个查询, 你只需要创建并且使用另外一个Statement.
*
如果你使用了 threads (线程),并且有几个使用数据库, 你对每个线程必须使用一个独立的Statement. 如果考虑使用线程, 请参考本文档稍后的 Section 5.8 章节, 因为这些内容包含一些重要的信息.
*
在你用完 Statement 或者 PreparedStatement 之后,你应该关闭它.
5.3.2. 使用ResultSet(结果集)接口
使用ResultSet接口时必须考虑下面的问题:
*
在读取任何数值的时候,你必须调用next(). 如果还有结果则返回真(true),但更重要的是,它为处理准备了数据行.
*
在 JDBC 规范里,你对一个字段应该只访问一次. 遵循这个规则是最安全的,不过目前 PostgreSQL 驱动将允许你对一个字段访问任意次.
*
一旦你结束对一个 ResultSet 的处理,你必须对之调用 close()来关闭它。
*
一旦你使用那个创建ResultSet的 Statement做另一个查询请求, 当前打开的 ResultSet 实例将自动关闭.
*
目前的 ResultSet 是只读的. 你不能通过 ResultSet 来更新数据. 如果你想更新数据,那么你就需要使用老式的风格来做它∶ 通过发出一条 SQL 更新语句.这么做是和 JDBC 规范兼容的,它并不要求驱动提供这个功能.
5.4. 执行更新
要改变数据(执行一个插入,更新或者删除操作),你要使用 executeUpdate() 方法. executeUpdate() 类似用于发出 select 的 executeQuery(),不过,它不返回 ResultSet,它返回的是插入,更新或者删除语句 影响的记录数.
Example 5-2. 简单的删除例子
这个例子将发出一个简单的删除并打印出删除的行数.
int foovalue = 500;
PreparedStatement st = db.prepareStatement("DELETE FROM mytable where columnfoo = ?");
st.setInt(1, foovalue);
int rowsDeleted = st.executeUpdate();
System.out.println(rowsDeleted + " rows deleted");
st.close();
5.5. 创建和更改数据库对象
要创建,更改或者删除一个类似表或者视图这样的数据库对象, 你要使用 execute() 方法. execute 类似于用于发出 select 的 executeQuery(),不过它不返回结果.
Example 5-3. 删除表的例子
这个例子删除一个表.
Statement st = db.createStatement();
ResultSet rs = st.executeQuery("DROP TABLE mytable");
st.close();
5.6. 存储二进制数据
PostgreSQL 提供两种不同的方法存储二进制数据. 二进制数据可以使用PostgreSQL的二进制数据类型 bytea存储在表中,或者使用大对象 特性,该特性以一种特殊的格式将二进制数据存储在一个独立的表中, 然后通过在你的表中保存一个指向该表的类型为 OID 的数值 来引用它.
为了判断那种方法比较合适,你必须理解每种方法的局限. bytea 数据类型并不适合存储非常大数量的二进制数据. 虽然类型为 bytea 的字段可以存储最多 1G 字节的二进制数据, 但是这样它会要求数量巨大的内存(RAM)来处理这样巨大 的数值.存储二进制的大对象的方法更适合存储非常大的数值, 但也有自己的局限.特别是删除一个包含大对象的行并未删除大对象. 删除大对象是一个需要处理的独立的操作.大对象还有一些安全性的问题, 因为人和联接到数据库的人都可以查看或者更改大对象,即使他们 没有查看/更新包含大对象的行的权限也一样.
7.2 是第一个支持 bytea 类型的 JDBC 驱动版本.在 7.2 中引入的这个功能同时也引入了一个和以往的版本不同的 行为.在 7.2 里,方法 getBytes(), setBytes(), getBinaryStream() 和 setBinaryStream() 操作 bytea 类型. 在 7.1 里这些方法操作和 OID 类型关联的大对象. 我们可以通过在 Connection 上设置 compatible 为数值 7.1 来获取旧的 7.1 的行为.
要使用 bytea 数据类型你只需要使用 getBytes(),setBytes(), getBinaryStream(),或者 setBinaryStream() 方法.
要使用大对象的功能,你可以使用 PostgreSQL JDBC 驱动提供的 LargeObject API,或者使用 getBLOB() 和 setBLOB() 方法.
Important: 对于 PostgreSQL 而言,你必须在 一次 SQL 事务内访问大对象.你应该使用 带 false 输入参数的 setAutoCommit() 方法打开一个事务.
注意: 在将来的 JDBC 驱动中, getBLOB() 和 setBLOB() 方法可能不再操作大对象,而是将处理 bytea 数据类型. 因此如果你要用大对象,我们建议你使用 LargeObject API.
Example 5-4. 二进制数据例子
比如,假设你有一个表包含一幅图像和它的文件名, 并且你还想在 bytea 字段里存储图像∶
CREATE TABLE images (imgname text, img bytea);
要插入一幅图象,你可以:
File file = new File("myimage.gif");
FileInputStream fis = new FileInputStream(file);
PreparedStatement ps = conn.prepareStatement("INSERT INTO images VALUES (?, ?)");
ps.setString(1, file.getName());
ps.setBinaryStream(2, fis, file.length());
ps.executeUpdate();
ps.close();
fis.close();
这里,setBinaryStream() 把来自一个流的 一些数目的字节转换成类型 bytea 的字段. 如果图像的内容已经放在 byte[] 里面了, 那么你也可以用 setBytes() 方法干这件事.
检索一幅图象甚至更容易(我在这里使用PreparedStatement,当然用Statement也是一样的):
PreparedStatement ps = con.prepareStatement("SELECT img FROM images WHERE imgname=?");
ps.setString(1, "myimage.gif");
ResultSet rs = ps.executeQuery();
if (rs != null) {
while(rs.next()) {
byte[] imgBytes = rs.getBytes(1);
// use the stream in some way here
}
rs.close();
}
ps.close();
这里的二进制数据是以 byte[] 形式检索的.你也可以使用一个 InputStream.
另外你可能会需要存储一个非常大的文件,因此希望使用 LargeObject API 存储该文件∶
CREATE TABLE imagesLO (imgname text, imgOID OID);
要插入一个图像,你可以用∶
// 所有大对象 API 调用都必须在一次事务中
conn.setAutoCommit(false);
// 获取大对象管理器以便进行操作
LargeObjectManager lobj = ((org.postgresql.PGConnection)conn).getLargeObjectAPI();
//创建一个新的大对象
int oid = lobj.create(LargeObjectManager.READ | LargeObjectManager.WRITE);
//打开一个大对象进行写
LargeObject obj = lobj.open(oid, LargeObjectManager.WRITE);
// 现在打开文件
File file = new File("myimage.gif");
FileInputStream fis = new FileInputStream(file);
// 从文件拷贝数据到大对象
byte buf[] = new byte[2048];
int s, tl = 0;
while ((s = fis.read(buf, 0, 2048)) > 0)
{
obj.write(buf, 0, s);
tl += s;
}
// 关闭大对象
obj.close();
//现在向 imgesLO 插入行
PreparedStatement ps = conn.prepareStatement("INSERT INTO imagesLO VALUES (?,?)");
ps.setString(1, file.getName());
ps.setInt(2, oid);
ps.executeUpdate();
ps.close();
fis.close();
从大对象中检索图像∶
// 所有 LargeObject API 调用都必须在一个事务里
conn.setAutoCommit(false);
// 获取大对象管理器以便进行操作
LargeObjectManager lobj = ((org.postgresql.PGConnection)conn).getLargeObjectAPI();
PreparedStatement ps = con.prepareStatement("SELECT imgOID FROM imagesLO WHERE imgname=?");
ps.setString(1, "myimage.gif");
ResultSet rs = ps.executeQuery();
if (rs != null) {
while(rs.next()) {
//打开大对象读
int oid = rs.getInt(1);
LargeObject obj = lobj.open(oid, LargeObjectManager.READ);
//读取数据
byte buf[] = new byte[obj.size()];
obj.read(buf, 0, obj.size());
//在这里对读取的数据做些处理
// 关闭对象
obj.close();
}
rs.close();
}
ps.close();
5.7. PostgreSQL 对 JDBC API的扩展
PostgreSQL 是一种可扩展的数据库系统. 你可以向数据库后端里增加你自己的函数,这些函数可以供查询调用, 甚至你可以增加你自己的数据类型.因为这些是 PostgreSQL 特有的功能,因此我们在 Java 里面支持它们,同时还带着一套扩展的 API.在标准驱动的核心里实际上使用了这些扩展 来实现大对象等等.
5.7.1. 访问这些扩展
要获得某些扩展,你需要使用 org.postgresql.PGConnection 类里的一些额外的方法,这时,你需要转换 Driver.getConnection() 的返回值.比如∶
Connection db = Driver.getConnection(url, username, password);
// ...
// 稍后
Fastpath fp = ((org.postgresql.PGConnection)db).getFastpathAPI();
5.7.1.1. 类 org.postgresql.PGConnection
public class PGConnection
这些是用于获取 PostgreSQL 的扩展 的额外的方法.
5.7.1.1.1. 方法
*
public Fastpath getFastpathAPI() throws SQLException
这个方法为当前联接返回 Fastpath API. 主要用于大对象API.
使用这个方法的最好方式是∶
import org.postgresql.fastpath.*;
...
Fastpath fp = ((org.postgresql.PGConnection)myconn).getFastpathAPI();
这里的myconn是一个已经打开的与 PostgreSQL 的Connection.
返回∶. 一个可以用来访问 PostgreSQL 后端里面的函数的 Fastpath 对象.
抛出∶. 在第一次初始化的时候 Fastpath 抛出的SQLException。
*
public LargeObjectManager getLargeObjectAPI() throws SQLException
这个方法为当前联接返回一个大对象 API.
使用这个方法的最佳手段如下∶
import org.postgresql.largeobject.*;
...
LargeObjectManager lo = ((org.postgresql.PGConnection)myconn).getLargeObjectAPI();
这里的myconn是一个已经打开的与 PostgreSQL 的Connection.
返回∶. 实现大对象 API 的LargeObject对象.
抛出∶. 在第一次初始化的时候LargeObject抛出的 SQLException.
*
public void addDataType(String type, String name)
这个方法允许客户端代码为PostgreSQL中比较独特的数据类型 加一个句柄.通常,驱动器不认识的数据类型是由 ResultSet.getObject() 以一个PGobject实例的形式返回的. 这个方法允许你写一个扩展PGobject 的类,然后告诉驱动该类型名子,以及要使用的类名子. 这个方法的缺点是,每次你建立新联接的时候,你都要调用这个方法.
使用这个用法的最佳手段是:
...
((org.postgresql.PGConnection)myconn).addDataType("mytype","my.class.name");
...
这里的myconn是一个已经打开的与 PostgreSQL 的Connection.做控制的类必须扩展 org.postgresql.util.PGobject.
5.7.1.2. 类 org.postgresql.Fastpath
public class Fastpath extends Object
java.lang.Object
|
+----org.postgresql.fastpath.Fastpath
Fastpath是一套存在于libpqC 接口里的 API , 并且这个接口允许客户机器执行后端数据库的函数. 大多数客户端代码不需要使用这个方法,但是我们还是提供这个方法, 因为大对象 API 使用它.
要使用这个扩展,你需要输入 postgresql.fastpath包,使用下面行:
import org.postgresql.fastpath.*;
然后,在你的代码里,你需要获取一个FastPath对象:
Fastpath fp = ((org.postgresql.PGConnection)conn).getFastpathAPI();
这样将返回一个实例,该实例与你发出命令的数据库联接相关联. 必须把Connection转换成 org.postgresql.PGConnection, 因为getFastpathAPI()是我们自己的方法之一,而不是 JDBC的. 一旦你拥有了 Fastpath 实例, 你就可以使用 fastpath() 方法执行一个后端函数.
又见∶. FastpathFastpathArg, LargeObject
5.7.1.2.1. 方法
*
public Object fastpath(int fnid,
boolean resulttype,
FastpathArg args[]) throws SQLException
向PostgreSQL后端发送一个函数调用.
参数∶. fnid - 函数 id resulttype - 如果结果为整数则为真,如果为其它则为假 args - 传递给 fastpath 的 FastpathArguments
返回∶. 如果没有数据返回空(null), 如果结果为整数返回一个Integer, 否则返回 byte[]
*
public Object fastpath(String name,
boolean resulttype,
FastpathArg args[]) throws SQLException
通过名字向PostgreSQL后端发送一个函数调用.
注意: 函数名到函数 id 的映射必须存在, 通常先调用 addfunction(). 这是调用函数的优选方法,因为函数 id 在不同版本的后端里是会/可能改变的. 这个方法工作的例子,可以参阅 org.postgresql.LargeObject.
参数∶. name - 函数名称 resulttype - 如果结果是整数返回真 (true), 其他结果返回假 (false) args - 传递给 fastpath 的参数FastpathArguments
返回∶. 如果没有数据返回空 (null), 如果结果为整数返回一个 Integer, 否则返回 byte[]
又见∶. LargeObject
*
public int getInteger(String name,
FastpathArg args[]) throws SQLException
这个便利方法假设返回值是一个 Integer (整数)
参数∶. name - 函数名 args - 函数参数
返回∶. 整数结果
抛出∶. 如果发生了数据库访问错误或者没有结果抛出 SQLException.
*
public byte[] getData(String name,
FastpathArg args[]) throws SQLException
这个便利方法假设返回值是二进制数据
参数∶. name - 函数名 args - 函数参数
返回∶. 包含结果的 byte[] 数组
抛出∶. 如果发生了数据库访问错误或者没有结果抛出SQLException?
*
public void addFunction(String name,
int fnid)
这个方法向我们的(函数)检索表里增加一个函数. 用户代码应该使用addFunctions方法, 因为这个方法基于一个查询, 而不是 OID 硬代码.我们不保证一个函数的 OID 是静态的, 甚至运行在不同服务器的同版本的数据库也不能保证是静态的.
*
public void addFunctions(ResultSet rs) throws SQLException
这个方法接收一个包含两个字段的ResultSet. 字段 1 包含函数名, 字段 2 是 OID. 它读取整个ResultSet,把值装载入函数表.
Important: 调用完这个方法后记得用close()关闭 ResultSet!!
关于函数名查找实现的信息: PostgreSQL 在pg_proc表里存储函数 id 和它们对应的名称, 在查找时不是从该表里查询每个所需函数的名称, 而是使用了一个Hashtable (散列表). 同样,只有需要的函数的名称才放到这个表里,以保证连接速度尽可能快.
org.postgresql.LargeObject 类在启动时执行一个查询, 并且把返回的 ResultSet 传递给这里提到的 addFunctions()方法. 一旦这些工作完成,LargeObjectAPI就用名称引用函数.
不要以为手工把它们转换成 OID 就可以了. 的确,目前这样做是可以用的,但随着开发的进行这些可能被修改 (在 V7.0 版本的讨论中有一些关于这些的话题), 所以这样做是防止未来可能出现的任何不受保障的痛苦的手段.
又见∶. LargeObjectManager
*
public int getID(String name) throws SQLException
这个方法返回与函数名关联的函数 id, 如果还没有对这个函数名调用 addFunction()或 addFunctions(), 那么抛出一个SQLException.
5.7.1.3. 类 org.postgresql.fastpath.FastpathArg
public class FastpathArg extends Object
java.lang.Object
|
+----org.postgresql.fastpath.FastpathArg
每个 fastpath 调用都需要一个参数列表,其数目和类型取决于被调用的函数. 这个类实现了提供这个功能所需要的方法.
关于如何使用这个方法的例子, 参阅 org.postgresql.LargeObject 包
又见∶. Fastpath, LargeObjectManager, LargeObject
5.7.1.3.1. 构造器
*
public FastpathArg(int value)
构造一个包含一个整数值的参数
参数∶. value - 待设置的 int (整数)值
*
public FastpathArg(byte bytes[])
构造一个包含一个字节数组的参数
参数∶. bytes - 要保存的数组
*
public FastpathArg(byte buf[],
int off,
int len)
构造一个包含一个数组的一部分的参数
参数∶.
buf
源数组
off
数组内的偏移量
len
要包括的数据的长度
*
public FastpathArg(String s)
构造一个字符串组成的参数.
5.7.2. 几何数据类型
PostgreSQL 有一个往表里存储几何特性的数据类型集. 范围包括点,线,和多边形. 我们通过 org.postgresql.geometric 包在 Java 里支持这些类型. 它包括扩展了 org.postgresql.util.PGobject 类的类. 参考该类获取如何实现你自己的数据类型的控制器的细节.
Class org.postgresql.geometric.PGbox
java.lang.Object
|
+----org.postgresql.util.PGobject
|
+----org.postgresql.geometric.PGbox
public class PGbox extends PGobject implements Serializable,
Cloneable
这个类在PostgreSQL里表示盒子 (box) 数据类型.
变量
public PGpoint point[]
这些是盒子的两个对角点.
构造器
public PGbox(double x1,
double y1,
double x2,
double y2)
参数∶
x1 - 第一个 x 坐标
y1 - 第一个 y 坐标
x2 - 第二个 x 坐标
y2 - 第二个 y 坐标
public PGbox(PGpoint p1,
PGpoint p2)
参数∶
p1 - 第一个点
p2 - 第二个点
public PGbox(String s) throws SQLException
参数∶
s -PostgreSQL语法里的盒子定义
抛出∶ SQLException
如果定义非法
public PGbox()
必须的构造(方法)
方法
public void setValue(String value) throws SQLException
这个方法设置这个对象的值.它应该被重载,但是仍然被子类调用.
参数∶
value - 一个代表对象值的字符串
抛出∶ SQLException
如果此数值对这个类型而言是非法的
覆盖∶
类 PGobject 里的 setValue
public boolean equals(Object obj)
参数∶
obj - 要比较的对象
返回∶
如果两个盒子相等返回真 (true)
覆盖∶
类 PGobject 里的 equals
public Object clone()
必须覆盖这个方法以允许对象被克隆 (cloned)
覆盖∶
类 PGobject 里的 equals
public String getValue()
返回∶
PostgreSQL句法需要的 PGbox
覆盖∶
getValue in class PGobject
Class org.postgresql.geometric.PGcircle
java.lang.Object
|
+----org.postgresql.util.PGobject
|
+----org.postgresql.geometric.PGcircle
public class PGcircle extends PGobject implements Serializable,
Cloneable
这个类代表 PostgreSQL 的圆数据类型,由一个点和一个半径组成
变量
public PGpoint center
这是圆心
double radius
这是半径
构造器
public PGcircle(double x,
double y,
double r)
参数∶
x - 圆心坐标
y - 圆心坐标
r - 圆半径
public PGcircle(PGpoint c,
double r)
参数∶
c - 描述圆心的 PGpoint
r - 圆半径
public PGcircle(String s) throws SQLException
参数∶
s -PostgreSQL里语法定义的圆.
抛出∶ SQLException
如果转换失败
public PGcircle()
这个构造(方法)被驱动器使用.
方法
public void setValue(String s) throws SQLException
参数∶
s - 用PostgreSQL的语法定义的圆.
抛出∶ SQLException
如果转换失败
覆盖∶
类 PGobject 里的 setValue
public boolean equals(Object obj)
参数∶
obj - 要对比的对象
返回∶
如果两个圆相同返回真 (true)
覆盖∶
类 PGobject 里的 equals
public Object clone()
必须重载这个方法以便允许对象被克隆 (cloned)
覆盖∶
类 PGobject 里的 clone
public String getValue()
返回∶
PostgreSQL 语法里的 PGcircle 字串
覆盖∶
PGobject 里的 getValue
Class org.postgresql.geometric.PGline
java.lang.Object
|
+----org.postgresql.util.PGobject
|
+----org.postgresql.geometric.PGline
public class PGline extends PGobject implements Serializable,
Cloneable
这个类实现由两个点组成的线.目前线还没有在后端实现,
但这个类保证在后端实现后即可使用(线).
变量
public PGpoint point[]
这是两个点.
构造器
public PGline(double x1,
double y1,
double x2,
double y2)
参数∶
x1 - 第一个点的x坐标
y1 - 第一个点的y坐标
x2 - 第二个点的x坐标
y2 - 第二个点的y坐标
public PGline(PGpoint p1,
PGpoint p2)
参数∶
p1 - 第一个点
p2 - 第二个点
public PGline(String s) throws SQLException
参数∶
s -PostgreSQL语法定义的点.
抛出∶ SQLException
当发生转换错误时
public PGline()
驱动需要
方法
public void setValue(String s) throws SQLException
参数∶
s -PostgreSQL里语法的线段的定义
抛出∶ SQLException
当发生转换错误时
覆盖∶
类 PGobject 里的 setValue
public boolean equals(Object obj)
参数∶
obj - 要比较的对象
返回∶
如果两条线段相同返回真 (true)
覆盖∶
类 PGobject 里的 equals
public Object clone()
这个方法必须被重载以便允许这个对象可以被克隆
覆盖∶
类 PGobject 里的 clone
public String getValue()
返回∶
PostgreSQL 语法里的 PGline
覆盖∶
类 PGobject 里的 getValue
Class org.postgresql.geometric.PGlseg
java.lang.Object
|
+----org.postgresql.util.PGobject
|
+----org.postgresql.geometric.PGlseg
public class PGlseg extends PGobject implements Serializable,
Cloneable
这样实现了一条包含两个点的 lseg (线段)
变量
public PGpoint point[]
这里是两个点
构造器
public PGlseg(double x1,
double y1,
double x2,
double y2)
参数∶
x1 - 第一个点的x坐标
y1 - 第一个点的y坐标
x2 - 第二个点的x坐标
y2 - 第二个点的y坐标
public PGlseg(PGpoint p1,
PGpoint p2)
参数∶
p1 - 第一个点
p2 - 第二个点
public PGlseg(String s) throws SQLException
参数∶
s -PostgreSQL里语法对线段定义的字串.
抛出∶ SQLException
在发生转换错误时
public PGlseg()
驱动要求
方法
public void setValue(String s) throws SQLException
参数∶
s -PostgreSQL里语法对线段定义的字串
抛出∶ SQLException
在发生转换错误时
覆盖∶
类 PGobject 里的 setValue
public boolean equals(Object obj)
参数∶
obj - 要比较的对象
返回∶
如果两条线段相等
覆盖∶
类 PGobject 里的 equals
public Object clone()
必须覆盖这个方法以便允许这个对象被克隆
覆盖∶
类 PGobject 里的 getValue
public String getValue()
返回∶
PostgreSQL 语法里的 PGlseg
覆盖∶
类 PGobject 里的 getValue
Class org.postgresql.geometric.PGpath
java.lang.Object
|
+----org.postgresql.util.PGobject
|
+----org.postgresql.geometric.PGpath
public class PGpath extends PGobject implements Serializable,
Cloneable
这是路径( 多线段图形, 可以为封闭的 )的实现
变量
public boolean open
如果路径开放时为真 (True),为封闭时为假
public PGpoint points[]
定义路径的点
构造器
public PGpath(PGpoint points[],
boolean open)
参数∶
points - 定义路径的 PGpoints
open - 如果路径是开放的为真 (True),封闭为假 (false)
public PGpath()
驱动需要
public PGpath(String s) throws SQLException
参数∶
s -PostgreSQL的语法定义的路径.
抛出∶ SQLException
在发生转换错误时
方法
public void setValue(String s) throws SQLException
参数∶
s -PostgreSQL的语法定义的路径的字串
抛出∶ SQLException
在发生转换失败时
覆盖∶
类 PGobject 里的 setValue
public boolean equals(Object obj)
参数∶
obj - 要比较的对象
返回∶
如果两个路径相同返回真 (true)
覆盖∶
类 PGobject 里的 equals
public Object clone()
必须覆盖这个方法以便允许这个对象被克隆
覆盖∶
clone in class PGobject
public String getValue()
这个方法返回PostgreSQL语法的多边形
覆盖∶
类 PGobject 里的 getValue
public boolean isOpen()
如果路径是开放的这个方法返回真 (true)
public boolean isClosed()
如果路径是封闭的这个方法返回真 (true)
public void closePath()
标记路径为封闭
public void openPath()
标记路径为开放
Class org.postgresql.geometric.PGpoint
java.lang.Object
|
+----org.postgresql.util.PGobject
|
+----org.postgresql.geometric.PGpoint
public class PGpoint extends PGobject implements Serializable,
Cloneable
这个类实现了 java.awt.Point 的一个版本,但用 double 表示参数.
它对应于 PostgreSQL 里的 point 数据类型.
变量
public double x
点的 X 坐标
public double y
点的 Y 坐标
构造器
public PGpoint(double x,
double y)
参数∶
x - 坐标
y - 坐标
public PGpoint(String value) throws SQLException
这个方法主要从其他几何类型调用 -- 当一个点嵌入它们的定义中时.
参数∶
value -PostgreSQL语法定义的点
public PGpoint()
驱动需要
方法
public void setValue(String s) throws SQLException
参数∶
s -PostgreSQL语法定义的点
抛出∶ SQLException
在转换失败时
覆盖∶
类 PGobject 里的 setValue
public boolean equals(Object obj)
参数∶
obj - 要比较的对象
返回∶
如果两个对象相同返回真 (true)
覆盖∶
类 PGobject 里的 equals
public Object clone()
必须覆盖这个方法以便允许这个对象被克隆
覆盖∶
类 PGobject 里的 clone
public String getValue()
返回∶
PostgreSQL里语法 PGpoint 的表示.
覆盖∶
类 PGobject 里的 getValue
public void translate(int x,
int y)
对点做指定数量的转换(位移).
参数∶
x - 向 x 轴增加的整型数量
y - 向 y 轴增加的整型数量
public void translate(double x,
double y)
对点做指定数量的转换(位移).
参数∶
x - 向 x 轴增加的双精度型数量
y - 向 y 轴增加的双精度型数量
public void move(int x,
int y)
把点移到指定坐标.
参数∶
x - 整数坐标
y - 整数坐标
public void move(double x,
double y)
把点移到指定坐标.
参数∶
x - 双精度坐标
y - 双精度坐标
public void setLocation(int x,
int y)
把点移到指定坐标. 参考
java.awt.Point 获取这个方法的描述信息
参数∶
x - 整数坐标
y - 整数坐标
又见∶
Point
public void setLocation(Point p)
把点移到指定坐标. 参考
java.awt.Point 获取这个方法的描述信息
参数∶
p - 移动的目的点 (Point)
又见∶
Point
Class org.postgresql.geometric.PGpolygon
java.lang.Object
|
+----org.postgresql.util.PGobject
|
+----org.postgresql.geometric.PGpolygon
public class PGpolygon extends PGobject implements Serializable,
Cloneable
这个类在PostgreSQL里实现了 polygon (多边形)数据类型.
变量
public PGpoint points[]
定义 polygon (多边形)的点
构造器
public PGpolygon(PGpoint points[])
使用一个 PGpoints 数组创建一个多边形
参数∶
points - 定义多边形 polygon 的点
public PGpolygon(String s) throws SQLException
参数∶
s - 用PostgreSQL语法定义的多边形.
抛出∶ SQLException
在转换失败时
public PGpolygon()
驱动需要
方法
public void setValue(String s) throws SQLException
参数∶
s - 用PostgreSQL语法定义的多边形.
抛出∶ SQLException
在转换失败时
覆盖∶
类 PGobject 里的 setValue
public boolean equals(Object obj)
参数∶
obj - 要比较的对象
返回∶
如果两个对象相同返回真 (true)
覆盖∶
类 PGobject 里的 equals
public Object clone()
必须覆盖这个方法以便允许这个对象被克隆
覆盖∶
类 PGobject 里的 clone
public String getValue()
返回∶
PostgreSQL里语法表示的 PGpolygon.
覆盖∶
类 PGobject 里的 getValue
5.7.3. 大对象
标准的 JDBC 规范里也支持大对象. 但是,那个接口有一些限制, 而PostgreSQL提供的 API 允许对对象内容的随机访问, 就象那是一个本地文件一样.
org.postgresql.largeobject 包为 Java 提供了libpqC 接口的大对象 API.它包含两个类, LargeObjectManager, 处理创建,打开和删除大对象的任务;以及 LargeObject,处理独立的对象.
5.7.3.1. 类org.postgresql.largeobject.LargeObject
public class LargeObject extends Object
java.lang.Object
|
+----org.postgresql.largeobject.LargeObject
这个类实现PostgreSQL的大对象接口.
它提供运行接口的基本的方法,另外还有一对方法为此对象提供 InputStream 和 OutputStream类.
通常,客户端代码将使用在 BLOB 里的方法 访问大对象.
但是,有时候需要低层次的大对象访问方法,那是 JDBC 规范还不支持的.
参考 org.postgresql.largeobject.LargeObjectManager 获取如何访问大对象和如何创建大对象的信息.
又见∶. LargeObjectManager
5.7.3.1.1. 变量
public static final int SEEK_SET
标识从一个文件的开头进行一次搜索
public static final int SEEK_CUR
标识从当前位置进行一次搜索
public static final int SEEK_END
标识从一个文件的结尾进行一次搜索
5.7.3.1.2. 方法
*
public int getOID()
返回这个 LargeObject 的 OID.
*
public void close() throws SQLException
这个方法关闭对象,在调用这个方法后你不能调用这个对象里的任何方法.
*
public byte[] read(int len) throws SQLException
从对象读取一些数据, 并且做为 byte[] 数组返回
*
public int read(byte buf[],
int off,
int len) throws SQLException
从对象读取一些数据到现有数组
参数∶.
buf
目的数组
off
数组内偏移量
len
读取的字节数
*
public void write(byte buf[]) throws SQLException
向对象里写入一个数组
*
public void write(byte buf[],
int off,
int len) throws SQLException
从数组里写一些数据到对象
参数∶.
buf
目标数组
off
数组内偏移量
len
写入字节数
5.7.3.2. 类org.postgresql.largeobject.LargeObjectManager
public class LargeObjectManager extends Object
java.lang.Object
|
+----org.postgresql.largeobject.LargeObjectManager
这个类型实现了PostgreSQL的大对象接口. 它提供了允许客户代码从数据库里创建,打开和删除大对象的方法. 在打开一个对象时,返回一个 postgresql.largeobject.LargeObject的实例, 然后它的方法就可以访问该对象.
这个类只能由 org.postgresql.PGConnection 创建 要访问这个类,使用下面的代码片段:
import org.postgresql.largeobject.*;
Connection conn;
LargeObjectManager lobj;
// ... 打开一个连接的代码 ...
lobj = ((org.postgresql.PGConnection)myconn).getLargeObjectAPI();
通常, 客户代码要使用 BLOB 方法访问大对象. 但是,有时候需要低层次的大对象访问方法,那是 JDBC 规范还不支持的.
请参考 org.postgresql.largeobject.LargeObject 获取如何控制大对象内容的信息.
5.7.3.2.1. 变量
public static final int WRITE
这个模式表明我们要写入大对象
public static final int READ
这个模式表明我们要读取大对象
public static final int READWRITE
这个模式是缺省的,表明我们要对大对象进行读和写的操作
5.7.3.2.2. 方法
*
public LargeObject open(int oid) throws SQLException
这个方法打开一个现有的大对象, 以其 OID 为基础. 这个方法假设 我们需要READ和WRITE访问模式 (缺省模式).
*
public LargeObject open(int oid,
int mode) throws SQLException
这个方法以其 OID 为基础打开一个现有的大对象. 并且允许设置访问模式.
*
public int create() throws SQLException
这个方法创建一个大对象, 返回它的 OID. 它把新创建的大对象模式设为缺省的READWRITE.
*
public int create(int mode) throws SQLException
这个方法创建一个大对象,返回它的 OID.并设置访问模式.
*
public void delete(int oid) throws SQLException
这个方法删除一个大对象.
*
public void unlink(int oid) throws SQLException
这个方法删除一个大对象.这个方法等同于 delete 方法, 并且作为类似使用"unlink"的 C API 出现.
5.8. 在一个多 Threaded (线程) 或 Servlet (服务器小应用)环境里使用驱动
许多 JDBC 驱动的一个共同问题是它们在任意时刻一个线程只能使用一个联接 Connection) - 否则可能一个在发送一个查询而另一个线程正在接受结果, 这个现象对数据库引擎是一个很糟糕的事情.
PostgreSQL JDBC 驱动都是线程安全的. 所以,如果你的应用要使用多线程, 那么你不必考虑任意时刻只允许一个线程使用数据库的复杂算法.
如果一个线程在其他线程正在使用数据库时试图访问数据库, 那么它将等到另一个线程完成当前操作之后进行. 如果这是一个普通的 SQL 语句, 那么该操作就是发送该语句, 并检索任何 ResultSet (完整的). 如果这是一个 Fastpath 调用 (例如: 从一个 LargeObject里读取一个数据块), 那么这时就发送, 和接收该数据块.
这对客户端的大小应用都很好, 但是可能造成服务器端小应用 (servlets) 的性能问题. 对于 servlets, 你可能会有很沉重的联接负荷. 如果你有好几个线程执行查询, 那么它们每个都暂停可不是你想看到的.
要解决这个问题, 我们建议你创建一个联接池. (pool of Connections) 当一个线程需要使用数据库, 它向管理类请求一个 Connection. 管理器赋予该线程一个空闲联接, 然后把它标记为忙. 如果没有空闲联接, 管理器就打开一个. 一旦线程完成数据库使用, 该线程把联接返回给管理器, 管理器既可以关闭该联接, 也可以把它加到联接池里. 管理器同样还检查联接是否仍然激活, 如果联接死亡了就把它从联接池删除.
所以, 对于服务器端小应用 ( servlets ), 选择单联接还是联接池是你的责任. 使用联接池的优点是线程不会成为单个网络联接的瓶颈. 缺点是这样做增加了服务器端 的负荷, 因为对每个Connection都要创建一个后端进程. 选择何种方式是你和你的应用的需求决定的.
5.9. 连接池和 DataSources
5.9.1. JDBC,JDK 版本支持
JDBC 2 以一个附加的 API 的方式引入了标准连接池的特性,这个 附加的 API 叫做 JDBC 2.0 可选包(也称作 JDBC 2.0 标准扩展)。因此这些特性就被包含到核心的 JDBC 3 API 中了。 PostgreSQL JDBC 驱动和 JDK 1.3.x 一起支持这些特性,以及 JDBC 2.0 可选包,或者是和 JDK 1.4+ (JDBC 3)一起,也支持这个特性。大多数应用服务器包含 JDBC 2.0 可选包,但我们也可以从 SUN 单独获得这些东西: JDBC下载站。
5.9.2. JDBC 连接池 API
JDBC API 为连接池提供了一个客户端和 一个服务器端的接口。客户端接口是 javax.sql.DataSource, 通常就是应用代码用来请求一个缓冲了的数据库连接的东西。 服务器接口是 javax.sql.ConnectionPoolDataSource, 通常是大多数应用服务器和 PostgreSQL JDBC 驱动打交道的接口。
在应用服务器环境里,应用服务器配置通常将指向 PostgreSQL ConnectionPoolDataSource 实现, 而应用组件代码将通常要求一个由应用服务器实现的 DataSource(不是由 PostgreSQL)。
在一个没有应用服务器的环境里,PostgreSQL 提供了 两种应用可以直接使用的 DataSource 的实现。 一种实现执行连接池,另外一种只是简单的通过 DataSource 接口 提供访问数据库的连接,而不使用任何缓冲池。同样,这些实现不应该 在一个应用服务器环境里使用,除非应用服务器不支持 ConnectionPoolDataSource 接口。
5.9.3. 应用服务器:ConnectionPoolDataSource
PostgreSQL 包含了一个用于 JDBC 2 的 ConnectionPoolDataSource 的实现,以及一个用于 JDBC 3 的实现:
Table 5-1. ConnectionPoolDataSource 实现
JDBC实现类
2org.postgresql.jdbc2.optional.ConnectionPool
3org.postgresql.jdbc3.Jdbc3ConnectionPool
两种实现都使用了同样的配置模式。JDBC 要求一个 ConnectionPoolDataSource 通过 JavaBean 属性来实现, 因此每个这样的属性都存在获取和设置方法:
Table 5-2. ConnectionPoolDataSource 配置属性
属性类型描述
serverNameStringPostgreSQL 数据库服务器主机名
databaseNameStringPostgreSQL 数据库名
portNumberintPostgreSQL 数据库服务器监听的 TCP/IP 端口 (为 0 则使用缺省端口)
userString用来进行数据库连接的用户
passwordString用来进行数据库连接的口令
defaultAutoCommitboolean提交给调用者的时候连接是应该打开 autoCommit 还是应该关闭。 缺省是 false,关闭 autoCommit。
许多应用服务器使用属性风格的语法来配置这些属性, 因此把属性当作一块文本输入应该并不罕见。
Example 5-5. ConnectionPoolDataSource 配置例子
如果应用服务器提供了单一的区域用于输入所有属性, 那么它们通常会象下面这样列出:
serverName=localhost
databaseName=test
user=testuser
password=testpassword
或者是用分号,而不是换行来分隔,象这样:
serverName=localhost;databaseName=test;user=testuser;password=testpassword
5.9.4. 应用:DataSource
PostgreSQL 包含两个用于 JDBC 2 的 DataSource,以及两个用于 JDBC 3的。 连接池的实现在客户端调用 close 方法的时候 实际上并不关闭连接,而是把连接返回到一个可用连接的连接池中 给其它客户端使用。这样就避免了任何重复打开和关闭连接造成的 开销,并且允许大量的客户端分享相对较少的数据库连接。
这里提供的连接池 datasource 实现并非世上特性最丰富的。 比如,连接在池本身关闭之前绝对不会关闭;而且也没有办法缩小连接池。 同样,非缺省配置的用户的连接请求无法如池。许多应用服务器提供 更加高级的连接池特性,并且使用的是 ConnectionPoolDataSource 实现。
Table 5-3. DataSource 实现
JDBC连接池实现类
2否org.postgresql.jdbc2.optional.SimpleDataSource
2是org.postgresql.jdbc2.optional.PoolingDataSource
3否org.postgresql.jdbc3.Jdbc3SimpleDataSource
3是org.postgresql.jdbc3.Jdbc3PoolingDataSource
所有实现使用同样的配置模式。JDBC 要求 DataSource 通过 JavaBean 属性配置,因此每种这个 属性都有获取和设置属性。
Table 5-4. DataSource 配置属性
属性类型描述
serverNameStringPostgreSQL 数据库服务器主机名
databaseNameStringPostgreSQL 数据库名
portNumberintPostgreSQL 数据库服务器监听的 TCP/IP 端口 (或者 0 表示使用缺省端口)
userString用于连接数据库的用户
passwordString用于连接数据库的口令
连接池实现要求一些额外的配置属性:
Table 5-5. 额外的连接池 DataSource 配置属性
属性类型描述
dataSourceNameString每一个连接池 DataSource 必须有一个唯一的名字
initialConnectionsint连接池初始化的时候要创建的数据库连接数目
maxConnectionsint允许打开的最大数据库连接个数。如果请求了更多的连接, 那么调用者将挂起,直到有一个连接返回给连接池。
下面是一个使用连接池 DataSource 的典型应用的代码:
Example 5-6. DataSource 代码例子
初始化连接池 DataSource 的代码例子看起来会象这样:
Jdbc3PoolingDataSource source = new Jdbc3PoolingDataSource();
source.setDataSourceName("A Data Source");
source.setServerName("localhost");
source.setDatabaseName("test");
source.setUser("testuser");
source.setPassword("testpassword");
source.setMaxConnections(10);
然后使用来自连接池的代码看起来会象这样。 请注意关闭连接是非常关键的,否则这个池子就会“泄漏”连接, 最后把所有客户端都锁在外面。
Connection con = null;
try {
con = source.getConnection();
// use connection
} catch(SQLException e) {
// log error
} finally {
if(con != null) {
try {con.close();}catch(SQLException e) {}
}
}
5.9.5. DataSources 和 JNDI
所有 ConnectionPoolDataSource 和 DataSource 实现都可以存储在 JNDI 里。在非连接池的实现中, 每次从 JNDI 中检索对象都将创建一个新的实例, 带有和存储的实例同样的设置。对于连接池实现而言,同一个实例 是在可得的情况下检索出来的(也就是说,没有其它 JVM 从 JNDI 中检索连接池),否则就创建同样设置的新的实例。
在应用服务器环境,通常是应用服务器的 DataSource 实例将存储在 JNDI 中,而不是 PostgreSQL ConnectionPoolDataSource 的实现。
在应用服务器环境,应用可以在 JNDI 中存储 DataSource, 这样它就不用制作一个指向 DataSource 的引用提供给 所有可能需要的应用组件使用它:
Example 5-7. DataSource JNDI 代码例子
初始化连接池 DataSource 并且把它加到 JNDI 的代码 看起来可能象这样:
Jdbc3PoolingDataSource source = new Jdbc3PoolingDataSource();
source.setDataSourceName("A Data Source");
source.setServerName("localhost");
source.setDatabaseName("test");
source.setUser("testuser");
source.setPassword("testpassword");
source.setMaxConnections(10);
new InitialContext().rebind("DataSource", source);
Then code to use a connection from the pool might look like this:
Connection con = null;
try {
DataSource source = (DataSource)new InitialContext().lookup("DataSource");
con = source.getConnection();
// use connection
} catch(SQLException e) {
// log error
} catch(NamingException e) {
// DataSource wasn't found in JNDI
} finally {
if(con != null) {
try {con.close();}catch(SQLException e) {}
}
}
5.9.6. 特定的应用服务器配置
在这里包含特定的应用服务器的配置信息。
5.10. 深入阅读
如果你还没有读过,我建议你阅读一下 JDBC API 文档(和 Sun 的 JDK一并提供),和 JDBC 规范.两者都可以在 http://java.sun.com/products/jdbc/index.html 获得.
http://jdbc.postgresql.org 包含本文档没有包含的更新信息,同样还有编译好了的驱动.