8.6. PostgreSQLJDBC API的扩展

Postgres 是一种可扩展的数据库系统. 你可以向数据库后端里增加你自己的函数,这些函数可以供查询调用, 甚至你可以增加你自己的数据类型.因为这些是 Postgres 特有的功能,因此我们在 Java 里面支持它们,同时还带着一套扩展的 API.在标准驱动的核心里实际上使用了这些扩展 来实现大对象等等.

8.6.1. 访问这些扩展

要获得某些扩展,你需要使用 org.postgresql.Connection 类里的一些额外的方法,这时,你需要转换 Driver.getConnection() 的返回值.比如∶

Connection db = Driver.getConnection(url, username, password);
// ...
// later on
Fastpath fp = ((org.postgresql.Connection)db).getFastpathAPI();

8.6.1.1. 类 org.postgresql.Connection

public class Connection extends Object implements Connection

java.lang.Object
   |
   +----org.postgresql.Connection

这些是用于获取 PostgreSQL 的扩展 的额外的方法.那些 java.sql.Connection 定义的方法没有列出.

8.6.1.1.1. 方法

  • public Fastpath getFastpathAPI() throws SQLException

    这个方法为当前联接返回 Fastpath API. 主要用于大对象API

    使用这个方法的最好方式是∶

    import org.postgresql.fastpath.*;
    ...
    Fastpath fp = ((org.postgresql.Connection)myconn).getFastpathAPI();
    这里的 myconn 是一个已经打开的与 PostgreSQL 的联接.

    返回∶. 一个可以用来访问 PostgreSQL 后端里面的函数的 Fastpath 对象.

    抛出∶. 在第一次初始化的时候 Fastpath 抛出的 SQLException.

  • public LargeObjectManager getLargeObjectAPI() throws SQLException
    这个方法为当前联接返回一个大对象 API

    使用这个方法的最佳手段如下∶

    import org.postgresql.largeobject.*;
    ...
    LargeObjectManager lo = ((org.postgresql.Connection)myconn).getLargeObjectAPI();
    这里的 myconn 是一个已经打开的与 PostgreSQL 的联接.

    返回∶. 实现大对象 API 的 LargeObject 对象.

    抛出∶. 在第一次初始化的时候 LargeObject 抛出的 SQLException.

  • public void addDataType(String type, String name)
    这个方法允许客户端代码为 PostgreSQL 中比较独特的数据类型 加一个句柄.通常,驱动器不认识的数据类型是由 ResultSet.getObject() 以一个 PGobject 实例的形式返回的.这个方法允许你写一个扩展 PGobject 的类,然后告诉驱动该类型名子,以及要使用的类名子. 这个方法的缺点是,每次你建立新联接的时候,你都要调用这个方法.

    使用这个用法的最佳手段是:

     ...
    ((org.postgresql.Connection)myconn).addDataType("mytype","my.class.name");
     ...
    这里的 myconn 是一个已经打开的与 PostgreSQL 的联接.做控制的类必须扩展 org.postgresql.util.PGobject

8.6.1.2. 类 org.postgresql.Fastpath

public class Fastpath extends Object

java.lang.Object
   |
   +----org.postgresql.fastpath.Fastpath

Fastpath是一套存在于 libpq C 接口里的 API , 并且这个接口允许客户机器执行后端数据库的函数. 大多数客户端代码不需要使用这个方法,但是我们还是提供这个方法, 因为大对象 API 使用它.

要使用这个扩展,你需要输入 postgresql.fastpath包,使用下面行:

import org.postgresql.fastpath.*;
然后,在你的代码里,你需要获取一个FastPath对象:
Fastpath fp = ((org.postgresql.Connection)conn).getFastpathAPI();
这样将返回一个实例,该实例与你发出命令的数据库联接相关联. 必须把Connection转换成 org.postgresql.Connection, 因为getFastpathAPI()是我们自己的方法之一,而不是 JDBC的. 一旦你拥有了 Fastpath 实例, 你就可以使用 fastpath() 方法执行一个后端函数.

又见∶. FastpathFastpathArg, LargeObject

8.6.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.

8.6.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

8.6.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)

    构造一个字符串组成的参数.

8.6.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
           
          这是圆心
 
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 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

8.6.3. 大对象

标准的 JDBC 规范里也支持大对象. 但是,那个接口有一些限制, 而 PostgreSQL 提供的 API 允许对对象内容的随机访问, 就象那是一个本地文件一样.

