↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

不受支持的版本: 6.4
历史版本PostgreSQL 6.4 已于 2003 年 10 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本手册首页。

56.11. Postgres 对 JDBC API 的扩展

Postgres 是一个可扩展的数据库系统。 你可以向后端添加自己的函数, 这些函数随后可以在查询中被调用,你甚至可以添加自己的 数据类型。

现在,由于这些是我们独有的设施,我们通过一组扩展 API 从 Java 支持它们。标准驱动核心中的某些特性 (如大对象)实际上就是使用这些扩展实现的。

访问扩展

要访问其中一些扩展,你需要使用 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 extends Object implements 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 的已打开连接。

        返回值:
                允许访问 postgresql 后端函数的 Fastpath 对象。

        抛出:SQLException
                首次初始化时由 Fastpath 抛出
          
 public LargeObjectManager getLargeObjectAPI() throws SQLException

          返回当前连接的 LargeObject API。

          注意:这不是 JDBC 的一部分,而是允许访问 postgresql 后端本身的函数。
   
          最好的使用方式如下:

 import postgresql.largeobject.*;
 ...
 LargeObjectManager lo = 
((postgresql.Connection)myconn).getLargeObjectAPI();

          其中 myconn 是一个到 postgresql 的已打开连接。

        返回值:
                实现该 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 的已打开连接。

          处理类必须继承 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

   extends 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 的 FastpathArg 参数

        返回值:
                无数据时为 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 的 FastpathArg 参数

        返回值:
                无数据时为 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() 该 resultset!!

          关于函数名查找的实现说明:
          
          PostgreSQL 把函数 id 及其对应名称存储在 pg_proc 表中。为了在本地加速,不是在需要时逐个查询该表,而是使用一个 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

   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
                如果值对该类型无效则抛出

        Overrides:
                setValue in class PGobject

 public boolean equals(Object obj)

        参数:
                obj - 要比较的对象
                
        返回值:
                如果两个矩形相同则为 true
          
        Overrides:
                equals in class PGobject

 public Object clone()
        
          必须覆盖此方法才能克隆该对象

        Overrides:
                clone in class PGobject
   
 public String getValue()
        
        返回值:
                按 postgresql 所期望语法表示的 PGbox

        Overrides:
                getValue in class PGobject

Class postgresql.geometric.PGcircle

java.lang.Object
   |
   +----postgresql.util.PGobject
           |
           +----postgresql.geometric.PGcircle
        
   public class PGcircle extends PGobject implements Serializable, 
Cloneable
               
   它表示 postgresql 的 circle 数据类型,由一个点和一个半径组成

变量

 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
                转换失败时

        Overrides:
                setValue in class PGobject

 public boolean equals(Object obj)

        参数:
                obj - 要比较的对象
            
        返回值:
                如果两个矩形相同则为 true

        Overrides:
                equals in class PGobject

 public Object clone()

          必须覆盖此方法才能克隆该对象

        Overrides:
                clone in class PGobject

 public String getValue()

        返回值:
                按 postgresql 所期望语法表示的 PGcircle
        
        Overrides:
                getValue in class PGobject

Class postgresql.geometric.PGline

java.lang.Object
   |
   +----postgresql.util.PGobject
           |
           +----postgresql.geometric.PGline

   public class PGline extends PGobject implements Serializable, 
Cloneable

   它实现由两点构成的 line。后端目前尚未实现 line 类型,但这个类保证了在实现之后我们就能直接使用它。

变量
   
 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
                转换失败时

        Overrides:
                setValue in class PGobject
                
 public boolean equals(Object obj)

        参数:
                obj - 要比较的对象
               
        返回值:
                如果两个矩形相同则为 true
   
        Overrides:
                equals in class PGobject

 public Object clone()
        
          必须覆盖此方法才能克隆该对象

        Overrides:
                clone in class PGobject

 public String getValue()
   
        返回值:
                按 postgresql 所期望语法表示的 PGline
        
        Overrides:
                getValue in class PGobject

Class postgresql.geometric.PGlseg
             
