联 系 我 们
售前咨询
售后咨询
微信关注:星环科技服务号
更多联系方式 >
6.4.2 基于 JDBC 开发
更新时间:11/2/2023, 7:27:03 AM

JDBC( Java 数据库连接)是一种用于执行 SQL 语句的 Java API,提供查询、更新数据库中数据的方法,工作流程如下:

jdbc dev flow
图 6.2.1:JDBC 工作流程

我们为您准备了丰富的教程,帮助您快速开发 Java 程序来连接和读写 ArgoDB 数据库,您可以按序阅读,也可以选择阅读所需文档:

  • 首次尝试开发:您可以阅读开发流程了解基本开发步骤,然后基于示例代码简单修改即可。

  • 熟悉开发流程:您可以阅读 JDBC 参考,快速查找相关接口的使用说明。

下载 JDBC 驱动

JDBC 或 ODBC 驱动程序用于连接 Transwarp ArgoDB 数据库,在开发应用程序前,您需要登录 Transwarp Manager 平台下载相关驱动程序。

操作步骤
  1. 登录 Transwarp Manager 平台。

  2. 在集群页面的 Transwarp ArgoDB 区域框中,找到并单击运行中的 Quark 组件。

  3. 单击页面右上角的 图标,然后选择下载 JDBC 或 ODBC 驱动。

    download jdbc driver
    图 6.2.2:下载 JDBC 驱动
  4. 在弹出的面板中,单击下载(推荐下载 All-in-one 包)。

常用 API 介绍

JDBC API 提供来自 Java 编程语言的通用数据访问,主要位于 java.sql 包中,定义了访问数据库的接口和类,常用的 API 如下:

  • DriverManager:负责加载各种不同驱动程序(Driver),并根据不同的请求,向调用者返回相应的数据库连接(Connection)。

  • Driver:驱动程序,负责将自身加载到 DriverManager 中去,并处理相应的请求并返回相应的数据库连接(Connection)。

  • Connection:数据库连接,负责进行与数据库间的通讯,SQL 执行以及事务处理都是在某个特定 Connection 环境中进行的。可以产生用以执行 SQL 的 Statement。

  • Statement:用以执行 SQL 查询和更新(针对静态 SQL 语句和单次执行)。

  • PreparedStatement:用以执行包含动态参数的 SQL 查询和更新(在服务器端编译,允许重复执行以提高效率)。

  • CallableStatement:用以调用数据库中的存储过程。

  • SQLException:代表在数据库连接的创建和关闭和 SQL 语句的执行过程中发生了例外情况(即错误)。

开发流程

ArgoDB 支持完整的 SQL 标准语法,可兼容 Oracle、IBM DB2、Teradata 方言,本章节中,我们将介绍如何开发 Java 应用程序对 ArgoDB 数据进行操作,通用开发流程如下:

在开发 Java 应用程序前,请确保 JDK 版本为 1.8 及以上。

jdbc reaction
图 6.2.3:JDBC 开发流程