org.postgresql.largeobject 包为 Java 提供了 libpq C 接口的大对象 API.它包含两个类, LargeObjectManager, 处理创建,打开和删除大对象的任务;以及 LargeObject,处理独立的对象.

8.6.3.1. 类org.postgresql.largeobject.LargeObject

public class LargeObject extends Object

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

这个类实现PostgreSQL的大对象接口.

它提供运行接口的基本的方法,另外还有一对方法为此对象提供 InputStreamOutputStream类.

通常, 客户代码将在ResultSet里使用 getAsciiStream, getBinaryStream,或 getUnicodeStream 方法; 或在访问大对象时用PreparedStatement里的 setAsciiStream,setBinaryStream,或 setUnicodeStream 方法.

但是,有时候需要低层次的大对象访问方法,那是 JDBC 规范还不支持的.

参考 org.postgresql.largeobject.LargeObjectManager 获取如何访问大对象和如何创建大对象的信息.

又见∶. LargeObjectManager

8.6.3.1.1. 变量

public static final int SEEK_SET

标识从一个文件的开头进行一次搜索

public static final int SEEK_CUR

标识从当前位置进行一次搜索

public static final int SEEK_END

标识从一个文件的结尾进行一次搜索

8.6.3.1.2. 方法

  • public int getOID()

    返回这个 LargeObject 的 OID.

  • public void close() throws SQLException

    这个方法关闭对象,在调用这个方法后你不能调用这个对象里的任何方法.

  • public byte[] read(int len) throws SQLException

    从对象读取一些数据, 并且做为 byte[] 数组返回

  • public void 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

    写入字节数

8.6.3.2. 类org.postgresql.largeobject.LargeObjectManager

                                
public class LargeObjectManager extends Object

java.lang.Object
   |
   +----org.postgresql.largeobject.LargeObjectManager

这个类型实现了PostgreSQL的大对象接口. 它提供了允许客户代码从数据库里创建,打开和删除大对象的方法. 在打开一个对象时,返回一个 postgresql.largeobject.LargeObject的实例, 然后它的方法就可以访问该对象.

这个类只能由 org.postgresql.Connection 创建 要访问这个类,使用下面的代码片段:

import org.postgresql.largeobject.*;
Connection  conn;
LargeObjectManager lobj;
// ... code that opens a connection ...
lobj = ((org.postgresql.Connection)myconn).getLargeObjectAPI();

通常, 客户代码将在 ResultSet 里使用 getAsciiStream, getBinaryStream,或 getUnicodeStream 方法; 或在访问大对象时用 PreparedStatement 里的 setAsciiStream,setBinaryStream,或 setUnicodeStream 方法. 但是,有时候需要低层次的大对象访问方法,那是 JDBC 规范还不支持的.

请参考 org.postgresql.largeobject.LargeObject 获取如何控制大对象内容的信息.

8.6.3.2.1. 变量

public static final int WRITE

这个模式表明我们要写入大对象

public static final int READ

这个模式表明我们要读取大对象

public static final int READWRITE

这个模式是缺省的,表明我们要对大对象进行读和写的操作

8.6.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 出现.

8.6.4. 对象的串行化

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

test=> select * from server;
servername|adminuser
----------+---------
maidast   |  2610132
(1 row)
好,上面的例子表明我们可以把一个表名字当作字段来用, 并且该行的 oid 值保存在该字段里.

那么这些与 Java 有什么关系呢?

在 Java 里,只要一个对象的类实现了 java.io.Serializable 接口, 你就可以把一个对象存储成一个 Stream (流). 这个过程称为对象串行化 (Object Serialization), 可以用于将复杂的对象存入数据库.

现在,在 JDBC里, 你将不得不使用一个 Large Object (大对象)来存储它们. 不过,你不能在这些对象上执行查询.

org.postgresql.util.Serialize 类做的工作就是提供一个把一个对象存储为表的方法, 并且从一个表中检索出该对象.大多数情况下,你将不需要直接访问这个类, 但是你要用到 PreparedStatement.setObject() 和 ResultSet.getObject() 方法.这些方法将对照数据库里的表检查对象类的名称, 如果找到一个匹配的,它就假设该对象是一个串行化了的对象 然后从该表中检索出对象来,在这么做的同时,如果该对象包含其他串行化对象 那么它递归地检索这个嵌套树.

