GBase JDBC 通过了 Sun's JDBC 兼容性测试套件中的测试。然而,在许多 地方,关于如何实现特定功能,JDBC 规范并没有给出明确的规定,因此存在一 定程度的实现上的灵活性。 本节将在接口层面上讲述关于特定的实施方案中用户使用 GBase JDBC 的 方式。
Blob 可以在创建连接时通过设定参数 emulateLocators=true 来提高 Blob 类型 的效率。通过设置这个参数,驱动会推迟加载真正的 Blob 数据,直到你调用 (getInputStream(), getBytes()等方法)的时候数据才会真正加载到 blob 数 据流中。
如果使用这个参数必须满足如下条件: 必须使用带有列值的列别名,在你编写的用于检索 Blob 的 SELECT 中,将 列值设为 Blob 列的真实名称。SELECT 只能从单表检索,该表必须有 1 个主键, 而且 SELECT 必须涵盖构成主键的所有列。随后,驱动程序将延期加载实际的 Blob 数据,直至检索了 Blob 并在其上调用了检索方法为止(getInputStream(), getBytes(),等)。 例如: SELECT id, 'data' as blob_data from blobtable Blob 的实例不允许“原地”调整(它们是“副本”,正如 DatabaseMetaData.locatorsUpdateCopies()方法所指明的那样)。因此,应使 用对应的 PreparedStatement.setBlob()或 ResultSet.updateBlob()(对于可 更新结果集)方法,将变化保存到数据库中。
CallableStatement 当通过 CallableStatement 接口连接 GBase 时,支持存储过程,不支持函 数,函数可以通过 PreparedStatemen 调用。
Clob Clob 实例不允许修改(它们是复本,就像 DatabaseMetaData.locatorsUpdateCopies()方法所指明的那样)。因此,用户 可以使用对应的 PreparedStatement.setClob() 方法把变化保存回数据库。 GBase JDBC API 没有提供 ResultSet.updateClob()支持。
Connection 按照 JDBC 规范,如果在这个连接上调用了 closed(),那么它只返回 true。 如果用户需要确定这个连接是否还有效,用户应该使用一个简单的查询,如 SELECT 1。如果连接已不再有效的话,驱动会抛出一个异常。 在 GBase 8a JDBC8.3.81.x 版本之后在 jdk1.6 及以上环境中运行时,可以 调用 boolean isValid(int timeout)方法来检查一个连接是否是有效。
DatabaseMetaData DatabaseMetaData 提供数据库的结构信息。 外键信息(getImportedKeys、getExportedKeys()和 getCrossReference()) 仅仅对 GsDB 类型的表有效,但是驱动是通过 SHOW CREATE TABLE 来获取相关信 息的,所以当其他存储引擎支持外键,驱动程序同样能支持他们。
Driver 使用 Class.forName("com.gbase.jdbc.Driver")加载驱动,在使用 GBase 8a 8.3.81.x 版本的 JDBC 驱动(jre1.6 及以上版本)时可以省去注册驱动,由 java 虚拟机自动完整驱动注册。
PreparedStatement 在 GBase 8a server 中不支持预处理功能,PreparedStatement 是由驱动来 实现的。因此,驱动程序不支持 getParameterMetaData()或 getMetaData()等, 因为其需要客户端上具有完整的 SQL 语法分析程序。 当服务器支持时,会使用服务端预处理语句和二进制编码的结果集。 当使用一个带有 large 参数的服务器端预处理命令时要小心,这些参数是 通过 setBinaryStream()、setAsciiStream()、setUnicodeStream()、setBlob() 或 setClob()设置的。如果用户将 large 参数修改为不带 large 的参数后重新执 行语句,那么此用户必需先调用 clearParameters()并重置所有的参数。原因如 下:
当设置参数时(在执行预处理语句前),驱动程序会将 large 数据 out-of-band 发送到服务器端预处理语句;
一旦完成了这些,这个在客户端用于读取数据的流就会被关闭(按照 JDBC 规范),并且不能再次读取流;
如果一个参数从 large 变为非 large,那么驱动必须重置服务器端的预 处理语句状态,这样就可以允许被改变成的参数替代先前的 large 值 了。这会删除掉所有已经发送给服务器的 large 数据,因此要求通过
setBinaryStream()、 setAsciiStream()、setUnicodeStream()、 setBlob()或 setClob()方法重发数据。 因此,如果用户想把一个参数的 large 类型改成一个非 large 的类型,那 么用户必须调用 clearParameters()并在重新执行前再次设置准备好语句的所 有参数。
ResultSet 缺省情况下,ResultSets 被完整地取回并存储在内存中。在大多数情况下, 这是操作起来最有效的方式,而且由于 GBase 网络协议的设计这也更容易实现。 如果用户使用着拥有大量行或大数据的 ResultSets,而且无法在 JVM 内为所需 内存分配大量空间,可以通知驱动以“流”方式返回结果,一次一行。为了使 这个功能可用,用户需要按如下方式创建一个语句实例: stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); stmt.setFetchSize(Integer.MIN_VALUE); 这是个向前只读结果集,它读取得容量以整数为单位。MIN_VALUE 指示驱动 程序以逐行操作的方式形成“流”结果输出。 此后,任何用这个语句创建的结果集都按行检索。 使用这种方法有些要注意的地方,用户必须在当前连接上使用任何查询之 前,读出结果集中所有的行(或者关闭它),否则就是会抛出异常。 这些语句持有的锁(在 GsDB 存储引擎中,无论它们是 GsSYS 表级锁还是行 级锁),最早可以在语句完成的时候释放。 如果这个语句在一个事务的范围内,那么这些锁在事务结束时(这意味着 那条语句需要先完成)释放。和大多数其它数据库一样,语句不会完成直到所 有依赖于该语句的结果被读取或对于这个语句活跃的结果被关闭。 因此,当使用“流”结果时,如果用户想对那些被这个语句引用并产生结 果集的表保持并发访问,应当尽快地处理它们。
ResultSetMetaData 可用于获取关于 ResultSet 对象中列的类型和属性信息的对象。
Statement Statements 允许用户执行基本的 SQL 查询并且通过后面将介绍的类 ResultSet 获得结果。 调用在对象 Connection 上的 createStatement()方法,可以创建一个 Statement 实例,而这个 Connection 对象可以通过在前面介绍过的 DriverManager.getConnection()或 DataSource.getConnection()方法获得。 一旦拥有了一个 Statement 实例,就能调用 executeQuery(String)方法执 行一个 SELECT 查询。 更新数据库中的数据可以使用 executeUpdate(String SQL)方法,该方法返 回由更新语句影响到的行数。 如果事先不知道 SQL 语句将执行一个 SELECT 操作还是一个 UPDATE/INSERT 操作,那么就可以使用 execute(String SQL)方法。如果 SQL 查询是一个 SELECT, 该方法返回 true,如果是一个 UPDATE/INSERT/DELETE 查询时返回 false。并且, 如果是一个 SELECT 查询,可以调用 getResultSet()方法获得结果,如果是一个 UPDATE/INSERT/DELETE 查询,可以调用 Statement 实例上的 getUpdateCount() 方法获得被影响到的行数。