java.lang.Object
   |
   +----postgresql.util.PGobject
           |
           +----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 - 第一个点的坐标
                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
                转换失败时
     
        Overrides:
                setValue in class PGobject
                
 public boolean equals(Object obj)

        参数:
                obj - 要比较的对象
               
        返回值:
                如果两个矩形相同则为 true
   
        Overrides:
                equals in class PGobject
   
 public Object clone()

          必须覆盖此方法才能克隆该对象

        Overrides:
               clone in class PGobject

 public String getValue()

        返回值:
                按 postgresql 所期望语法表示的 PGlseg
        
        Overrides:
                getValue in class PGobject

Class postgresql.geometric.PGpath
                                
java.lang.Object
   |
   +----postgresql.util.PGobject
           |
           +----postgresql.geometric.PGpath
          
   public class PGpath extends PGobject implements Serializable, 
Cloneable
               
   它实现 path(一条多段线,可以是闭合的)
           
变量

 public boolean open
               
          如果路径是开放的则为 true,闭合则为 false

 public PGpoint points[]

          定义该路径的各个点

构造器

 public PGpath(PGpoint points[],
               boolean open)
          
        参数:
                points - 定义该路径的 PGpoint 数组
                open - 如果路径是开放的则为 true,闭合则为 false

 public PGpath()

          驱动所需

 public PGpath(String s) throws SQLException

        参数:
                s - PostgreSQL 语法的圆定义。

        抛出:SQLException
                转换失败时

方法

 public void setValue(String s) throws SQLException
   
        参数:
                s - PostgreSQL 语法的路径定义
           
        抛出:SQLException
                转换失败时

        Overrides:
                setValue in class PGobject

 public boolean equals(Object obj)

        参数:
                obj - 要比较的对象

        返回值:
                如果两个矩形相同则为 true

        Overrides:
                equals in class PGobject

 public Object clone()

          必须覆盖此方法才能克隆该对象

        Overrides:
                clone in class PGobject

 public String getValue()

          返回按 postgresql 所期望语法表示的该多边形

        Overrides:
                getValue in class PGobject

 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
          
   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
                转换失败时

        Overrides:
                setValue in class PGobject
          
 public boolean equals(Object obj)

        参数:
                obj - 要比较的对象

        返回值:
                如果两个矩形相同则为 true

        Overrides:
                equals in class PGobject

 public Object clone()
                
          必须覆盖此方法才能克隆该对象

        Overrides:
                clone in class PGobject
          
 public String getValue()       
    
        返回值:
                按 postgresql 所期望语法表示的 PGpoint

        Overrides:
                getValue in class PGobject
          
 public void translate(int x,
                       int y)

          按给定的量平移该点。

        参数:
                x - 在 x 轴上要加的整数增量
                y - 在 y 轴上要加的整数增量

 public void translate(double x,
                       double y)
          
          按给定的量平移该点。
 
        参数:
                x - 在 x 轴上要加的 double 增量
                y - 在 y 轴上要加的 double 增量

 public void move(int x,
                  int y)
                
          把该点移动到给定的坐标。

        参数:
                x - 整数坐标
                y - 整数坐标

public void move(double x,
                  double y)
          
          把该点移动到给定的坐标。

        参数:
                x - double 坐标
                y - double 坐标

 public void setLocation(int x,
                         int y)

          把该点移动到给定的坐标。相关描述参见 java.awt.Point

        参数:
                x - 整数坐标
                y - 整数坐标

        参见:
                Point

 public void setLocation(Point p)

          把该点移动到给定的 java.awt.Point。相关描述参见 java.awt.Point

        参数:
                p - 要移动到的点

        参见:
                Point

Class postgresql.geometric.PGpolygon
                                
java.lang.Object
   |
   +----postgresql.util.PGobject
           |
           +----postgresql.geometric.PGpolygon

   public class PGpolygon extends PGobject implements Serializable, 
Cloneable
               
   它实现 PostgreSQL 中的 polygon 数据类型。