接下来,我们将介绍各步骤的详细操作及示例代码供您参考:

  1. 在项目中加载您下载的驱动包,以 IntelliJ IDEA 开发工具为例,流程如下:

    1. 在 IntelliJ IDEA 顶部,选择 File > Project Structure

    2. 在弹出的对话框单击 Modules 页签,然后单击右侧的 Dependencies 页签。

    3. 单击 + > JARs or Directories…,然后选择您下载的驱动以完成加载。

      load jdbc jars
      图 6.2.4:加载驱动
  2. 开始编写项目中的 Java 代码,首先我们在代码中加载 jar 包 和 JDBC 驱动。

    // 导入 jar 包
    import java.sql.*;
    // 加载 JDBC 驱动
    Class.forName("org.apache.hive.jdbc.HiveDriver");
    复制
  3. 在 DriverManager 中,使用 DriverManager.getConnection() 方法获取数据库连接(Connection)。

    下述示例代码以连接免认证的 ArgoDB 数据库为例,如数据库开启了认证,请参考示例代码章节

    String jdbcURL = "jdbc:transwarp2://<host_ip>:<port>/<database_name>;<JDBC_Conf>?<ArgoDB_Conf>";
    Connection conn = DriverManager.getConnection(jdbcURL);
    复制
    • <host_ip>:数据库的连接地址,即 Quark 组件的服务地址,您可以登录 Transwarp Manager 平台,找到 Quark 组件并获取其服务地址。

    • <port>:数据库服务端口,默认为 10000。

    • <database_name>:要连接的数据库名。

    • <JDBC_Conf>:JDBC 连接参数,多个参数间通过英文分号(;)分隔,常见参数如下:

      • limitSelect:限制 select 的结果集的行数,例如:jdbc:transwarp2://localhost:10000/default;limitSelect=0

      • fetchSize:修改数据库交互时,每次提取出来的记录行总数,例如:jdbc:transwarp2://localhost:10000/default;fetchSize=2000

      • autoReconnect:连接出错后自动重连,例如:jdbc:transwarp2://localhost:10000/default;autoReconnect=true

    • <ArgoDB_Conf>:ArgoDB 连接参数,多个参数间通过英文分号(;)分隔,常用参数为 ngmr.execute.mode,即设置 Inceptor 的执行模式。

      例如设置为 local 模式,适用于低延时、高并发、参与计算数据量少的场景:jdbc:transwarp2://localhost:10000/default;limitSelect=1?ngmr.execute.mode=local

  4. 提交 SQL 语句至数据库执行,可使用 StatementPreparedStatement 构建。

    • Statement 构建方式

      Statement stmt = conn.createStatement();
      stmt.executeUpdate( "insert into table_test values(a,a)" );
      stmt.executeUpdate( "delete from table_test where col1=a" );
      stmt.executeQuery( "select * from table_test" );
      stmt.execute( "begin transaction" );
      复制
    • PreparedStatement 构建方式

      ps = conn.prepareStatement( "SELECT i.*, j.* FROM Omega i, Zappa j WHERE i = ? AND j = ?" );
      ps.setString(1, "Poor Yorick");
      ps.setInt(2, 8008);
      rs = ps.executeQuery();
      复制
  5. (可选)通过 JDBC 执行事务。

    默认情况下,处于自动提交模式,即每执行一条 SQL 都是作为事务自动执行的,您也可以使用 begin transaction,可以在一个事务中执行多条语句,事务以 commit 结束。

    stmt.execute("begin transaction");
    stmt.executeUpdate(SQL 1);
    stmt.executeUpdate(SQL 2);
    stmt.executeUpdate(SQL 3);
    stmt.execute("commit");
    复制
  6. 使用 ResultSet.getXXX() 方法获取数据结果。

    int numColumns = rs.getMetaData().getColumnCount();
    while ( rs.next() ) {
    for ( int i = 1 ; i <= numColumns ; i++ ) {
    System.out.println( "COLUMN " + i + " = " + rs.getObject(i) );
    }
    }
    复制
  7. 关闭所有的数据库资源。

    rs.close();
    stmt.close();
    conn.close();
    复制
异常处理

异常处理允许我们以受控的方式处理异常情况,而不是直接退出程序。例如数据库操作失败,JDBC 将抛出一个 SQLException,此类异常很少能够恢复,此时需要尽可能详细地打印异常日志,将 SQLException 翻译成应用程序领域相关的异常(非强制处理异常),然后回滚数据库并通知用户。

示例代码

为帮助您更好地上手 ArgoDB 相关应用程序的开发,下文提供了不同验证模式下,与 ArgoDB 进行交互的相关代码功能参考。

与免认证的 ArgoDB 交互

当 ArgoDB 未开启认证时,您可以参考下述代码连接并操作 ArgoDB,相关说明请参考代码中的注释。

package demo;
import java.sql.*;
public class JDBCExample {

  // 驱动程序
  private static String driverName = "org.apache.hive.jdbc.HiveDriver";

