5-TDengine集成SpringBoot,MyBatis,MyBatisPlus

简介: 5-TDengine集成SpringBoot,MyBatis,MyBatisPlus

背景


前面的体验中,用到了 taos 的客户端、 RESTful Connector 以及 JDBC-JNI 等连接方式,这次我们体验下更接近实际应用场景的示例: TDengineSpringBootMyBatisMyBatisPlus 等的集成。


官方已经自带了示例,

https://github.com/taosdata/TDengine/tree/develop/tests/examples/JDBC


这些示例在安装的客户端目录也有: /usr/local/taos/examples/JDBC 或者 C:\TDengine\examples\JDBC ,我把这些示例都跑了一遍,大体都可以跑起来,但是也存在一些问题或bug,尤其是一些测试用例不太严谨。我把改过的示例放到了我的GitHub上,修改的地方与说明在README.md中。

image.png


SpringBoot+TDengine+MyBatis


示例内容基本上就是建库、建表、插入数据,具体看代码即可。下面只列一下遇到的问题以及解决方法。


  • 依赖版本与服务端相兼容
<dependency>
    <groupId>com.taosdata.jdbc</groupId>
    <artifactId>taos-jdbcdriver</artifactId>
    <version>2.0.28</version>
</dependency>

修改为:

<dependency>
    <groupId>com.taosdata.jdbc</groupId>
    <artifactId>taos-jdbcdriver</artifactId>
    <version>2.0.28</version>
</dependency>

如果不修改依赖版本,当与服务端版本不一致时,则报错:

Cause: java.sql. SQLException: TDengine ERROR (216): Syntax error in SQL; uncategorized SQLException; SQL state []; error code [534]; TDengine ERROR (216): Syntax error in SQL; nested exception is java.sql. SQLException: TDengine ERROR (216): Syntax error in SQL] with root cause

关于版本兼容性说明,见官方这个表(我的服务端TDengine版本为:2.1.2.0):

image.png

  • TDengine批量插入数据遇到bug


这里用三种方式写了批量插入的语句(这里仅选择一个普通表批量插入,后续实现动态向多个普通表中批量插入数据),但是有一种写法按道理是正确的,但实际就是报错,懵逼一脸,经过调试,应该是个bug。。


第一种:使用后端sql语句中的时间戳作为主键,now+步长