变量

 public PGpoint points[]

          定义该多边形的各个点
                                
构造器

 public PGpolygon(PGpoint points[])

          用一个 PGpoint 数组创建多边形

        参数:
                points - 定义该多边形的各个点

 public PGpolygon(String s) throws SQLException
                 
        参数:
                s - PostgreSQL 语法的圆定义。

        抛出:SQLException
                转换失败时

 public PGpolygon()

          驱动所需

方法

 public void setValue(String s) throws SQLException

        参数:
                s - PostgreSQL 语法的多边形定义

        抛出:SQLException
                转换失败时

        Overrides:
                setValue in class PGobject

 public boolean equals(Object obj)
     
        参数:
                obj - 要比较的对象
                                
        返回值:
                如果两个矩形相同则为 true

        Overrides:
                equals in class PGobject

 public Object clone()
        
          必须覆盖此方法才能克隆该对象

        Overrides:
                clone in class PGobject
                 
 public String getValue()

        返回值:
                按 postgresql 所期望语法表示的 PGpolygon

        Overrides:
                getValue in class PGobject

大对象

标准 JDBC 规范支持大对象。但那个接口能力有限,而 PostgreSQL 提供的 api 允许像访问本地文件一样随机访问对象内容。

postgresql.largeobject 包向 Java 提供了 libpq C 接口的大对象 API。它由两个类组成:负责创建、打开和删除大对象的 LargeObjectManager,以及处理单个对象的 LargeObject。

Class postgresql.largeobject.LargeObject

java.lang.Object
   |
   +----postgresql.largeobject.LargeObject

public class LargeObject extends 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

public class LargeObjectManager extends Object

这个类实现 postgresql 的大对象接口。
        
   它提供允许客户端代码在数据库中创建、打开和删除大对象的方法。打开对象时会返回一个 postgresql.largeobject.LargeObject 实例,其方法随后允许访问该对象。

这个类只能由 postgresql.Connection 创建

要访问这个类,使用下面这段代码:

 import postgresql.largeobject.*;
 Connection  conn;
 LargeObjectManager lobj;
 ... 打开连接的代码 ...
 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 - 大对象的

        返回值:
                提供对该对象访问的 LargeObject 实例

        抛出:SQLException
                出错时

 public LargeObject open(int oid,
                         int mode) throws SQLException
          
          它根据 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 方法相同,之所以提供是因为 C API 使用 unlink。

        参数:
                oid - 描述要删除的对象

        抛出:SQLException
                出错时

对象序列化
PostgreSQL 不是普通的 SQL 数据库。它比大多数其他数据库可扩展得多,并且支持它独有的面向对象特性。 

其中一个后果是,可以让一个表引用另一个表中的某一行。例如:

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;
username|fullname      
--------+--------------
peter   |Peter Mount   
(1 row)

test=> select * from server;
servername|adminuser
----------+---------
maidast   |  2610132
(1 row)

好,上面的例子表明我们可以把表名用作字段,该行的 oid 值就存储在这个字段中。

这与 Java 有什么关系?

在 Java 中,只要对象的类实现了 java.io.Serializable 接口,就可以把对象存储到流中。这一过程称为对象序列化,可用于把复杂对象存入数据库。

而在 JDBC 之下,你得用 LargeObject 来存储它们。然而,无法对这些对象执行查询。

postgresql.util.Serialize 类所做的事,就是提供一种把对象存成表、再从表中取回该对象的手段。大多数情况下你不需要直接访问这个类,而是使用 PreparedStatement.setObject() 和 ResultSet.getObject() 方法。这些方法会把对象的类名与数据库中的表比对。找到匹配时,就假定该对象是一个序列化对象,并从那个表取回它。在此过程中,如果对象还包含其他序列化对象,它会沿树递归。

听起来复杂?其实比我写的简单——只是难以解释。

唯一需要直接访问这个类的场合,是使用 create() 方法。驱动本身不使用它们,而是根据你要序列化的 Java 对象或类,向数据库发出一条或多条 "create table" 语句。