  public static void main(String[] args) throws SQLException {
    try {
      Class.forName(driverName);
      // 加载驱动
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
      System.exit(1);
    }
    // 本示例连接至 default 数据库,您也可以指定要连接的数据库
    String jdbcURL = "jdbc:transwarp2://172.18.130.13:10000/default";
    Connection conn = DriverManager.getConnection(jdbcURL);
            // 执行查询并获取结果
    Statement  stmt = conn.createStatement();
    ResultSet rs = stmt.executeQuery("select * from table_jdbc");
    ResultSetMetaData rsmd = rs.getMetaData();
    int size = rsmd.getColumnCount();
    while(rs.next()) {
      StringBuffer value = new StringBuffer();
      for(int i = 0; i < size; i++) {
        value.append(rs.getString(i+1)).append("\t");
      }
    // 获取输出结果并关闭连接
    System.out.println(value.toString());
    }
    rs.close();
    stmt.close();
    conn.close();
  }
}
复制
与启用 Kerberos 认证的 ArgoDB 交互

当 ArgoDB 启用了 Kerberos 认证时,您可以参考下述代码连接并操作 ArgoDB。

import java.sql.*;

public class JDBCExample {
  // 驱动程序
  private static String driverName = "org.apache.hive.jdbc.HiveDriver";

  public static void main(String[] args) throws SQLException {
    try {
      Class.forName(driverName);
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
      System.exit(1);
    }

    // 建立连接
    String jdbcURL = "jdbc:transwarp2://localhost:10000/default;principal=hive/node@TDH;"+ (1)
        "authentication=kerberos;"+
        "kuser=user_principal;"+ (2)
        "keytab=keytab_path;"+ (3)
        "krb5conf=krb5.conf_path"; (4)
    Connection conn = DriverManager.getConnection(jdbcURL);
    // 执行查询并获取结果
    Statement  stmt = conn.createStatement();
    ResultSet rs = stmt.executeQuery("select c1, c2 from table1");
    ResultSetMetaData rsmd = rs.getMetaData();
    int size = rsmd.getColumnCount();
    while(rs.next()) {
      StringBuffer value = new StringBuffer();
      for(int i = 0; i < size; i++) {
        value.append(rs.getString(i+1)).append("\t");
      }
    // 获取输出结果并关闭连接
    System.out.println(value.toString());
    }
    rs.close();
    stmt.close();
    conn.close();
  }
}
复制
1 连接至开启 Kerberos 认证的 ArgoDB 的 JDBC 连接串,格式为 jdbc:transwarp2://<host_ip>:10000/<database_name>;principal=<username>/node@TDH;
  • <host_ip>:数据库的连接地址。

  • <database_name>:连接的数据库名。

  • <username>:Kerberos 中 Principal 的用户名,默认为 hive。

2 kuser:将值设置为 ArgoDB server的用户的 principal。
3 keytab_path:将值设置为 user_principal 对应 keytab 文件的绝对路径 。

目前尚不支持在应用程序中使用 principal + 密码的认证方式。

4 krb5.conf_path:将值设置为 Kerberos 配置文件 krb5.conf 的绝对路径 。
与启用 LDAP 认证的 ArgoDB 交互

当 ArgoDB 启用了 LDAP 认证时,您可以参考下述代码连接并操作 ArgoDB。

import java.sql.*;
public class JDBCExample {

  // 驱动程序
  private static String driverName = "org.apache.hive.jdbc.HiveDriver";

  public static void main(String[] args) throws SQLException {
    try {
      Class.forName(driverName);
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
      System.exit(1);
    }

    // 连接数据库,本示例连接至 default 数据库,您也可以指定要连接的数据库
    String jdbcURL = "jdbc:transwarp2://localhost:10000/default";
    // 访问 ArgoDB 的用户名。
    String user = "user";
    // 用户名对应的密码。
    String password = "password";
    Connection conn = DriverManager.getConnection(jdbcURL, user, password);
    // 执行查询并获取结果
    Statement  stmt = conn.createStatement();
    ResultSet rs = stmt.executeQuery("select c1, c2 from table1");
    ResultSetMetaData rsmd = rs.getMetaData();
    int size = rsmd.getColumnCount();
    while(rs.next()) {
      StringBuffer value = new StringBuffer();
      for(int i = 0; i < size; i++) {
        value.append(rs.getString(i+1)).append("\t");
      }
    // 获取输出结果并关闭连接
    System.out.println(value.toString());
    }
    rs.close();
    stmt.close();
    conn.close();
  }
}
复制
JDBC 接口参考

本章节介绍 JDBC 4 支持的接口及返回类型功能参考,包含:

java.sql.Connection

数据库连接接口,相关方法名和返回值类型如下。

方法名 返回值类型

