#YashanDB JDBC驱动使用介绍

# 连接数据库

# 连接方式

YashanDB JDBC驱动提供如下两种建立数据库连接的方法:

DriverManager连接

可通过如下三个DriverManager方法建立数据库连接:

  • DriverManager.getConnection(String url);
  • DriverManager.getConnection(String url, Properties info);
  • DriverManager.getConnection(String url, String user, String password);

YasDataSource连接

通过YashanDB提供的YasDataSource类建立数据库连接:

  • YasDataSource ads = new YasDataSource();

参数说明

参数 描述
url 数据库连接描述符。格式如下: jdbc:yasdb://host:port/database_name
* database_name:数据库名称;(保留参数,必填,但不校验内容)
* host:主机域名或IP地址,需配置为单机/集群实例服务器地址或分布式CN服务器地址,不填时表示连接localhost主机;
* port:数据库服务端口,如1688。
user 数据库用户名。
password 数据库用户密码。
info 数据库连接属性。

示例

//DriverManager方法
public static Connection getConnection(String username, String passwd) {
        //驱动类。
        String driver = "com.yashandb.jdbc.Driver";
        //数据库连接描述符。
        String sourceURL = "jdbc:yasdb://10.10.10.2:1688/yasdb";
        Connection conn = null;
         
        try {
            //加载驱动。
            Class.forName(driver);
        } catch( Exception e ) {
            e.printStackTrace();
            return null;
        }
         
        try {
             //创建连接。
            conn = DriverManager.getConnection(sourceURL, username, passwd);
            System.out.println("Connection succeed!");
        } catch(Exception e) {
            e.printStackTrace();
            return null;
        }
         
        return conn;
    }
 
//YasDataSource
public static Connection getConnDS() {
    Connection connect = null;
    try {
      YasDataSource ads = new YasDataSource();
      ads.setURL(url);
      connect = ads.getConnection(user, password);
    } catch (Exception e) {
      e.printStackTrace();
    }
    return connect;
  }

# 特殊连接格式

上述参数说明中的url为基本连接配置格式,YashanDB JDBC驱动还支持一些特殊连接格式的配置。

# 超时时间配置

YashanDB JDBC驱动建立了超时处理机制,并允许通过配置超时时间让程序在指定期限达到时进行友好退出。

可供配置的超时时间及说明在下表中列出:

超时时间 说明
connectTimeout 建立连接时,创建socket连接的超时时间,单位为s。不配置时默认为10s。通过info属性或者url配置。
socketTimeout 获取connection后,TCP通信过程中,客户端等待服务端返回数据的超时时间,单位为s。不配置时默认为0s,一直等待。通过info属性或者url配置。
loginTimeout 创建socket成功后,进行登录认证时,客户端等待服务端返回数据的超时时间,单位为s。不配置时默认为300s。通过info属性或者url配置。
sql执行超时时间 通过statement接口setQueryTimeout配置。不配置时默认无超时时间,一直等待。

connectTimeout, socketTimeout, loginTimeout通过url进行配置时的格式示例如下:

jdbc:yasdb://192.168.1.1:1688/yashan?connectTimeout=60&socketTimeout=120&loginTimeout=60

# 连接模式配置

通过serverMode参数控制连接模式,不配置默认为shared模式。

连接模式 说明
dedicated 表示连接专用服务器模式
shared 表示连接共享服务器模式

url连接配置示例:

jdbc:yasdb://192.168.1.1:1688/yashan?connecTimeout=60&socketTimeout=120&loginTimeout=60&serverMode=dedicated

# 多IP/PORT连接配置

在高可用主备和负载均衡场景下,可以配置多个IP/PORT连接,url参数格式为:

jdbc:yasdb:serverType://host1:port1,host2:port2,host3:port3/databasename

serverType表示服务类型,可以为如下值:

  • primary:表示一主多备连接,JDBC将自动识别出主节点并连接。

例如: jdbc:yasdb:primary://192.168.1.1:1688,192.168.1.2:1688,192.168.1.3:1688/yashan

对于主备服务类型,可以配置JDBC连接主Host的超时时间。

配置项:poolTimeout,单位为秒,默认300s。

url配置示例:

jdbc:yasdb:primary://192.168.1.1:1688,192.168.1.2:1688,192.168.1.3:1688/yashan?poolTimeout=180
  • loadBalance,表示负载均衡连接,JDBC将自动识别出连接数最少的节点并连接。

示例

jdbc:yasdb:loadBalance://192.168.1.1:1688,192.168.1.2:1688,192.168.1.3:1688/yashan

serverType可以不配置,在输入多IP模式下,默认创建一主多备连接。

# SSL加密通信连接配置

在服务端打开了SSL开关时,JDBC需要配置根证书路径。

配置项:sslRootCer,为SSL加密通信根证书的标准路径,可以为绝对路径或相对路径。