听起来很复杂?实际上,它比我写的要简单 - 只是解释起来困难些.

可能你访问这个类的唯一机会是使用 create() 方法. 这些不会被驱动使用, 只是对数据库执行一条或更多条 "create table" 语句 - 以你想要串行化的表或 Java 对象为基础.

哦,最后一件事情.如果你的对象包含象这样的一行:

public int oid;
那么,当对象从表里检索出来时,它被设置为表里的 oid. 然后,如果该对象被修改,然后重新串行化,那么现有的记录将被更新.

如果不存在 oid 变量,那么当对象串行化时, 它总是被插入表中,而表中任何现存的记录将保留.

在串行化之前把 oid 设为 0 将同样导致对象被插入. 这样就使在表中复制对象成为可能.

Class org.postgresql.util.Serialize

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

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

        这个方法把一个 Java 类名称转换成一个
        PostgreSQL表, 通过
        把 . 替换成 _

        参数∶
                name - PostgreSQL 表名称
  
        返回∶
                类名称

        抛出∶ SQLException
                出错时
工具类

org.postgresql.util 包包含被主驱动内部使用的类以及其他扩展.

Class org.postgresql.util.PGmoney
                                
java.lang.Object
   |
   +----org.postgresql.util.PGobject
           |
           +----org.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
                转换错误时

        覆盖∶
                PGobject 里的 setValue

 public boolean equals(Object obj)

        参数∶
                obj - 要比较的对象
                                
        返回∶
                如果两个对象相同返回真 (true)

        覆盖∶
                类 PGobject 里的 equals

 public Object clone()
                
           必须覆盖这个方法以便允许这个对象被克隆

        覆盖∶
                类 PGobject 里的 clone

 public String getValue()

        返回∶
                PostgreSQL 的语法定义的货币

        覆盖∶
               类 PGobject 里的 getValue

Class org.postgresql.util.PGobject

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

   public class PGobject extends Object implements Serializable, 
Cloneable
               
这个类用于描述标准
JDBC
不认识的数据类型
 对 org.postgresql.Connection 
的调用允许一个与这个类关联的类与一个命名类型相关联.
这就是 org.postgresql.geometric 包工作的原理.
 ResultSet.getObject() 对任何无法识别拥有自身控制器的数据类型都将返回这个类.
 因此, 任何PostgreSQL 数据类型都被支持.

构造器

 public PGobject()

          这个方法被 org.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)

        覆盖∶
                类 Object 里的 equals

 public Object clone()

          必须覆盖这个方法以便允许这个对象被克隆

        覆盖∶
                类 Object 里的 clone

 public String toString()

          这个方法在这里定义, 这样用户代码就不必重载它.
          
        返回∶
                以PostgreSQL预期的语法表示的对象值.

        覆盖∶
                类 Object 里的 toString

Class org.postgresql.util.PGtokenizer

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

   public class PGtokenizer extends Object

    这个类用于把PostgreSQL 的文本输出记号化.

   我们可以使用 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 org.postgresql.util.Serialize

这个类在前面 Object Serialisation (对象串行化)已经有文档了.

Class org.postgresql.util.UnixCrypt
              
java.lang.Object
   |
   +----org.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")的口令.
   
        参数∶
                salt - 一个两字符字串代表的所用的种子,
                        用以向加密引擎说明加密的不同方式.
                        如果你要生成一个新的密文那么这个值应该是随机生成的.
                original - 待加密口令.

        返回∶
                一个字串, 先是 2 字符的种子, 然后跟着密文口令.
              
 public static final String crypt(String original)

        加密给出的明文口令.
        这个方法用 'java.util.Random' 类生成一个随机的种子.

        参数∶
                original - 要加密的口令.
   
        返回∶ 
                一个字串, 先是 2 字符的种子, 然后跟着密文口令.
               
 public static final boolean matches(String encryptedPassword,
                                     String enteredPassword)
                 
          检查加密成 encryptedPassword 的 enteredPassword.
               
        参数∶
                encryptedPassword - 口令密文.
                                头两字符假设为种子.
                                这个字符串将与 Unix 文件 /etc/passwd 里的一样.
                enteredPassword - 
				用户输入的口令(或者其他需要的东西).

        返回∶
                如果口令被认为是正确的则返回真 (true).