close()

void

commit()

void

createStatement()

Statement

getAutoCommit()

boolean

getClientInfo()

Properties

getClientInfo(String name)

String

getTransactionIsolation()

int

isClosed()

boolean

isReadOnly()

boolean

prepareStatement(String sql)

PreparedStatement

rollback()

void

setAutoCommit(boolean autoCommit)

void

setClientInfo(Properties properties)

void

setClientInfo(String name,String value)

void

java.sql.CallableStatement

存储过程执行接口,相关方法名和返回值类型如下。

方法名 返回值类型

registerOutParameter(int parameterIndex, int type)

void

wasNull()

boolean

getString(int parameterIndex)

String

getBoolean(int parameterIndex)

boolean

getByte(int parameterIndex)

byte

getShort(int parameterIndex)

short

getInt(int parameterIndex)

int

getLong(int parameterIndex)

long

getFloat(int parameterIndex)

float

getDouble(int parameterIndex)

double

getBigDecimal(int parameterIndex)

BigDecimal

getBytes(int parameterIndex)

byte[]

getDate(int parameterIndex)

Date

getTime(int parameterIndex)

Time

getTimestamp(int parameterIndex)

Timestamp

getObject(int parameterIndex)

Object

java.sql.DatabaseMetaData

数据库对象定义接口,相关方法名和返回值类型如下。

方法名 返回值类型

getTables(String catalog,String schemaPattern, String tableNamePattern, String[] types)

ResultSet

getColumns(String catalog,String schemaPattern, String tableNamePattern, String columnNamePattern)

ResultSet

getTableTypes()

ResultSet

getUserName()

String

isReadOnly()

boolean

nullsAreSortedHigh()

boolean

nullsAreSortedLow()

boolean

nullsAreSortedAtStart()

boolean

nullsAreSortedAtEnd()

boolean

getDatabaseProductName()

String

getDatabaseProductVersion()

String

getDriverName()

String

getDriverVersion()

String

getDriverMajorVersion()

int

getDriverMinorVersion()

int

usesLocalFiles()

boolean

usesLocalFilePerTable()

boolean

supportsMixedCaseIdentifiers()

boolean

storesUpperCaseIdentifiers()

boolean

storesLowerCaseIdentifiers()

boolean

supportsMixedCaseQuotedIdentifiers()

boolean

storesUpperCaseQuotedIdentifiers()

boolean

storesLowerCaseQuotedIdentifiers()

boolean

storesMixedCaseQuotedIdentifiers()

boolean

supportsAlterTableWithAddColumn()

boolean

supportsAlterTableWithDropColumn()

boolean

supportsColumnAliasing()

boolean

nullPlusNonNullIsNull()

boolean

supportsConvert()

boolean

supportsConvert(int fromType, int toType)

boolean

supportsTableCorrelationNames()

boolean

supportsDifferentTableCorrelationNames()

boolean

supportsExpressionsInOrderBy()

boolean

supportsOrderByUnrelated()

boolean

supportsGroupBy()

boolean

supportsGroupByUnrelated()

boolean

supportsGroupByBeyondSelect()

boolean

supportsLikeEscapeClause()

boolean

supportsMultipleResultSets()

boolean

supportsMultipleTransactions()

boolean

supportsNonNullableColumns()

boolean

supportsMinimumSQLGrammar()

boolean

supportsCoreSQLGrammar()

boolean

supportsExtendedSQLGrammar()

boolean

supportsANSI92EntryLevelSQL()

boolean

supportsANSI92IntermediateSQL()

boolean

supportsANSI92FullSQL()

boolean

supportsIntegrityEnhancementFacility()

boolean

supportsOuterJoins()

boolean

supportsFullOuterJoins()

boolean

supportsLimitedOuterJoins()

boolean

isCatalogAtStart()

boolean

supportsSchemasInDataManipulation()

boolean

supportsSavepoints()

boolean

supportsResultSetHoldability(int holdability)

boolean

getResultSetHoldability()

int

getDatabaseMajorVersion()

int

getDatabaseMinorVersion()

int

getJDBCMajorVersion()

int

getJDBCMinorVersion()

int

java.sql.Driver

数据库驱动接口,相关方法名和返回值类型如下。