哦,最后一件事。如果你的对象里有这样一行:

     public int oid;

那么,当对象从表中取回时,它会被设为表内的 oid。之后,如果对象被修改并重新序列化,既有条目会被更新。

如果没有 oid 变量,那么对象被序列化时总是插入表中,表中任何既有条目都会保留。

序列化之前把 oid 设为 0 也会导致对象被插入。这使得可以在数据库中复制一个对象。

Class postgresql.util.Serialize

java.lang.Object
   |
   +----postgresql.util.Serialize

   public class Serialize extends Object

   这个类利用 PostgreSQL 的面向对象特性来存储 Java 对象。做法是把 Java 类名映射为数据库中的一个表。新表中的每个条目代表该类的一个序列化实例。由于每个条目都有一个 OID(对象标识符),这个 OID 可以被包含在另一个表中。这太复杂,不在此展示,主文档中会有更详细的说明。

构造器

 public Serialize(Connection c,
                  String type) throws SQLException

          它创建一个实例,可用于对 PostgreSQL 表中的 Java 对象做序列化/反序列化。

方法

 public Object fetch(int oid) throws SQLException

          它根据 OID 从表中取回一个对象

        参数:
                oid - 对象的 oid

        返回值:
                与 oid 对应的对象

        抛出:SQLException
                出错时

 public int store(Object o) throws SQLException

          它把一个对象存入表中并返回其 OID。

          如果对象有一个名为 OID 的 int 且其值 > 0,就用该值作 OID,表将被更新。如果 OID 的值为 0,则会新建一行,并且 OID 的值会被设置到对象中。这使对象在数据库中的值可以更新。如果对象没有名为 OID 的 int,则直接存储对象。但若对象随后被取回、修改并再次存储,它的新状态会被追加到表中,而不会覆盖旧条目。

        参数:
                o - 要存储的对象(必须实现 Serializable)

        返回值:
                已存储对象的 oid

        抛出:SQLException
                出错时
 
 public static void create(Connection con,
                           Object o) throws SQLException

          驱动不使用此方法;它根据一个可序列化的 Java 对象创建表。应当在序列化任何对象之前使用它。

        参数:
                c - 到数据库的连接
                o - 表所基于的对象

        抛出:SQLException
                出错时

                   返回值:
                与 oid 对应的对象

        抛出:SQLException
                出错时

 public int store(Object o) throws SQLException

          它把一个对象存入表中并返回其 OID。

          如果对象有一个名为 OID 的 int 且其值 > 0,就用该值作 OID,表将被更新。如果 OID 的值为 0,则会新建一行,并且 OID 的值会被设置到对象中。这使对象在数据库中的值可以更新。如果对象没有名为 OID 的 int,则直接存储对象。但若对象随后被取回、修改并再次存储,它的新状态会被追加到表中,而不会覆盖旧条目。

        参数:
                o - 要存储的对象(必须实现 Serializable)

        返回值:
                已存储对象的 oid

        抛出:SQLException
                出错时
 
 public static void create(Connection con,
                           Object o) throws SQLException

          驱动不使用此方法;它根据一个可序列化的 Java 对象创建表。应当在序列化任何对象之前使用它。

        参数:
                c - 到数据库的连接
                o - 表所基于的对象

        抛出:SQLException
                出错时
                
 public static void create(Connection con,
                           Class c) throws SQLException

          驱动不使用此方法;它根据一个可序列化的 Java 对象创建表。应当在序列化任何对象之前使用它。

        参数:
                c - 到数据库的连接
                o - 表所基于的类

        抛出: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

   public class PGmoney extends PGobject implements 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

        参数:
                s - PostgreSQL 语法的该点定义

        抛出:SQLException
                转换失败时

        Overrides:
                setValue in class PGobject

 public boolean equals(Object obj)

        参数:
                obj - 要比较的对象
                                
        返回值:
                如果两个矩形相同则为 true

        Overrides:
                equals in class PGobject

 public Object clone()
                
          必须覆盖此方法才能克隆该对象

        Overrides:
                clone in class PGobject

 public String getValue()

        返回值:
                按 postgresql 所期望语法表示的 PGpoint

        Overrides:
                getValue in class PGobject