url连接配置示例:

jdbc:yasdb://192.168.1.1:1688/yashan?sslRootCer=./ca.crt

# 透明应用故障转移TAF配置

TAF相关参数如下:

参数 类型 描述
failover string 该参数表示TAF是否开启,当故障发生的时候,TAF会链接到已配置的其他数据库节点,由ON和OFF两个可选值,默认OFF。ON表示开启TAF,OFF表示关闭。(当前不支持OFF状态下自动重连当前数据库节点。)
failoverType string TAF的类型,NONE,SESSION,SELECT三种类型,目前不支持SELECT,默认NONE,NONE表示关闭TAF。
failoverMethod string TAF模式,由BASIC和PRECONNECT两个可选值,目前只支持BASIC,默认BASIC。
failoverRetries int 重试次数,默认5次。
failoverDelay int 重试间隔时间,单位秒,默认1秒。

url连接配置示例:

jdbc:yasdb://192.168.1.1:1688/yashan?failover=on&failoverType=session&failoverMethod=basic&failoverRetries=5&failoverDelay=1

# 心跳连接的配置

开启心跳连接能够使得程序更快的检测到正在使用的连接已经异常,从而跳出当前等待返回数据的状态,从而触发后续的操作,例如故障恢复。

心跳连接相关参数如下:

参数 类型 描述
heartbeatSwitch string 该参数表示心跳连接是否开启,由ON和OFF两个可选值,默认ON。
heartbeatSocketTimeout int 心跳连接的保活超时时间,单位秒,默认60秒。
heartbeatSchedulePeriod int 心跳连接的保活间隔时间,单位秒,默认20秒。

url连接配置示例:

jdbc:yasdb://192.168.1.1:1688/yashan?heartbeatSwitch=on&heartbeatSocketTimeout=60&heartbeatSchedulePeriod=20

# 执行SQL

# 执行普通SQL

JDBC应用程序通过执行SQL语句来操作数据库的数据(不用传递参数的语句),按以下步骤进行:

1. 调用Connection的createStatement方法创建语句对象。

Statement stmt = con.createStatement();

2. 调用Statement的execute方法执行SQL语句。

stmt.execute("CREATE TABLE table_example(id INTEGER, name VARCHAR(32))");

3. 关闭语句对象。

stmt.close();

# 执行绑定参数的SQL

JDBC应用程序通过执行SQL语句来操作数据库的数据(绑定参数的语句),按以下步骤进行:

1.调用Connection的prepareStatement方法创建语句对象。

PreparedStatement pstmt = conn.prepareStatement("insert into tb1(col1) values(?)");

2.调用set方法传参数。

pstmt.setObject(1, 1);

Note: 预编译SQL中如果使用:name形式占位符且多处同名,按位置绑定值时需要绑定多次。通常同名占位符位置绑定的是相同值。

3.调用PreparedStatement的execute方法执行SQL语句。

pstmt.execute();

4.关闭语句对象。

pstmt.close();

Note: 使用pstmt.setString接口传入字符串时,需注意以下场景:

  Statement stmt = conn.createStatement();
  stmt.execute("CREATE TABLE T1(id INT, data CHAR(10))");
  stmt.execute("INSERT INTO T1 VALUES(1, 'abc')");
  stmt.execute("COMMIT");
  
  PreparedStatement pstmt = conn.prepareStatement("select id from t1 where data=?");
  pstmt.setString(1, "abc");
  pstmt.execute();
  
  // 对查询结果进行处理

用例在23.1版本之前和之后的查询结果会有不同,在23.1版本之前能查询出结果,但是在23.1及之后的版本WHERE条件无法匹配成功。差异源于23.1及之后的版本有变量窥视功能,YaShanDB对于语句待绑定参数的预推导类型逻辑发生了变化。具体解释可以查看变量窥视的介绍。

对于绑定参数执行场景,JDBC客户端会先向服务端发送prepare命令然后发送绑定参数执行。

可以开启直接执行支持绑定参数配置,将prepare sql和绑定参数一起发给服务端,减少网络交互。

开启方式:

配置/接口 说明 示例
clientPrepare配置参数 开启直接执行带绑定参数;
设置true或者 false;
jdbc:yasdb://192.168.1.1:1688/yashan?clientPrepare=true
void setClientPrepare(boolean clientPrepare) YasConnection接口扩展方法 Connection connection = DriverManager.getConnection(url); ((YasConnection)connection).setClientPrepare(true);

