Apache IoTDB 系列教程-4:客户端接口
说了半天语法和部署运维,实际使用还是要落到代码里的,今天介绍一下客户端的接口。
正文 3516 字,预计阅读时间 5 分钟。
现在的客户端和服务器通信采用了跨语言的 RPC 框架 Thirft,理论上 Thrift 能生成的语言都能支持。但是直接用 Thrift 生成的代码对数据库使用者不太友好,所以我们在生成代码的基础上,包装出来了我们的各种客户端接口,这种接口对用户就比较友好了。接下来介绍一下各种客户端接口。
JDBC 接口
JDBC 是关系数据库的标准接口,也是大家最熟悉的接口。所以一开始我们就提供了这种接口。
和标准 JDBC 的使用方式一样,需要加载数据库驱动类,建立连接,建立 Statement,通过 Statement 执行语句,对于非查询来说,可以批量执行减少网络传输次数。下面是一个简单的例子,
public static void main(String[] args) throws ClassNotFoundException, SQLException { Class.forName("org.apache.iotdb.jdbc.IoTDBDriver"); try (Connection connection = DriverManager .getConnection("jdbc:iotdb://127.0.0.1:6667/", "root", "root"); Statement statement = connection.createStatement()) { // 创建存储组 statement.execute("SET STORAGE GROUP TO 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"); // 在客户端积累一批更新语句 for (int i = 0; i <= 100; i++) { statement.addBatch("insert into root.sg1.d1(timestamp, s1, s2, s3) values("+ i + "," + 1 + "," + 1 + "," + 1 + ")"); } // 执行 statement.executeBatch(); statement.clearBatch(); // 查询 ResultSet resultSet = statement.executeQuery("select * from root where time <= 10"); // 打印结果集 ResultSetMetaData metaData = resultSet.getMetaData(); int columnCount = metaData.getColumnCount(); while (resultSet.next()) { for (int i = 1; i < columnCount; i++) { System.out.print(resultSet.getString(i)); System.out.print(" "); } System.out.println(); } } }
完整的示例代码位置:
https://github.com/apache/incubator-iotdb/blob/master/example/jdbc/src/main/java/org/apache/iotdb/JDBCExample.java
Java 原生接口 Session
对于数据写入,SQL 解析就占了 70% 耗时。于是我们提供了一个原生的 NoSQL 接口(Session),相比于 JDBC 更高效。
insertRecord(String deviceId, long time, List<String> measurements, List<TSDataType> types, List<Object> values)
这个接口就对应一个 insert 语句,一次可以写入一个设备一个时间戳多个测点的值,其中值的类型需要和注册的类型保持一致,如果没注册过则自动注册此类型。
insertRecord(String deviceId, long time, List<String> measurements, List<String> values)
在一些场景下,客户端拿不到具体的数据类型,这时候可以用这种 String 参数的接口。如果提前注册了序列,服务器会根据注册的类型来解析这些 String 的值,如果没注册,会根据值的格式推断类型进行注册。
insertTablet(Tablet tablet, boolean sorted)
一个Tablet 是一个设备多个时间戳多个测点的值。这里要注意,每个测点在每个时间戳都需要有值,不能有空的。sorted 表示是否时间戳是递增的,如果能保证递增,可以设置为 true,否则我们还会再排个序。
如果只计算执行时间,这个接口是最高效的,因为里边使用了原始类型的数组,避免了装箱。但是,这个接口对数据的格式要求很高,如果数据采集不是对齐采的,强行转化成这种接口,转化的耗时需要统计一下。
此外还有 insertTablets 和 insertRecords 两种,其实就是以上几种接口的批量的形式。
Session 的查询结果集是 SessionDataSet,这个结构提供的 hasNext 和 next 方法把每一行数据都转化成了 RowRecord 这个结构,如果客户端还需要做其他转化,这个结构就多余了。这时候可以通过 SessionDataSet.iterator()得到一个迭代器,这个迭代器的访问数据的方式和 JDBC 的 ResultSet 是一样的,直接从字节数组里拿数据,比 RowRecord 更高效。
完整的示例代码位置:
https://github.com/apache/incubator-iotdb/blob/master/example/session/src/main/java/org/apache/iotdb/SessionExample.java
连接池 SessionPool
自从原生接口诞生以来,很多用户就从 JDBC 迁移到原始接口了,我们也扩充了原生接口的能力,增加了 Session 的连接池(东哥倾情奉献)。连接池的接口和 Session 基本一样,但是连接池可以供多线程使用,而且可以屏蔽连接异常等问题。
使用连接池唯一一点需要注意的是,查询得到的结果集使用完需要返还给连接池(调用连接池的 closeResultSet 方法),不然连接会被占用,无法得到新的连接就报超时了。
SessionDataSetWrapper wrapper = null; try { wrapper = pool.executeQueryStatement("select * from root.sg1.d1"); while (wrapper.hasNext()) { System.out.println(wrapper.next()); } } catch (IoTDBConnectionException | StatementExecutionException e) { e.printStackTrace(); } finally { // remember to close data set finally! pool.closeResultSet(wrapper); }
完整的示例代码位置:
https://github.com/apache/incubator-iotdb/blob/master/example/session/src/main/java/org/apache/iotdb/SessionPoolExample.java
Python 接口
除了 JAVA 的接口,我们还包装了一下 Python 的接口,是在 0.9 版本之后才增加的。位置在
https://github.com/apache/incubator-iotdb/blob/master/client-py
总结
今天主要介绍了 JDBC 接口、JAVA 原生接口 Session 和连接池,里边有一些注意事项,比如使用 SessionPool 做查询时,需要手动关闭结果集(我对这个印象深刻,曾经踩了几天的坑)。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
区块链系列教程之:比特币中的网络和区块链
简介 比特币的底层就是区块链技术,区块链也是因为比特币而广为人知的。和其他的区块链技术相比,比特币的区块链有什么特征呢?作为去区块链的鼻祖,又有什么与众不同的特性呢?快来跟我们一起看看吧。 比特币的网络 比特币使用的是P2P(peer-to-peer)网络,此P2P非彼P2P,这里是点对点的网络架构,而不是人对人的借钱模式。 P2P是指位于同一网络中的每台计算机都彼此对等,各个节点共同提供网络服务,不存在任何“特殊”节点。每个网络节点以“扁平(flat)”的拓扑结构相互连通。在P2P网络中不存在任何服务端(server)、中央化的服务、以及层级结构。 传统的网络结构是client-server的模式,所有的client都是和server交互获取信息, 只要server挂掉了,client也就没有用了。 而在P2P网络中,没有server的概念,每个节点可以作为一个server。对比起来P2P网络在稳定性方面要比C-S架构的系统要稳定得多。 网络发现与同步 既然是P2P网络,那么问题来了,这个P2P网络是怎么建立起来的呢?节点之间是怎么发现的呢? 有做过P2P下载的同学应该都听说过种子的...
- 下一篇
RuoYi 4.3.0 发布,更多细节优化
若依管理系统 v4.3.0已发布,更新日志: 代码生成模板支持主子表 代码生成显示类型支持复选框 前端表单样式修改成圆角 新增回显数据字典(字符串数组) 修复浏览器手动缩放比例后菜单无法自适应问题 限制用户不允许选择系统管理员角色 用户信息添加输入框组图标&鼠标按下显示密码 升级fastjson到最新版1.2.70 修复高危安全漏洞 升级Bootstrap版本到v3.3.7 修复selectColumns方法获取子对象数据无效问题 修改数据源类型优先级,先根据方法,再根据类 修改上级部门(选择项排除本身和下级) 首页菜单显示调整 添加是否开启swagger配置 新增示例(主子表提交) 新增示例(多级联动下拉示例) 新增示例(表格属性data数据加载) 新增表格列参数(是否列选项可见ignore) 新增表格参数(是否启用显示卡片视图cardView) 新增表格参数(是否显示全屏按钮showFullscreen) 新增表格参数(是否启用分页条无限循环的功能paginationLoop) 新增表格参数(是否显示表头showHeader) 表格添加显示/隐藏所有列方法 showAllC...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS6,CentOS7官方镜像安装Oracle11G
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- CentOS8编译安装MySQL8.0.19
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Windows10,CentOS7,CentOS8安装Nodejs环境