JDBC
注意: 目前的JDBC实现仅是为与第三方工具连接使用的。不推荐使用 JDBC (执行插入语句时),因无法提供高性能写入,查询推荐使用 JDBC。
对于Java应用,我们推荐使用Java 原生接口 。
1. 使用方式
环境要求:
JDK >= 1.8
Maven >= 3.6
获取依赖包:
联系技术支持获取依赖包udbds-jdbc-${version}-jar-with-dependencies.jar
安装依赖包至本地仓库:
mvn install:install-file \
-Dfile=/parh/to/jar/udbds-jdbc-${version}-jar-with-dependencies.jar \
-DgroupId=com.unvdb.udbds \
-DartifactId=udbds-jdbc \
-Dversion=${version} \
-Dpackaging=jar \
-Dclassifier=jar-with-dependencies \
-DgeneratePom=true
在maven中添加依赖:
<dependencies>
<dependency>
<groupId>com.unvdb.udbds</groupId>
<artifactId>udbds-jdbc</artifactId>
<version>${version}</version>
<classifier>jar-with-dependencies</classifier>
</dependency>
</dependencies>
2. 示例代码
本章提供了如何建立数据库连接、执行 SQL 和显示查询结果的示例。
要求您已经在工程中包含了数据库编程所需引入的包和 JDBC class.
注意:为了更快地插入,建议使用 executeBatch()
import com.unvdb.udbds.jdbc.UDBDSSQLException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.time.LocalDate;
import java.util.Properties;
public class JDBCExample {
private static final Logger LOGGER = LoggerFactory.getLogger(JDBCExample.class);
public static void main(String[] args) throws ClassNotFoundException, SQLException {
final Properties info = new Properties();
info.put("user", "root");
info.put("password", "root");
/*
* TLCP协议配置说明:
* 1. 启用协议前需配置JVM模块开放参数(适用于JDK9+):
* --add-opens=java.base/javax.crypto=ALL-UNNAMED
* --add-opens=java.base/sun.security.util=ALL-UNNAMED
* --add-opens=java.base/sun.security.x509=ALL-UNNAMED
* --add-opens=java.base/sun.security.pkcs12=ALL-UNNAMED
* --add-exports=java.base/jdk.internal.access=ALL-UNNAMED
* --add-exports=java.base/sun.net.util=ALL-UNNAMED
* --add-exports=java.base/sun.security.pkcs=ALL-UNNAMED
* --add-exports=java.base/sun.security.action=ALL-UNNAMED
* --add-exports=java.base/sun.security.provider=ALL-UNNAMED
* --add-exports=java.base/sun.security.provider.certpath=ALL-UNNAMED
*/
// info.put("use_tlcp", "true");
/*
* 证书信任库配置(单向认证)
* - 文件路径需使用类路径格式(如/cacert.truststore)
* - 证书文件需放置在src/main/resources目录下
*/
// info.put("tlcp_trust_store", "cacert.truststore");
// info.put("tlcp_trust_store_pwd", "unvdb@123"); // CA证书密码
/*
* 客户端密钥库配置(双向认证)
* - 文件路径需使用类路径格式(如/client.keystore)
* - 密钥库需包含客户端证书链及私钥
*/
// info.put("tlcp_key_store", "client.keystore");
// info.put("tlcp_key_store_pwd", "unvdb@123"); // 客户端证书密码
Class.forName("com.unvdb.udbds.jdbc.UDBDSDriver");
try (Connection connection =
DriverManager.getConnection("jdbc:udbds://127.0.0.1:7777", info);
Statement statement = connection.createStatement()) {
// set JDBC fetchSize
statement.setFetchSize(10000);
statement.execute("CREATE DATABASE root.sg1");
statement.execute(
"CREATE TIMESERIES root.sg1.d1.s1 WITH DATATYPE=INT64, ENCODING=RLE, COMPRESSOR=SNAPPY");
statement.execute(
"CREATE TIMESERIES root.sg1.d1.s2 WITH DATATYPE=INT64, ENCODING=RLE, COMPRESSOR=SNAPPY");
statement.execute(
"CREATE TIMESERIES root.sg1.d1.s3 WITH DATATYPE=INT64, ENCODING=RLE, COMPRESSOR=SNAPPY");
statement.execute(
"CREATE TIMESERIES root.sg1.d1.s4 WITH DATATYPE=DATE, ENCODING=PLAIN, COMPRESSOR=SNAPPY");
statement.execute(
"CREATE TIMESERIES root.sg1.d1.s5 WITH DATATYPE=TIMESTAMP, ENCODING=PLAIN, COMPRESSOR=SNAPPY");
statement.execute(
"CREATE TIMESERIES root.sg1.d1.s6 WITH DATATYPE=BLOB, ENCODING=PLAIN, COMPRESSOR=SNAPPY");
statement.execute(
"CREATE TIMESERIES root.sg1.d1.s7 WITH DATATYPE=STRING, ENCODING=PLAIN, COMPRESSOR=SNAPPY");
for (int i = 0; i <= 100; i++) {
statement.addBatch(prepareInsertStatement(i));
}
statement.executeBatch();
statement.clearBatch();
ResultSet resultSet = statement.executeQuery("select ** from root where time <= 10");
outputResult(resultSet);
resultSet = statement.executeQuery("select count(**) from root");
outputResult(resultSet);
resultSet =
statement.executeQuery(
"select count(**) from root where time >= 1 and time <= 100 group by ([0, 100), 20ms, 20ms)");
outputResult(resultSet);
} catch (UDBDSSQLException e) {
LOGGER.error("UDB-DS Jdbc example error", e);
}
}
@SuppressWarnings({"squid:S106"})
private static void outputResult(ResultSet resultSet) throws SQLException {
if (resultSet != null) {
System.out.println("--------------------------");
final ResultSetMetaData metaData = resultSet.getMetaData();
final int columnCount = metaData.getColumnCount();
for (int i = 0; i < columnCount; i++) {
System.out.print(metaData.getColumnLabel(i + 1) + " ");
}
System.out.println();
while (resultSet.next()) {
for (int i = 1; ; i++) {
System.out.print(resultSet.getString(i));
if (i < columnCount) {
System.out.print(", ");
} else {
System.out.println();
break;
}
}
}
System.out.println("--------------------------\n");
}
}
private static String prepareInsertStatement(int time) {
return String.format(
"insert into root.sg1.d1(timestamp, s1, s2, s3, s4, s5, s6, s7) values(%d, %d, %d, %d, \"%s\", %d, %s, \"%s\")",
time, 1, 1, 1, LocalDate.of(2024, 5, time % 31 + 1), time, "X'cafebabe'", time);
}
}
UDB-DS 在 JDBC 中提供了额外的接口,供用户在连接中使用不同的字符集(例如 GB18030)读写数据库。 UDB-DS 默认的字符集为 UTF-8。当用户期望使用 UTF-8 外的字符集时,需要在 JDBC 的连接中,指定 charset 属性。例如:
使用 GB18030 的 charset 创建连接:
DriverManager.getConnection("jdbc:udbds://127.0.0.1:7777?charset=GB18030", "root", "root")
调用如下
UDBDSStatement接口执行 SQL 时,可以接受byte[]编码的 SQL,该 SQL 将按照被指定的 charset 解析成字符串。
public boolean execute(byte[] sql) throws SQLException;
查询结果输出时,可使用
ResultSet的getBytes方法得到的byte[],byte[]的编码使用连接指定的 charset 进行。
System.out.print(resultSet.getString(i) + " (" + new String(resultSet.getBytes(i), charset) + ")");
以下是完整示例:
import com.unvdb.udbds.jdbc.UDBDSSQLException;
import com.unvdb.udbds.jdbc.UDBDSStatement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.charset.Charset;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
public class JDBCCharsetExample {
private static final Logger LOGGER = LoggerFactory.getLogger(JDBCCharsetExample.class);
public static void main(String[] args) throws Exception {
Class.forName("com.unvdb.udbds.jdbc.UDBDSDriver");
try (final Connection connection =
DriverManager.getConnection(
"jdbc:udbds://127.0.0.1:7777?charset=GB18030", "root", "root");
final UDBDSStatement statement = (UDBDSStatement) connection.createStatement()) {
final String insertSQLWithGB18030 =
"insert into root.测试(timestamp, 彝语, 繁体, 蒙文, 简体, 标点符号, 藏语) values(1, 'ꆈꌠꉙ', \"繁體\", 'ᠮᠣᠩᠭᠣᠯ ᠬᠡᠯᠡ', '简体', '——?!', \"བོད་སྐད།\");";
final byte[] insertSQLWithGB18030Bytes = insertSQLWithGB18030.getBytes("GB18030");
statement.execute(insertSQLWithGB18030Bytes);
} catch (UDBDSSQLException e) {
LOGGER.error("UDB-DS Jdbc example error", e);
}
outputResult("GB18030");
outputResult("UTF-8");
outputResult("UTF-16");
outputResult("GBK");
outputResult("ISO-8859-1");
}
private static void outputResult(String charset) throws SQLException {
System.out.println("[Charset: " + charset + "]");
try (final Connection connection =
DriverManager.getConnection(
"jdbc:udbds://127.0.0.1:7777?charset=" + charset, "root", "root");
final UDBDSStatement statement = (UDBDSStatement) connection.createStatement()) {
outputResult(statement.executeQuery("select ** from root"), Charset.forName(charset));
} catch (UDBDSSQLException e) {
LOGGER.error("UDB-DS Jdbc example error", e);
}
}
private static void outputResult(ResultSet resultSet, Charset charset) throws SQLException {
if (resultSet != null) {
System.out.println("--------------------------");
final ResultSetMetaData metaData = resultSet.getMetaData();
final int columnCount = metaData.getColumnCount();
for (int i = 0; i < columnCount; i++) {
System.out.print(metaData.getColumnLabel(i + 1) + " ");
}
System.out.println();
while (resultSet.next()) {
for (int i = 1; ; i++) {
System.out.print(
resultSet.getString(i) + " (" + new String(resultSet.getBytes(i), charset) + ")");
if (i < columnCount) {
System.out.print(", ");
} else {
System.out.println();
break;
}
}
}
System.out.println("--------------------------\n");
}
}
}