GBase 8a
运维管理
文章

GBase JDBC 介绍 -1

发表于2024-08-27 19:18:45236次浏览0个评论

GBase JDBC 介绍

GBase 数据库通过提供 JDBC 驱动为使用 JAVA 程序语言的应用程序提供访问 GBase 数据库的接口,叫做 GBase JDBC。

GBase JDBC 是一种兼容 JDBC-3.0、4.0 "类型 4"的驱动,这意味着它是符 合 JDBC 3.0、4.0 版本规范的一种纯 Java 程序,并能使用 GBase 协议直接和 GBase 服务器通信。

这一章并不是完整的 JDBC 指南。如果需要了解 JDBC 的更多信息,请参考 下面的在线教程,与本章提供的内容相比,它们介绍的更为详细也更具深度:

  •  JDBC Basics – Sun 提供的 JDBC 指南,涵盖了 JDBC 的基本主题。
  •  JDBC Short Course - Sun 和 JGuru 提供的更深入的指南。

GBase JDBC 版本

GBase JDBC 8.3.81.51 提供了如下新特性:
1) 自动注册驱动(需要 jdk1.6 的)
2) National Character Set Conversion Support
GBase JDBC 8.3.81.53 提供了如下新特性:
1) 针对 GBase8a 集群提供高可用性(IP 自动路由)功能; GBase JDBC 8.3.81.53_build51.1 提供了如下新特性:
1) 针对 GBase8a 集群提供高可用性负载均衡功能;

GBase JDBC 驱动与 Server 的对应关系如下表格所示:
 

GBase JDBC 版本驱动类型JDBC 版本状态
8.3.81.53_build51.143.0、4.0推荐(集群)
8.3.81.5343.0、4.0推荐(集群)
8.3.81.5143.0、4.0推荐
8.2.0143.0稳定

GBase JDBC 基本概念

GBase JDBC 主要类与接口

GBase JDBC 由具有建立和管理与 GBase 数据库连接功能、执行 SQL 语句功 能和对结果集进行储存和管理功能的若干功能类组成。

下面是 Gbase JDBC 涉及的主要类:

 Driver类 (com.gbase.jdbc.Driver)

当注册驱动的时候或配置软件以使用 GBase JDBC 的时候,应该使用这个类 名。在使用 GBase JDBC 8.3.81.x 版本的驱动(jre1.6 及以上版本)时可以省 去注册驱动,由 java 虚拟机自动完整驱动注册。

示例:
Class.forName("com.gbase.jdbc.Driver");
 DriverManager 类(java.sql.DriverManager) 跟踪可用的驱动程序,在数据库与相应的驱动程序之间建立连接。 在应用服务器外使用 JDBC 时,DriverManager 类管理连接的确立。

需要告诉 DriverManager 应该与哪个 JDBC 驱动进行连接,最简单的方法就 是使用实现了接口 java.sql.Driver 的类的 Class.forName()方法。在 GBase JDBC 中,这个类的名字叫做 com.gbase.jdbc.Driver。用这种方法,就可以在 连接一个数据库时使用一个外部配置文件来给驱动提供类名和驱动参数。

 Connection 接口(com.gbase.jdbc. Connection)

与特定数据库的连接(会话)。在连接上下文中执行 SQL 语句并返回结果。

示例:

Connection con=DriverManager.getConnection("jdbc:gbase://host:port/dbname ","user", "password");
 Statement接口(com.gbase.jdbc.Statement)
用于执行 SQL 语句并返回结果。
 ResultSet接口(java.sql.ResultSet)
通常由执行 SQL 语句来产生。
示例:
Statement st = con.createStatement();
ResultSet rs = st.executeQuery(select c_custkey from customer);

URL 语法、JDBC Connector 配置属性

对于 GBase JDBC ,JDBC URL 的格式如下,方括号([, ])里的项是可选的:

jdbc:gbase://[host][:port]/[database][?propertyName1][=propertyV alue1][&propertyName2][=propertyValue2]...

