PostgreSQL7.0手册-接口-58. JDBC 接口
内容
制作 JDBC 接口
为 JDBC准备数据库
使用驱动
装入 JDBC
装载驱动
与数据库联接
发出查询和处理结果
执行更新
关闭联接
使用大对象
Postgres 对 JDBC API的扩展
深入阅读
作者:由 Peter T. Mount 执笔,他是JDBC 驱动的作者.
JDBC 是 Java 1.1 及以后的核心 API.它为 SQL 兼容的数据库提供了一个标准的接口集合.
Postgres 提供了类型 4JDBC 驱动.类型 4 表明该驱动是用纯 Java 书写的,并且与数据库之间使用数据库自己的网络协议通讯.因此,驱动是平台无关的.一旦编译,该驱动可以用于任意平台.
制作 JDBC 接口
编译驱动
驱动的源代码位于源码树的 src/interfaces/jdbc 目录.要编译之,你只需要进入该目录,然后键入:
% make
编译完成后,你将在当前目录发现文件 postgresql.jar.这就是 JDBC 驱动.
注意:你必须使用 make,而不是 javac,因为驱动因为性能原因使用了一些动态联接技巧,这些是 javac 办不到的.Makefile 将生成 jar 归档文件.
安装驱动
要使用驱动,.jar 文件 postgresql.jar 需要被包含在 CLASSPATH 里.
例子
我有一个使用 JDBC 驱动的应用,该应用访问一个包含天文对象的大数据库.我已经有这个应用并且 jdbc 驱动安装在 /usr/local/lib 目录,并且 java jdk 安装在 /usr/local/jdk1.1.6.
要运行应用,我可以用:
export CLASSPATH = /usr/local/lib/finder.jar:/usr/local/lib/postgresql.jar:.
java uk.org.retep.finder.Main
装载驱动在本章后面部分介绍.
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
为 JDBC 准备数据库
因为 Java 只能使用 TCP/IP 联接,Postgres 的 postmaster 必须带 -i 参数运行.
同样,必须配置 pg_hba.conf 文件.它放在 PGDATA 目录.缺省安装时,这个文件只允许 UNIX 域套接字访问.对联到同样 localhost 的JDBC 驱动(应用),你需要加一些象:
host all 127.0.0.1 255.255.255.255 password
的东西(到 pg_hba.conf 文件),这里允许从本地 JDBC 对所有数据库的访问.
JDBC 驱动支持 trust,ident,password 和 crypt 认证模式.
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
使用驱动
本章并不想作为完整的 JDBC 编程的指导,但应该能帮你走出第一步.更多信息请参考标准 JDBCAPI 文档.同样,读一下包含在源代码里的例子.其中的基本例子在这里使用.
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
装入 JDBC
任何使用 JDBC 的程序需要输入 java.sql 包,用:
import java.sql.*;
关键:不要输入 postgresql 包.如果这样做,你的源码将不能编译,因为 javac 会被你搞糊涂。
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
装载驱动
在你试图与数据库连接之前,你需要装载驱动.有两种方法,那种更好取决于你使用的代码.
在第一种方法里,你的代码用 Class.forName() 方法显式装载驱动.对于 Postgres,你要用:
Class.forName("postgresql.Driver");
这样将装载驱动,并且在装载时,驱动将自动与 JDBC 注册自己.
注意:forName() 方法可以抛出一个 ClassNotFoundException,所以如果驱动不可获得时你需要捕获它.
这是最常用的方法,但是把你的代码限制于 Postgres 专用.如果你的代码以后还要访问其他数据库,并且你不想使用我们的扩展,那么第二种方法可用.
第二种方法把驱动做为参数在 JVM 启动时传递给它,使用 -D 参数.
% java -Djdbc.drivers=postgresql.Driver example.ImageViewer
在这个例子里,JVM 将试图把驱动作为它的初始化的一部分装载.一旦完成,启动 ImageViewer。
现在,这个方法是一个更好的手段,因为它允许你的代码用于其他数据库,而不用重新编译代码.唯一要修改的东西是 URL,我们下面要提到.
最后一件事情.当你的代码试图打开一个联接,而且你收到一个抛出的 No driver available SQLException 例外,这可能是因为驱动不在 classpath (类路径)里,或者参数值不正确.
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
与数据库联接
在 JDBC 里,数据库是用 URL (Uniform Resource Locator)(统一资源定位器)表示的.在 Postgres 里,这可以由下面几种格式之一表示:
jdbc:postgresql:database
jdbc:postgresql://host/database
jdbc:postgresql://hostport/database
这里:
host
服务器的主机名.缺省是 "localhost".
port
服务器监听的端口号.缺省时是 Postgres 标准的端口号(5432).
database
数据库名.
要联接(数据库),你需要从 JDBC 获取一个联接实例(Connection instance).要做这些,你要使用 DriverManager.getConnection() 方法:
Connection db = DriverManager.getConnection(url,user,pwd);
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
发出查询和处理结果
在任何你想向数据库运行一个 SQL 语句的时候,你都需要一个 Statement (语句)实例.一旦你拥有了一个 Statement (语句),你就可以使用 executeQuery() 方法来运行一个查询.这样将返回一个 ResultSet 实例,在其内部包含整个结果.
使用 Statement (语句)接口
在使用 Statement 接口时必须考虑下面的问题:
你可以使用一个 Statement (语句)实例任意次.你可以在打开一个联接后马上创建一个 Statement (语句)实例,并且在联接的生存期里使用之.你必须知道每个 Statement 只能存在一个 ResultSet (结果集).
如果你需要在处理一个 ResultSet 的时候执行一个查询,你只需要创建并且使用另外一个 Statement.
如果你使用了 Threads (线程),并且有几个使用数据库,你对每个线程必须使用一个独立的 Statement.如果考虑使用线程,请参考本文档稍后描述 Threads 和 Servlets 的章节,因为这些内容包含一些重要的信息.
使用 ResultSet (结果集)接口
使用 ResultSet 接口时必须考虑下面的问题:
在读取任何数值的时候,你必须调用 next().如果还有结果则返回真(true),但更重要的是,它为处理准备了数据行.
在 JDBC 规范里,你应该对一个字段只访问一次.遵循这个规则是安全的,不过目前 Postgres 驱动将允许你对一个字段访问任意次.
一旦你结束对一个 ResultSet 的处理,你必须调用对之 close()。
一旦你使用那个创建 ResultSet 的 Statement 做另一个查询请求,当前打开的实例将被关闭.
下面是一个例子:
Statement st = db.createStatement();
ResultSet rs = st.executeQuery("select * from mytable");
while(rs.next()) {
System.out.print("Column 1 returned ");
System.out.println(rs.getString(1));
}
rs.close();
st.close();
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
执行更新
要执行一次更新 (或任何其他不返回结果的 SQL 语句),你只需要使用 executeUpdate() 方法:
st.executeUpdate("create table basic (a int2, b int2)");
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
关闭联接
要关闭数据库联接,只需要对联接调用 close() 方法:
db.close();
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
使用大对象
在 Postgres 里,大对象(也称之为 液滴(blobs) )用于保存那些无法在通常 SQL 表里面保存的数据.它们是通过表/索引对进行存储的,然后用一个 OID 值从你自己的表里面引用.
关键:对于 Postgres,你必须在一个 SQL 事务里面访问大对象。尽管我们总是这样要求,但直到版本 6.5 我们才严格要求这样做。你应该带着一个输入参数 false 使用 setAutoCommit() 方法打开一个事务:
Connection mycon;
...
mycon.setAutoCommit(false);
... now use Large Objects
现在,你有几种使用大对象的方法.第一种是标准的 JDBC 方式,这个方式在这里有文档.另一种,使用我们对该(JDBC)api (编程接口)的扩展,也是一种用于 Java 的 libpq 大对象 API 的形式,提供了一种比标准方法更好的访问大对象的访问方法.在系统内部,该驱动使用这种扩展来提供大对象支持.
在JDBC里,标准的访问大对象的方法是使用 ResultSet 里的 getBinaryStream() 方法,和PreparedStatement 里的 setBinaryStream() 方法.这些方法把大对象表示成 Java 的流(stream),允许你用 java.io 和其他的包来操纵这些对象.
例如,假设你有一个包含一幅图象文件名的表,而且一个大对象包含这个图象:
create table images (imgname name,imgoid oid);
要插入一幅图象,你可以:
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 从一个流里面把一定字节的数据转换到大对象里,然后把(大对象的) OID 存储到引用它的字段里.
检索一幅图象甚至更快(我在这里使用 PreparedStatement ,当然用 Statement 也是一样的):
PreparedStatement ps = con.prepareStatement("select oid from images where name=?");
ps.setString(1,"myimage.gif");
ResultSet rs = ps.executeQuery();
if(rs!=null) {
while(rs.next()) {
InputStream is = rs.getBinaryInputStream(1);
// use the stream in some way here
is.close();
}
rs.close();
}
ps.close();
这里你可以看到这里大对象是当做一个 InputStream (输入流)检索的.你还会注意到我们在处理结果的下一行之前关闭了流.这是 JDBC 规范的一部分,该规范指出任何返回的 InputStream 在调用 ResultSet.next() 或 ResultSet.close() 后都要被关闭.
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
Postgres 对 JDBC API的扩展
Postgres 是一种可扩展的数据库系统.你可以向数据库后端里增加你自己的函数,这些函数可以供查询调用,甚至你可以增加你自己的数据类型.
因为目前这些特性是我们独有的,所以我们在 Java 里通过一套扩展的 API 提供对这些特性的支持.在标准驱动的核心里有些特性实际上是通过这些扩展实现的,比如大对象等.
获得这些扩展
要获得某些扩展,你需要使用 postgresql.Connection 类里的一些额外的方法
这时,你需要转换 Driver.getConnection() 的返回值.
例如:
Connection db = Driver.getConnection(url,user,pass);
// later on
Fastpath fp = ((postgresql.Connection)db).getFastpathAPI();
Class postgresql.Connection
java.lang.Object
+----postgresql.Connection
公共类 (public class) Connection 扩展了(类) Object 实现的 Connection
这些是用于获取我们的扩展的额外方法.我
没有列出由 java.sql.Connection 定义的方法.
public Fastpath getFastpathAPI() throws SQLException
这里返回当前联接的 Fastpath API.
注意:这个用法不是 JDBC 的一部分,但是允许使用 postgresql 后端本身的函数.
这个用法基本上是用于 LargeObject API 的
使用这个用法的最好的方法是:
import postgresql.fastpath.*;
...
Fastpath fp = ((postgresql.Connection)myconn).getFastpathAPI();
这里 myconn 是一个打开了的到 postgresql 的 Connection (联接).
返回:
Fastpath 对象允许使用在 postgresql 后端上的函数.
抛出: SQLException
在 Fastpath 为第一次使用初始化时生成
public LargeObjectManager getLargeObjectAPI() throws SQLException
这个语句为当前联接返回 LargeObject API.
注意:这个用法不是 JDBC 的一部分,但是允许使用 postgresql 后端本身的函数.
使用这个用法的最好的方法是:
import postgresql.largeobject.*;
...
LargeObjectManager lo =
((postgresql.Connection)myconn).getLargeObjectAPI();
这里 myconn 是一个打开了的到 postgresql 的 Connection (联接).
返回:
实现该 API 的 LargeObject 对象
抛出: SQLException
在 LargeObject 为第一次使用初始化时生成
public void addDataType(String type,
String name)
这个函数允许客户应用代码为 postgresql 众多独立数据类型的一个增加一个控制器.
通常,驱动器不能识别的数据类型由 ResultSet.getObject() 做为 PGobject 实例返回.
这个方法允许你写一个类扩展 PGobject,并且
告诉驱动器要使用的类型名称和类名称.
这样做的不便之处是你每次进行联接后都必须调用这个方法.
注意:这个用法不是 JDBC 的一部分, 而是一个扩展.
使用这个用法的最好方法是:
...
((postgresql.Connection)myconn).addDataType("mytype","my.class.name"-
);
...
这里 myconn 是一个打开了的与 postgresql 的 Connection (联接).
该控制类必须扩展 postgresql.util.PGobject
参阅:
PGobject
Fastpath
Fastpath 是一套存在于libpq C 接口里的API,并且这个接口允许客户机器执行后端数据库的函数.
大多数客户端代码不需要使用这个方法,但是我们还是提供这个方法,因为大对象 API 使用它.
要使用这个特性,你需要输入 postgresql.fastpath 包,使用下面行
import postgresql.fastpath.*;
然后,在你的代码里,你需要获取一个 FastPath 对象:
Fastpath fp = ((postgresql.Connection)conn).getFastpathAPI();
这样将返回一个实例,该实例与你用来执行命令的数据库联接相关联.
把 Connection 转换成 postgresql.Connection 是必须的,因为 getFastpathAPI() 是我们自己的
方法之一,而不是 JDBC 的.
一旦你有一个 Fastpath 实例,你就可以使用 fastpath() 方法来执行后端函数.
Class postgresql.fastpath.Fastpath
java.lang.Object
+----postgresql.fastpath.Fastpath
公共类 (public class) Fastpath
扩展了 Object
这个类实现了 Fastpath api (编程接口).
这是在一个 java 应用里执行内嵌在 postgresql 后端的函数的方法.
这个方法是以文件 src/interfaces/libpq/fe-exec.c 为基础的
参阅:
FastpathFastpathArg, LargeObject
方法
public Object fastpath(int fnid,
boolean resulttype,
FastpathArg args[]) throws SQLException
向 PostgreSQL 后端发送一个函数调用
参数:
fnid - 函数 id
resulttype - 如果结果是整数返回真 (true), 其他结果返回假 (false)
args - 传递给 fastpath 的参数 FastpathArguments
返回:
如果没有数据返回空(null), 如果结果为整数返回一个Integer, 否则返回 byte[]
抛出: SQLException
如果发生了一个数据库访问错误.
public Object fastpath(String name,
boolean resulttype,
FastpathArg args[]) throws SQLException
通过名称向 PostgreSQL 后端发送一个函数调用.
注意:
函数名到函数 id 的影射必须存在, 通常先调用 addfunction(). 这是调用函数的比较好的方法,
因为函数 id 在不同版本的后端里是会/可能改变的. 获取这个方法工作的例子, 参阅 postgresql.LargeObject
参数:
name - 函数名称
resulttype - 如果结果是整数返回真 (true), 其他结果返回假 (false)
args - 传递给 fastpath 的参数 FastpathArguments
返回:
如果没有数据返回空 (null), 如果结果为整数返回一个 Integer, 否则返回 byte[]
抛出: SQLException
如果名称未知或者数据库访问错误发生.
参阅:
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 是静态的, 甚至运行在不同服务器的同版本的数据库也不能保证是统一的.
参数:
name - 函数名
fnid - 函数 id
public void addFunctions(ResultSet rs) throws SQLException
这个方法接收一个包含两个字段的 ResultSet. 字段 1 包含函数名, 字段 2 是 oid.
它读取整个 ResultSet, 把值装载入函数表.
调用完这个方法后记得用 close() 关闭结果集!!
关于函数名查找实现的信息:
PostgreSQL 在 pg_proc 表里存储函数 id 和它们对应的名称, 在
查找时不是从该表里查询每个所需函数的名称, 而是使用了一个 Hashtable (散列表).
同样, 只有需要的函数的名称才放到这个表里, 以保证连接速度尽可能快.
postgresql.LargeObject 类在启动时执行一个查询, 并且把返回的
ResultSet 传递给这里提到的 addFunctions() 方法
一旦这些工作完成, LargeObject api 用名称引用函数.
不要以为手工把它们转换成 oid 可以工作. 的确, 目前这样做是可以用的, 但随着开发的
过程这些可能被修改(在 V7.0 版本的讨论中有一些关于这些的话题), 所以这样做是防止未来将出现的
任何没有保证的痛苦的手段.
参数:
rs - ResultSet
抛出: SQLException
如果发生了数据库访问错误.
参阅:
LargeObjectManager
public int getID(String name) throws SQLException
这个方法返回与函数名关联的函数 id
如果还没有对这个函数调用 addFunction() 或 addFunctions(), 那么抛出一个 SQLException .
参数:
name - 待查找的函数名
返回:
用于 fastpath 调用的函数 ID
抛出: SQLException
如果函数未知.
Class postgresql.fastpath.FastpathArg
java.lang.Object
+----postgresql.fastpath.FastpathArg
public class FastpathArg extends Object
每个 fastpath 调用需要一个参数列表, 其数目和类型取决于被调用的函数.
这个类实现了提供这个功能所需要的方法.
关于如何使用这个方法的例子, 参阅postgresql.largeobject 包
参阅:
Fastpath, LargeObjectManager, LargeObject
构造(方法)
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)
构造一个包含一个字符串的参数.
参数:
s - 要保存的字符串
几何数据类型
PostgreSQL 有一个往表里存储几何特性的数据类型集.范围包括点, 线, 和多边形.
我们通过 postgresql.geometric 包来在 Java 里支持这些类型.
它包括扩展 postgresql.util.PGobject 类的类.参考该类获取如何实现你自己的数据类型的控制器的细节.
Class postgresql.geometric.PGbox
java.lang.Object
+----postgresql.util.PGobject
+----postgresql.geometric.PGbox
公共类 PGbox 扩展 PGobject 实现 Serializable, Cloneable
这个类在 postgresql 里表示盒子 (box) 数据类型.
变量 (Variables)
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 里的 clone
public String getValue()
返回:
postgresql 需要的 PGbox 句法字串
重载:
PGobject 里的 getValue
Class postgresql.geometric.PGcircle
java.lang.Object
+----postgresql.util.PGobject
+----postgresql.geometric.PGcircle
公共类 PGcircle 扩展 PGobject 实现的 Serializable, Cloneable
这个类代表 postgresql 的圆数据类型, 由一个点和一个半径组成
变量
public PGpoint center
这是圆心
public 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 postgresql.geometric.PGline
java.lang.Object
+----postgresql.util.PGobject
+----postgresql.geometric.PGline
公共类 PGline 扩展 PGobject 实现的 Serializable, Cloneable
这个类实现由两个点组成的线. 目前线还没有在后端实现,但这个类保证在后端实现后即可使用(线).
变量
public PGpoint point[]
这是两个点.
构造(方法)
public PGline(double x1,
double y1,
double x2,
double y2)
参数:
x1 - 第一个点的坐标
y1 - 第一个点的坐标
x2 - 第二个点的坐标
y2 - 第二个点的坐标
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 postgresql.geometric.PGlseg
java.lang.Object
+----postgresql.util.PGobject
+----postgresql.geometric.PGlseg
公共类 PGlseg 扩展 PGobject 实现的 Serializable, Cloneable
这个实现是一条包含两个点的 lseg (线段)
变量
public PGpoint point[]
这里是两个点
构造(方法)
public PGlseg(double x1,
double y1,
double x2,
double y2)
参数:
x1 - 第一个点的坐标
y1 - 第一个点的坐标
x2 - 第二个点的坐标
y2 - 第二个点的坐标
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 里的 clone
public String getValue()
返回:
postgresql 语法要求的 PGlseg 字串
重载:
类 PGobject 里的 getValue
Class postgresql.geometric.PGpath
java.lang.Object
+----postgresql.util.PGobject
+----postgresql.geometric.PGpath
公共类 PGpath 扩展 PGobject 实现 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()
必须重载这个方法以便允许这个对象被克隆
重载:
类 PGobject 里的 clone
public String getValue()
这个方法返回 postgresql 语法的多边形字串
重载:
类 PGobject 里的 getValue
public boolean isOpen()
如果路径是开放的这个方法返回真 (true)
public boolean isClosed()
如果路径是封闭的这个方法返回真 (true)
public void closePath()
标记路径为封闭
public void openPath()
标记路径为开放
Class postgresql.geometric.PGpoint
java.lang.Object
+----postgresql.util.PGobject
+----postgresql.geometric.PGpoint
公共类 PGpoint 扩展 PGobject 实现 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 postgresql.geometric.PGpolygon
java.lang.Object
+----postgresql.util.PGobject
+----postgresql.geometric.PGpolygon
公共类 PGpolygon 扩展 PGobject 实现 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
大对象
标准的 JDBC 规范里也支持大对象. 但是, 那个接口有限制, 而 PostgreSQL 提供的 api
允许对对象内容的随机访问, 就象那是一个本地文件一样.
postgresql.largeobject 包为 Java 提供了 libpq C 接口的大对象 API. 它包含两个类,
LargeObjectManager, 处理创建, 打开和删除大对象的任务, 以及 LargeObject, 处理独立的对象.
Class postgresql.largeobject.LargeObject
java.lang.Object
+----postgresql.largeobject.LargeObject
公共类 LargeObject 扩展 Object
这个类实现 postgresql 的大对象接口.
它提供运行接口的基本的方法, 另外还有一对方法为此对象提供 InputStream 和 OutputStream 类.
通常, 客户代码将在 ResultSet 里使用 getAsciiStream, getBinaryStream,
或 getUnicodeStream 方法, 或在访问大对象 PreparedStatement 时用
setAsciiStream, setBinaryStream, 或 setUnicodeStream 方法.
但是, 有时候需要低层次的大对象访问方法,那是 JDBC 规范还不支持的.
参考 postgresql.largeobject.LargeObjectManager 获取如何访问大对象和如何创建大对象的信息.
参阅:
LargeObjectManager
变量
public static final int SEEK_SET
标识从一个文件的开头进行一次搜索
public static final int SEEK_CUR
标识从当前位置进行一次搜索
public static final int SEEK_END
标识从一个文件的结尾进行一次搜索
方法
public int getOID()
返回:
此大对象的 OID
public void close() throws SQLException
这个方法关闭对象. 在调用这个方法后你不能调用这个对象里的任何方法.
抛出: SQLException
如果发生了数据库访问错误
public byte[] read(int len) throws SQLException
从对象读取一些数据, 并且做为 byte[] 数组返回
参数:
len - 读取的字节数
返回:
包含读取数据的 byte[] 数组
抛出: SQLException
如果发生了数据库访问错误
public void read(byte buf[],
int off,
int len) throws SQLException
从对象读取一些数据到现有数组
参数:
buf - 目的数组
off - 数组内偏移量
len - 读取的字节数
抛出: SQLException
如果发生了数据库访问错误
public void write(byte buf[]) throws SQLException
向对象里写入一个数组
参数:
buf - 待写数组
抛出: SQLException
如果发生了数据库访问错误
public void write(byte buf[],
int off,
int len) throws SQLException
从数组里写一些数据到对象
参数:
buf - 目标数组
off - 数组内偏移量
len - 写入字节数
抛出: SQLException
如果发生了数据库访问错误
public void seek(int pos,
int ref) throws SQLException
在对象内部设置当前位置.
这个类似于标准 C 库里的 fseek() 调用它允许你对大对象进行随机访问.
参数:
pos - 对象内部的位置
ref - 可以是 SEEK_SET, SEEK_CUR 或 SEEK_END
抛出: SQLException
如果发生了数据库访问错误
public void seek(int pos) throws SQLException
在对象内部设置当前位置.
这个类似于标准 C 库里的 fseek() 调用它允许你对大对象进行随机访问.
参数:
pos - 对象内部相对开头的位置
抛出: SQLException
如果发生了数据库访问错误
public int tell() throws SQLException
返回:
对象内部当前位置
抛出: SQLException
如果发生了数据库访问错误
public int size() throws SQLException
这个方法不够高效, 因为找出一个对象的唯一方法是搜索到结尾, 记录当前位置,然后返回到初始位置.
今后要找出一个更好的方法.
返回:
大对象的尺寸
抛出: SQLException
如果发生了数据库访问错误
public InputStream getInputStream() throws SQLException
从对象返回一个 InputStream.
然后这个 InputStream 就可以用于任何需要一个 InputStream 的方法里.
抛出: SQLException
如果发生了数据库访问错误
public OutputStream getOutputStream() throws SQLException
返回一个这个对象的 OutputStream
然后这个 OutputStream 就可以用于任何需要一个 OutputStream 的方法里.
抛出: SQLException
如果发生了数据库访问错误
Class postgresql.largeobject.LargeObjectManager
java.lang.Object
+----postgresql.largeobject.LargeObjectManager
公共类 LargeObjectManager 扩展 Object
这个类型实现 postgresql 的大对象接口.
它提供了允许客户代码从数据库里创建, 打开和删除大对象的方法.在打开一个对象时, 返回一个
postgresql.largeobject.LargeObject 的实例, 并且它的方法允许访问该对象.
这个类只能由 postgresql.Connection 创建
要访问这个类, 使用下面的代码片段:
import postgresql.largeobject.*;
Connection conn;
LargeObjectManager lobj;
... code that opens a connection ...
lobj = ((postgresql.Connection)myconn).getLargeObjectAPI();
通常, 客户代码会在 ResultSet 里使用 getAsciiStream, getBinaryStream,
或 getUnicodeStream 方法, 或在访问大对象的 PreparedStatement 里使用 setAsciiStream,
setBinaryStream, 或 setUnicodeStream 方法.
但是, 有时候需要低层次的大对象访问方法,那是 JDBC 规范还不支持的.
请参考 postgresql.largeobject.LargeObject 获取如何控制大对象内容的信息.
参阅:
LargeObject
变量
public static final int WRITE
这个模式表明我们要写入大对象
public static final int READ
这个模式表明我们要读取大对象
public static final int READWRITE
这个模式是缺省的, 表明我们要对大对象进行读和写的操作
方法
public LargeObject open(int oid) throws SQLException
这个方法打开一个现有的大对象, 以其 OID 为基础. 这个方法假设
我们需要 READ 和 WRITE 访问模式 (缺省模式).
参数:
oid - 大对象标识 (oid)
返回:
提供访问大对象的方法的 LargeObject 实例
抛出: SQLException
出错时
public LargeObject open(int oid,
int mode) throws SQLException
这个方法打开一个现有的大对象, 以其 OID 为基础.
参数:
oid - 大对象标识 (oid)
mode - 打开模式
返回:
提供访问大对象的方法的 LargeObject 实例
抛出: SQLException
出错时
public int create() throws SQLException
这个方法创建一个大对象, 返回它的 OID.
它把新创建的大对象模式设为缺省的 READWRITE .
返回:
新对象的 oid (对象标识)
抛出: SQLException
出错时
public int create(int mode) throws SQLException
这个方法创建一个大对象, 返回它的 OID.
参数:
mode - 一个描述新对象不同属性的位掩码
返回:
新对象的 oid (对象标识)
抛出: SQLException
出错时
public void delete(int oid) throws SQLException
这个方法删除一个大对象.
参数:
oid - 描述要删除的对象
抛出: SQLException
出错时
public void unlink(int oid) throws SQLException
这个方法删除一个大对象.
这个方法等同于 delete 方法, 并且作为类似使用 unlink 的
C API 出现.
参数:
oid - 描述要删除的对象
抛出: SQLException
出错时
对象的串行化 (Object Serialisation)PostgreSQL 不是通常的 SQL 数据库. 它比其他数据库有更强的可扩展性,
并且支持面向对象的特性, 这一点另 postgresql 非常独特.
这些特性的一个结果就是你可以拥有一个引用其他表的行的表, 例如:
test=> create table users (username name,fullname text);
CREATE
test=> create table server (servername name,adminuser users);
CREATE
test=> insert into users values ('peter','Peter Mount');
INSERT 2610132 1
test=> insert into server values ('maidast',2610132::users);
INSERT 2610133 1
test=> select * from users;
usernamefullname
--------+--------------
peter Peter Mount
(1 row)
test=> select * from server;
servernameadminuser
----------+---------
maidast 2610132
(1 row)
好, 上面的例子表明我们可以把一个表当作字段来用,并且该行的 oid 值保存在该字段里.
那么这些与 Java 有什么关系呢?
在 Java 里, 只要一个对象的类实现了 java.io.Serializable 接口, 你就可以把一个对象存储成一个
Stream (流). 这个过程称为对象串行化 (Object Serialization), 可以用于将复杂的对象存入数据库.
现在, 在 JDBC 里, 你将不得不使用一个 LargeObject 来存储它们.不过, 你不能在这些对象上执行查询.
postgresql.util.Serialize 类做的工作就是提供一个把一个对象存储为表的方法,
并且从一个表中检索出该对象. 大多数情况下, 你将不需要直接访问这个类,
但是你要用到 PreparedStatement.setObject() 和
ResultSet.getObject() 方法. 这些方法将对照数据库里的表检查对象类的名称,
如果找到一个匹配的, 它就假设该对象是一个串行化了的对象
然后从该表中检索出对象来. 在这么做的同时, 如果该对象包含其他串行化对象
那么它递归地检索这个嵌套树.
听起来很复杂? 实际上, 它比我写的要简单 - 只是解释起来困难些.
你可能访问这个类的唯一机会是使用 create() 方法. 这些不会被驱动使用, 只是对数据库执行一条或更多条
"create table" 语句 - 以你想要串行化的表或 Java 对象为基础.
哦, 最后一件事情. 如果你的对象包含象这样的一行:
public int oid;
那么, 当对象从表里检索出来时, 它被设置为表里的 oid.
那么, 如果该对象被修改, 然后重新串行化, 那么现有的记录将被更新.
如果不存在 oid 变量, 那么当对象串行化时, 它总是被插入表中, 而任何现存的记录将保留.
在串行化之前把 oid 设为 0 将同样导致对象被插入.这样就使在表中复制对象成为可能.
Class postgresql.util.Serialize
java.lang.Object
+----postgresql.util.Serialize
公共类 Serialize 扩展 Object
这个类使用 PostgreSQL 的面向对象的特性存储 Java 对象.
它通过把 Java Class 的名称映射到一个数据库里的表实现这一点.
这样, 这个新表里的每条记录都代表一个这个类的串行化了的实例.
因为每条记录都有一个 OID (Object IDentifier 对象标识),
这个 OID 可以被包含在其他表里. 在这里演示实在是太复杂了, 将在主文档里记录更多的细节.
构造(方法)
public Serialize(Connection c,
String type) throws SQLException
这个方法创建一个可以用于从一个 PostgreSQL 表里串行化一个 Java 对象的实例.
方法
public Object fetch(int oid) throws SQLException
这个方法通过给出的 OID 从一个表里抓取一个对象.
参数:
oid - 对象的 oid (对象标识)
返回:
与 oid 相关的 Object (对象)
抛出: SQLException
出错时
public int store(Object o) throws SQLException
这个方法把一个对象存入一个表中, 返回它的 OID.
如果对象有一个 int (整数)叫 OID, 并且 > 0, 那么那个值
用于 OID, 并且表将被更新. 如果 OID 的值是 0, 那么将创建一个新行, 而且
OID 的值将被设置在对象里(对象必须实现串行化). 这样就使一个对象在数据库里的值被更新成为可能.
如果对象没有名为 OID 的 int (整数), 那么对象被存储. 不过, 如果对象随后被检索, 改动并且重新
存储, 那么它的新状态将被附加到表上, 并且将不覆盖原来的记录.
参数:
o - 待存储的 Object 对象 (必须实现串行化)
返回:
存储了的对象的 oid
抛出: SQLException
出错时
public static void create(Connection con,
Object o) throws SQLException
这个方法不被驱动使用, 但是它创建一个表, 给出一个可串行化的 Java 对象.
应该在串行化任何对象之前使用它.
参数:
c - 与数据库的 Connection (联接)
o - 表所依赖的 Object (对象)
抛出: SQLException
出错时
返回:
与 Object (对象)相关的 oid
抛出: SQLException
出错时
public int store(Object o) throws SQLException
这个方法存储一个对象到表里面, 返回对象的 OID.
如果对象有一个 int (整数)叫 OID, 并且 > 0, 那么那个值
用于 OID, 并且表将被更新. 如果 OID 的值是 0, 那么将创建一个新行, 而且
OID 的值将被设置在对象里. 这样就使一个对象在数据库里的值被更新成为可能.
如果对象没有名为 OID 的 int (整数), 那么对象被存储. 不过, 如果对象随后被检索, 改动并且重新
存储, 那么它的新状态将被附加到表上, 并且将不覆盖原来的记录.
参数:
o - 要存储的 Object (对象) (必须实现串行化)
返回:
存储了的对象的 oid
抛出: SQLException
出错时
public static void create(Connection con,
Object o) throws SQLException
这个方法不被驱动使用, 但是它创建一个表, 给出一个可串行化的 Java 对象.
应该在串行化任何对象之前使用它.
参数:
c - 与数据库的 Connection (联接)
o - 表所依赖的 Object (对象)
抛出: SQLException
出错时
public static void create(Connection con,
Class c) throws SQLException
这个方法不被驱动使用, 但是它创建一个表, 给出一个可串行化的 Java 对象.
应该在串行化任何对象之前使用它.
参数:
c - 与数据库的 Connection (联接)
o - 表所依赖的 Object (对象)
抛出: SQLException
出错时
public static String toPostgreSQL(String name) throws SQLException
这个方法把一个 Java 类名称转换成一个 postgresql 表, 通过
把 . 替换成 _
因为这个原因, 一个类的名称不能包含 _ .
另外一个限制, 是整个表名 (包括
包名) 不能长于 31 个字符 (一个源于 PostgreSQL 的限制 ).
参数:
name - 类名称
返回:
PostgreSQL 表名称
抛出: SQLException
出错时
public static String toClassName(String name) throws SQLException
这个方法把一个 postgresql 表转换成一个 Java 类名称, 通过把 _ 替换成 .
参数:
name - PostgreSQL 表名称
返回:
类名称
抛出: SQLException
出错时
工具类
postgresql.util 包包含被主驱动内部使用的类以及其他扩展.
Class postgresql.util.PGmoney
java.lang.Object
+----postgresql.util.PGobject
+----postgresql.util.PGmoney
公共类 PGmoney 扩展 PGobject 实现 Serializable, Cloneable
这个类实现一个操纵 PostgreSQL money (货币)类型的类
变量
public double val
字段的值
构造(方法)
public PGmoney(double value)
参数:
value - 字段值
public PGmoney(String value) throws SQLException
这个方法主要是被从其他类型里面调用 -- 当货币被嵌入到那些类型的定义里面的时候.
参数:
value - PostgreSQL 的语法定义的货币字串
public PGmoney()
驱动需要
方法
public void setValue(String s) throws SQLException
参数:
obj - 要比较的对象
返回:
如果两个对象相同返回真 (true)
重载:
类 PGobject 里的 equals
public boolean equals(Object obj)
参数:
obj - 要比较的对象
返回:
如果两个对象相同返回真 (true)
重载:
类 PGobject 里的 equals
public Object clone()
必须重载这个方法以便允许这个对象被克隆
重载:
类 PGobject 里的 clone
public String getValue()
返回:
postgresql 希望的货币?