Class postgresql.util.PGobject

java.lang.Object
   |
   +----postgresql.util.PGobject

   public class PGobject extends Object implements Serializable, 
Cloneable
               
   这个类用于描述 JDBC 标准所不知道的数据类型。调用 postgresql.Connection 可以让一个继承本类的类与一个命名类型关联。postgresql.geometric 包就是这样工作的。对任何没有自己处理器的类型,ResultSet.getObject() 都会返回这个类。因此,任何 postgresql 数据类型都得到支持。

构造器

 public PGobject()

          它由 postgresql.Connection.getObject() 调用来创建对象。

方法

 public final void setType(String type)

          此方法设置该对象的类型。

          子类不应扩展它,因此它是 final 的

        参数:
                type - 描述该对象类型的字符串

 public void setValue(String value) throws SQLException

          此方法设置该对象的值。它必须被覆盖。

        参数:
                value - 对象值的字符串表示

        抛出:SQLException
                如果值对该类型无效则抛出
    
 public final String getType()

          由于它在对象生命周期内不能改变,因此是 final 的。

        返回值:
                该对象的类型名

 public String getValue()

          必须覆盖它,以 postgresql 所要求的形式返回对象的值。

        返回值:
                该对象的值

 public boolean equals(Object obj)

          必须覆盖它才能比较对象

        参数:
                obj - 要比较的对象

        返回值:
                如果两个矩形相同则为 true

        Overrides:
                equals in class Object

 public Object clone()

          必须覆盖此方法才能克隆该对象

        Overrides:
                clone in class Object

 public String toString()

          这里已定义它,因此用户代码不必覆盖。
          
        返回值:
                按 postgresql 所期望语法表示的该对象的值

        Overrides:
                toString in class Object

Class postgresql.util.PGtokenizer

java.lang.Object
   |
   +----postgresql.util.PGtokenizer

   public class PGtokenizer extends Object

   这个类用于对 postgres 的文本输出做分词。

   本可以用 StringTokenizer 来做,但我们需要处理 '(' ')' '[' ']' '<' 和 '>' 的嵌套,几何数据类型会用到它们。

   它主要由几何类使用,但对解析 postgresql 自定义数据类型的任何输出也有用。
                 
   参见:
          PGbox, PGcircle, PGlseg, PGpath, PGpoint, PGpolygon
          
构造器

 public PGtokenizer(String string,
                    char delim)

          创建一个分词器。

        参数:
                string - 包含各词的字符串
                delim - 分割各词的单个字符

方法
        
 public int tokenize(String string,
                     char delim)

          用一个新字符串和/或新分隔符重置该分词器。

        参数:
                string - 包含各词的字符串
                delim - 分割各词的单个字符

 public int getSize()

        返回值:
                可用词的数量

 public String getToken(int n)

        参数:
                n - 词的编号(0 ... getSize()-1)

        返回值:
                词的值

 public PGtokenizer tokenizeToken(int n,
                                  char delim)

          它基于我们的某个词返回一个新的分词器。几何数据类型用它处理嵌套的词(通常是 PGpoint)。

        参数:
                n - 词的编号(0 ... getSize()-1)
                delim - 要使用的分隔符

        返回值:
                基于该词的一个新 PGtokenizer 实例

 public static String remove(String s,
                             String l,
                             String t)

          移除一个字符串的前导/尾随字符串

        参数:
                s - 源字符串
                l - 要移除的前导字符串
                t - 要移除的尾随字符串
                
        返回值:
                不含前导/尾随字符串的字符串

 public void remove(String l,
                    String t)

          移除所有词的前导/尾随字符串

        参数:
                l - 要移除的前导字符串
                t - 要移除的尾随字符串

 public static String removePara(String s)

          移除字符串开头和结尾的 ( 和 )

        参数:
                s - 要从中移除的字符串

        返回值:
                不含 ( 或 ) 的字符串

 public void removePara()

          移除所有词开头和结尾的 ( 和 )

        返回值:
                不含 ( 或 ) 的字符串

 public static String removeBox(String s)
   
          移除字符串开头和结尾的 [ 和 ]

        参数:
                s - 要从中移除的字符串
   
        返回值:
                不含 [ 或 ] 的字符串

 public void removeBox()

          移除所有词开头和结尾的 [ 和 ]

        返回值:
                不含 [ 或 ] 的字符串

 public static String removeAngle(String s)

          移除字符串开头和结尾的 < 和 >

        参数:
                s - 要从中移除的字符串

        返回值:
                不含 < 或 > 的字符串

 public void removeAngle()

          移除所有词开头和结尾的 < 和 >

        返回值:
                不含 < 或 > 的字符串

