#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型数据。 |