示例:

  Connection conn = getConnection("sales", "sales");
  ((YasConnection)conn).setClientPrepare(true);
  PreparedStatement preparedStatement = conn.prepareStatement("select ? from dual");

  Clob clob = conn.createClob();
  String testLobString = "test clob direct bind";
  clob.setString(1, testLobString);
  preparedStatement.setClob(1, clob);
  preparedStatement.execute();

  ResultSet resultSet = preparedStatement.getResultSet();
  resultSet.next();
  Clob clob1 = resultSet.getClob(1);
  clob.free();
  resultSet.close();

  preparedStatement.setInt(1,1);
  preparedStatement.execute();
  
  resultSet = preparedStatement.getResultSet();
  resultSet.next();
  int iValue1 = resultSet.getInt(1);
  resultSet.close();

  preparedStatement.close();
  conn.close();

# 获取结果集

# 设置结果集类型

不同类型的结果集有各自的应用场景,应用程序需要根据实际情况选择相应的结果集类型。在执行SQL语句的过程中,都需要先创建相应的语句对象。而部分创建语句对象的方法提供了设置结果集类型的功能。涉及的Connection的方法如下:

//创建一个Statement对象。
createStatement();
 
//创建一个PreparedStatement对象。
prepareStatement(String sql);
 
//创建一个CallableStatement对象。
prepareCall(String sql);

结果集类型说明如下所示:

参数 描述
resultSetType 表示结果集的类型,具体有三种类型:
* ResultSet.TYPE_FORWARD_ONLY:ResultSet只能向前移动,是缺省值。
* ResultSet.TYPE_SCROLL_SENSITIVE:在修改后重新滚动到修改所在行,可以看到修改后的结果。
* ResultSet.TYPE_SCROLL_INSENSITIVE:对可修改例程所做的编辑不进行显示。
resultSetConcurrency 表示结果集的并发,具体有两种类型: 
* ResultSet.CONCUR_READ_ONLY:如果不从结果集中的数据建立一个新的更新语句,不能对结果集中的数据进行更新。
* ResultSet.CONCUR_UPDATEABLE:可改变的结果集。对于可滚动的结果集,可对结果集进行适当的改变。

# 在结果集中定位

ResultSet对象具有指向其当前数据行的光标。最初,光标被置于第一行之前。next方法将光标移动到下一行;因为该方法在ResultSet对象没有下一行时返回false,所以可以在while循环中使用它来迭代结果集。但对于可滚动的结果集,JDBC驱动程序提供更多的定位方法,如下所示:

# 在结果集中定位的方法

方法 描述
next() 把ResultSet向下移动一行。
previous() 把ResultSet向上移动一行。
beforeFirst() 把ResultSet定位到第一行之前。
afterLast() 把ResultSet定位到最后一行之后。
first() 把ResultSet定位到第一行。
last() 把ResultSet定位到最后一行。
absolute(int) 把ResultSet移动到参数指定的行数。
relative(int) 向前或者向后移动参数指定的行。

# 获取结果集光标位置

方法 描述
isFirst() 是否在一行。
isLast() 是否在最后一行。
isBeforeFirst() 是否在第一行之前。
isAfterLast() 是否在最后一行之后。
getRow() 获取当前在第几行。

# 获取结果集中的数据

方法 描述
boolean getBoolean(int columnIndex) 按列标获取bool型数据。
boolean getBoolean(String columnLabel) 按列名获取bool型数据。
byte getByte(int columnIndex) 按列标获取Byte型数据。
byte getByte(String columnLabel) 按列名获取Byte型数据。
short getShort(int columnIndex) 按列标获取short型数据。
short getShort(String columnLabel) 按列名获取short型数据。
long getLong(int columnIndex) 按列标获取long型数据。
long getLong(String columnLabel) 按列名获取long型数据
float getFloat(int columnIndex) 按列标获取float型数据。
float getFloat(String columnLabel) 按列名获取float型数据。
double getDouble(int columnIndex) 按列标获取double型数据。
double getDouble(String columnLabel) 按列名获取double型数据
BigDecimal getBigDecimal(int columnIndex) 按列标获取BigDecimal 型数据。
BigDecimal getBigDecimal(String columnLabel) 按列名获取BigDecimal 型数据。
byte[] getBytes(int columnIndex) 按列标获取byte[]数据。
byte[] getBytes(String columnLabel) 按列名获取byte[]数据。
int getInt(int columnIndex) 按列标获取int型数据。
int getInt(String columnLabel) 按列名获取int型数据。
RowId getRowId(int columnIndex) 按列标获取RowId型数据。
RowId getRowId(String columnLabel) 按列名获取RowId型数据。
String getString(int columnIndex) 按列标获取String型数据。
String getString(String columnLabel) 按列名获取String型数据。
Time getTime(int columnIndex) throws SQLException; 按列标获取Time型数据。
Time  getTime(String columnLabel) throws SQLException; 按列名获取Time型数据。
Timestamp getTimestamp(int columnIndex) 按列标获取TimeStamp型数据。
Timestamp getTimestamp(String columnLabel) 按列名获取TimeStamp型数据。
Date getDate(int columnIndex) 按列标获取Date型数据
Date getDate(String columnLabel) 按列名获取Date型数据。