Class postgresql.util.Serialize

它已在前面“对象序列化”一节中说明。

Class postgresql.util.UnixCrypt
              
java.lang.Object
   |
   +----postgresql.util.UnixCrypt

   public class UnixCrypt extends Object

   这个类使我们能够在口令经网络流发送时对其加密

   包含用于加密口令以及与 Unix 加密口令比对的静态方法。

   原始源码见 John Dumas 的 Java Crypt 页面。

   http://www.zeh.com/local/jfd/crypt.html

方法

 public static final String crypt(String salt,
                                  String original)

          根据明文口令和一个“盐”加密口令。
   
        参数:
                salt - 一个两字符字符串,表示用于以多种方式迭代加密引擎的盐。如果要生成新加密,此值应当随机化。 original - 要加密的口令。

        返回值:
                由 2 字符盐后接加密口令组成的字符串。
              
 public static final String crypt(String original)

          根据明文口令加密口令。此方法用 'java.util.Random' 类生成随机盐。

        参数:
                original - 要加密的口令。
   
        返回值:
                由 2 字符盐后接加密口令组成的字符串。
               
 public static final boolean matches(String encryptedPassword,
                                     String enteredPassword)
                 
          检查 enteredPassword 加密后是否等于 encryptedPassword。
               
        参数:
                encryptedPassword - 已加密口令。假定前两个字符是盐。该字符串与 Unix /etc/passwd 文件中的形式相同。 enteredPassword - 用户(或其他途径)输入的口令。

        返回值:
                如果口令应视为正确则为 true。

在多线程或 Servlet 环境中使用驱动

许多 JDBC 驱动都有一个问题:同一时刻只能有一个线程使用一个连接——否则一个线程可能在另一个线程接收结果时发出查询,这对数据库引擎是坏事。

PostgreSQL 6.4 为整个驱动带来了线程安全。6.3.x 中标准 JDBC 是线程安全的,但 Fastpath API 不是。

因此,如果你的应用使用多线程(大多数像样的应用都会),就不必为确保同一时刻只有一个线程使用数据库而操心复杂方案。

如果一个线程在另一个线程正在使用连接时试图使用它,它会等那个线程完成当前操作。

若是标准 SQL 语句,操作就是发送语句并(完整地)取回任何 ResultSet。

若是 Fastpath 调用(即从 LargeObject 读取一块),就是发送并取回该块的时间。

对应用和小程序来说这没问题,但可能给 servlet 带来性能问题。

对 servlet 而言,连接可能承受重载。如果多个线程执行查询,每个都会停顿,这可能不是你想要的。

为解决此问题,建议创建一个连接池。

每当线程需要使用数据库时,它向一个管理器类请求 Connection。管理器把一个空闲连接交给线程并标记为忙。如果没有空闲连接,就新开一个。

线程用完后把连接还给管理器,管理器可以关闭它或把它放回池中。管理器还会检查连接是否仍存活,若已死则从池中移除。

所以在 servlet 场景下,用单连接还是连接池由你决定。池的好处是线程不会受单一网络连接造成的瓶颈影响;坏处是服务器负载增加,因为每个 Connection 都会创建一个后端。

这取决于你和你的应用需求。

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。