方法名 返回值类型

acceptsURL(String url)

boolean

connect(String url, Properties info)

Connection

jdbcCompliant()

boolean

getMajorVersion()

int

getMinorVersion()

int

java.sql.PreparedStatement

预处理语句接口,相关方法名和返回值类型如下。

方法名 返回值类型

clearParameters()

void

execute()

boolean

executeQuery()

ResultSet

excuteUpdate()

int

getMetaData()

ResultSetMetaData

setBoolean(int parameterIndex, boolean x)

void

setBigDecimal(int parameterIndex,BigDecimal x)

void

setByte(int parameterIndex, byte x)

void

setBytes(int parameterIndex, byte[]x)

void

setDate(int parameterIndex, Date x)

void

setDouble(int parameterIndex, doublex)

void

setFloat(int parameterIndex, float x)

void

setInt(int parameterIndex, int x)

void

setLong(int parameterIndex, long x)

void

setShort(int parameterIndex, short x)

void

setString(int parameterIndex, String x)

void

addBatch()

void

executeBatch()

int[]

clearBatch()

void

java.sql.ResultSet

执行结果集接口,相关方法名和返回值类型如下。

方法名 返回值类型

findColumn(String columnLabel)

int

getBigDecimal(int columnIndex)

BigDecimal

getBigDecimal(String columnLabel)

BigDecimal

getBoolean(int columnIndex)

boolean

getBoolean(String columnLabel)

boolean

getByte(int columnIndex)

byte

getBytes(int columnIndex)

byte[]

getByte(String columnLabel)

byte

getBytes(String columnLabel)

byte[]

getDate(int columnIndex)

Date

getDate(String columnLabel)

Date

getDouble(int columnIndex)

double

getDouble(String columnLabel)

double

getFloat(int columnIndex)

float

getFloat(String columnLabel)

float

getInt(int columnIndex)

int

getInt(String columnLabel)

int

getLong(int columnIndex)

long

getLong(String columnLabel)

long

getShort(int columnIndex)

short

getShort(String columnLabel)

short

getString(int columnIndex)

String

getString(String columnLabel)

String

getTime(int columnIndex)

Time

getTime(String columnLabel)

Time

getTimestamp(int columnIndex)

Timestamp

getTimestamp(String columnLabel)

Timestamp

isAfterLast()

boolean

isBeforeFirst()

boolean

isFirst()

boolean

next()

boolean

java.sql.ResultSetMetaData

描述 ResultSet 对象的相关信息,相关方法名和返回值类型如下。

方法名 返回值类型

getColumnCount()

int

getColumnName(int column)

String

getColumnType(int column)

int

getColumnTypeName(int column)

String

java.sql.Statement

SQL 语句接口,相关方法名和返回值类型如下。

方法名 返回值类型

close()

void

execute(String sql)

boolean

executeQuery(String sql)

ResultSet

executeUpdate(String sql)

int

getConnection()

Connection

getResultSet()

ResultSet

getQueryTimeout()

int

getUpdateCount()

int

isClosed()

boolean

setQueryTimeout(int seconds)

void

setFetchSize(int rows)

void

cancel()

void

javax.sql.ConnectionPoolDataSource

数据源连接池接口,相关方法名和返回值类型如下。

方法名 返回值类型

getLoginTimeout()

int

getLogWriter()

PrintWriter

getPooledConnection()

PooledConnection

getPooledConnection(String user,String password)

PooledConnection

setLoginTimeout(int seconds)

void

setLogWriter(PrintWriter out)

void

javax.sql.DataSource

数据源接口,相关方法名和返回值类型如下。

方法名 返回值类型

getConneciton()

Connection

getConnection(String username,String password)

Connection

getLoginTimeout()

int

getLogWriter()

PrintWriter

setLoginTimeout(int seconds)

void

setLogWriter(PrintWriter out)

void

javax.sql.PooledConnection

由连接池创建的连接接口,相关方法名和返回值类型如下。

方法名 返回值类型

addConnectionEventListener(ConnectionEventListener listener)

void

close()

void

getConnection()

Connection

removeConnectionEventListener(ConnectionEventListener listener)

void

addStatementEventListener(StatementEventListener listener)

void

removeStatementEventListener(StatementEventListener listener)

void