<insert id="insertBatch" parameterType="java.util.List">
            insert into demo.t0 (ts, temperature, humidity) values
            <foreach separator=" " collection="list" item="weather" index="index" >
                <!-- 参考涛思数据官方文档:https://www.taosdata.com/cn/documentation/taos-sql#data-type
                数字后面的时间单位可以是 u(微秒)、a(毫秒)、s(秒)、m(分)、h(小时)、d(天)、w(周)
                在指定降频操作(down sampling)的时间窗口(interval)时,时间单位还可以使用 n(自然月) 和 y(自然年)。-->
                (now + #{index}a, #{weather.temperature}, #{weather.humidity})
            </foreach>
        </insert>

Note: (now + #{index}a, #{weather.temperature}, #{weather.humidity}) 这样的写法,让我一度怀疑是不是不小心打错了,多打了个字母a。。


第二种:使用前端传参列表中的时间戳作为主键,表名在循环体外,这种方法报错,应该是个bug。。

<!--用这种写法,直接使用前端传过来的时间戳,报错:uncategorized SQLException; SQL state []; error code [534]; TDengine ERROR (216): Syntax error in SQL; -->
    <insert id="insertBatch" parameterType="java.util.List">
        insert into demo.t0 (ts, temperature, humidity) values
        <foreach separator=" " collection="list" item="weather" index="index">
            (#{weather.ts}, #{weather.temperature}, #{weather.humidity})
        </foreach>
    </insert>

第一种方法可以,第二种就不行,让人怀疑人生。。然后就跟着调试了一番。

image.png

image.png

image.png

image.png

结果:在批量插入时,第二条记录的时间戳竟然没有自动加上引号,导致报错。。

第三种:使用前端传参列表中的时间戳作为主键,表名在循环体内,批量插入成功~

<insert id="insertBatch" parameterType="java.util.List">
            insert into
            <foreach separator=" " collection="list" item="weather" index="index">
                demo.t0 values
                (#{weather.ts}, #{weather.temperature}, #{weather.humidity})
            </foreach>
        </insert>

附: Postman 里的批量数据传参方式(向后端传递一个数组类型的参数):

curl --location --request POST 'localhost:8080/weather/batch' \
--header 'Content-Type: application/json' \
--data-raw '[
    {
        "ts": 1626324781093,
        "temperature": 30.00000,
        "humidity": 99.00000
    },
    {
        "ts": 1626324981322,
        "temperature": 9.50609,
        "humidity": 10.00000
    }
]'
# 或者(换了传递的时间戳格式):
curl --location --request POST 'localhost:8080/weather/batch' \
--header 'Content-Type: application/json' \
--data-raw '[
    {
        "ts": "2021-07-19 14:53:01.093",
        "temperature": 30.00000,
        "humidity": 99.00000
    },
    {
        "ts": "2021-07-19 14:53:01.200",
        "temperature": 9.50609,
        "humidity": 10.00000
    }
]'

Note: 我用的这个版本,已经不允许往超级表中直接插入数据了,但示例代码自带的README.md中还是这样写的: insert into test.weather (ts, temperature, humidity) values ,总之,文档不太严谨。。


SpringBoot+TDengine+MyBatisPlus


  • 依赖修改


同样,不贴源码了,下面只列一下遇到的问题以及解决方法。


  1. 删除了h2依赖


  1. druid依赖替换为starter
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.17</version>
</dependency>
  1. 升级了taos-jdbcdriver依赖版本
<dependency>
    <groupId>com.taosdata.jdbc</groupId>
    <artifactId>taos-jdbcdriver</artifactId>
    <version>2.0.30</version>
</dependency>
  • 配置修改


user: root 改为: username: root


不过这里改不改都不影响结果,就比较奇怪。。


  • 代码修改


循环生成记录时,时间戳应考虑递增,而不是所有记录使用同一个时间戳,这样会导致覆盖、或者丢弃(依赖于数据库的配置)。


TemperatureMapperTest.java

// insert into table
    int affectRows = 0;
    // insert 10 tables
    for (int i = 0; i < 10; i++) {
        // each table insert 5 rows
        for (int j = 0; j < 5; j++) {
            Temperature one = new Temperature();
            // 如果是插入单条记录,这样写没问题,可这里是在循环体里,TDengine表中时间戳为主键,相同的时间戳会发生覆盖,导致最终插入的记录数量与预期不符
            one.setTs(new Timestamp(1605024000000l));
            one.setTemperature(random.nextFloat() * 50);
            one.setLocation("望京");
            one.setTbIndex(i);
            affectRows += mapper.insertOne(one);
        }
    }
    Assert.assertEquals(50, affectRows);

改为

// insert into table
    int affectRows = 0;
    long ts = System.currentTimeMillis();
    // insert 10 tables
    for (int i = 0; i < 10; i++) {
        // each table insert 5 rows
        for (int j = 0; j < 5; j++) {
            Temperature one = new Temperature();
            // 如果是插入单条记录,这样写没问题,可这里是在循环体里,TDengine表中时间戳为主键,相同的时间戳会发生覆盖,导致最终插入的记录数量与预期不符
//                one.setTs(new Timestamp(1605024000000l));
            Timestamp timestamp = new Timestamp(ts + j);
            one.setTs(timestamp);
            one.setTemperature(random.nextFloat() * 50);
            one.setLocation("望京");
            one.setTbIndex(i);
            affectRows += mapper.insertOne(one);
        }
    }
    Assert.assertEquals(50, affectRows);


Source Code



目录
相关文章
|
2天前
|
XML Java 数据库连接
SpringBoot集成Flowable:打造强大的工作流管理系统
在企业级应用开发中,工作流管理是一个核心组件,它能够帮助我们定义、执行和管理业务流程。Flowable是一个开源的工作流和业务流程管理(BPM)平台,它提供了强大的工作流引擎和建模工具。结合SpringBoot,我们可以快速构建一个高效、灵活的工作流管理系统。本文将探讨如何将Flowable集成到SpringBoot应用中,并展示其强大的功能。
15 1
|
29天前
|
Java 数据库连接 Maven
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和MyBatis Generator,使用逆向工程来自动生成Java代码,包括实体类、Mapper文件和Example文件,以提高开发效率。
87 2
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
|
29天前
|
SQL JSON Java
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和PageHelper进行分页操作,并且集成Swagger2来生成API文档,同时定义了统一的数据返回格式和请求模块。
49 1
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
|
12天前
|
JSON Java API
springboot集成ElasticSearch使用completion实现补全功能
springboot集成ElasticSearch使用completion实现补全功能
18 1
|
1月前
|
前端开发 Java Apache
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
本文详细讲解了如何整合Apache Shiro与Spring Boot项目,包括数据库准备、项目配置、实体类、Mapper、Service、Controller的创建和配置,以及Shiro的配置和使用。
257 1
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
|
2天前
|
XML 存储 Java
SpringBoot集成Flowable:构建强大的工作流引擎
在企业级应用开发中,工作流管理是核心功能之一。Flowable是一个开源的工作流引擎,它提供了BPMN 2.0规范的实现,并且与SpringBoot框架完美集成。本文将探讨如何使用SpringBoot和Flowable构建一个强大的工作流引擎,并分享一些实践技巧。
14 0
|
27天前
|
前端开发 Java 程序员
springboot 学习十五:Spring Boot 优雅的集成Swagger2、Knife4j
这篇文章是关于如何在Spring Boot项目中集成Swagger2和Knife4j来生成和美化API接口文档的详细教程。
48 1
|
27天前
|
Java 关系型数据库 MySQL
springboot学习五:springboot整合Mybatis 连接 mysql数据库
这篇文章是关于如何使用Spring Boot整合MyBatis来连接MySQL数据库,并进行基本的增删改查操作的教程。
45 0
springboot学习五:springboot整合Mybatis 连接 mysql数据库
|
29天前
|
SQL Java 数据库连接
mybatis使用二:springboot 整合 mybatis,创建开发环境
这篇文章介绍了如何在SpringBoot项目中整合Mybatis和MybatisGenerator,包括添加依赖、配置数据源、修改启动主类、编写Java代码,以及使用Postman进行接口测试。
15 0
mybatis使用二:springboot 整合 mybatis,创建开发环境
|
29天前
|
Java 数据库连接 API
springBoot:后端解决跨域&Mybatis-Plus&SwaggerUI&代码生成器 (四)
本文介绍了后端解决跨域问题的方法及Mybatis-Plus的配置与使用。首先通过创建`CorsConfig`类并设置相关参数来实现跨域请求处理。接着,详细描述了如何引入Mybatis-Plus插件,包括配置`MybatisPlusConfig`类、定义Mapper接口以及Service层。此外,还展示了如何配置分页查询功能,并引入SwaggerUI进行API文档生成。最后,提供了代码生成器的配置示例,帮助快速生成项目所需的基础代码。
下一篇
无影云桌面