如果没有指定数据库,这个连接将没有'当前'数据库。这种情况下,用户 需要在连接实例上调用 setCatalog()方法,或者在 SQL 中使用数据库名完整指 定表名(即 'SELECT dbname.tablename.colname FROM dbname.tablename...')。 不指定连接使用的数据库,只用在建立的连接需要使用多个库的工具时才有用, 如 GUI 数据库管理器。

示例:

Class.forName("com.gbase.jdbc.Driver");

java.sql.Connection con = DriverManager.getConnection("jdbc:gbase:///", "user", "password");

Statement st = con.createStatement();
ResultSet rs = st.executQuery(select test.testTbale.* from test.testTbale); 或者

Class.forName("com.gbase.jdbc.Driver");

java.sql.Connection con = DriverManager.getConnection("jdbc:gbase:///", "user", "password");

con.setCatalog("test");
Statement st = con.createStatement();
ResultSet rs = st.executQuery(select * from testTbale); 该示例查询了 test 数据库中的 testTbale 表的全部列数据。

属性配置定义了 GBase JDBC 将会如何连接到一个 GBase server 上。除非 有其它说明,否则可以为 DataSource 对象和 Connection 对象设置属性。

配置属性可以通过下列任意一种方式来设置:

 在 java.sql.DataSource 的 GBase 实例上使用 set*()方法:

 com.gbase.jdbc.jdbc2.optional.GBaseDataSource
 com.gbase.jdbc.jdbc2.optional.GBaseConnectionPoolDataSource

  •   在 java.util.Properties 实例中,作为一个键/值对传给 DriverManager.getConnection() 或 Driver.connect()
  •   在赋给java.sql.DriverManager.getConnection()、 java.sql.Driver.connect() 或 javax.sql.DataSource's setURL() 方法的 GBase 实例的 URL 中,作为一个 JDBC URL 变量。

    示例: Class.forName("com.gbase.jdbc.Driver");

GBaseDataSource ds = new GBaseDataSource(); ds.setUrl("jdbc:gbase://localhost:5258/test"); ds.setUser("user");
ds.setPassword("password");
java.sql.Connection con = ds.getConnection();
Statement st = con.createStatement();
ResultSet rs = st.executQuery(select c_custkey from customer); 注释:

如果用户用来配置一个 JDBC URL 的方法是基于 XML 的,那么用户需要使用 XML 特征字符&amp 来分开配置参数,“&”是 XML 的保留字符。

GBase JDBC API 实现要点

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() 方法获得被影响到的行数。

使用字符集和 Unicode

JDBC 驱动发送给服务器的所有字符串都自动地从本地的 Java Unicode 转换 到客户端的字符编码,包括所有通过 Statement.execute() 、 Statement.executeUpdate() 、 Statement.executeQuery()发送的查询以及所 有 PreparedStatement 和 CallableStatement 参数,但使用 setBytes() 、 setBinaryStream() 、setAsiiStream() 、setUnicodeStream() 和 setBlob() 的参数集不包含在内。

GBase 8a 使用 JDBC 的 ResultSets 在客户端与服务器之间传输数据支持单 一编码形式以及任意数目的编码形式。

在连接时会自动地检测客户端与服务器之间的字符编码。通过配置变量, 驱动使用的编码指定在服务器上,这个变量在 GBase 8a server 中是 “character_set_server ”。如果不想客户端自动识别编码,可以在用来连接 服务器的 URL 中使用 characterEncoding 属性,使用该属性的同时必须使用设 置“useUnicode”的值为 true。

当在客户端指定字符编码时,应该使用 Java-style 名字。下表列出了对于 GBase 字符集的 Java-style 名字:

GBase Server 字符集名Java 字符集名称
gbkGBK
utf8UTF-8

警告:在 GBase JDBC 中,不要执行“set names”来设置字符集,因为驱 动不会发现字符集已经改变,而是会继续使用在初始化连接设置时使用的字符 集。

为了允许从客户端发来的各种字符集,应当使用“UTF-8”编码,或者把 “UTF-8”配置成缺省的服务器字符集,或者通过 characterEncoding 属性配置 JDBC 驱动使用“UTF-8”。

 

评论

登录后才可以发表评论