通过Mybatis实现iotdb数据库的连接遇到的问题以及解决方法
出自物联网新人之手,有什么不对的还请赐教,欢迎感兴趣的小伙伴提出自己宝贵的意见。
背景:
物联网的业务需求迫使我们需要用到各种各样的组件以及工具,在使用iotdb时序数据库的过程中遇到很多问题,首先批量的插入通过原生session来实现(这个本人已经跑通了),无话可说,官方也是推荐的,但是对于用惯了mybatis的小新,怎么用都感觉别扭,而且网上的例子也很少,我参考了这位大佬的文章全网首发一IoTDB数据库整合MyBatis实现SpringBoot项目CRUD_iotdb 与 mybatis plus_阳光非宅猿的博客-CSDN博客,但是没有跑通,官方不推荐使用jdbc(无法提供高性能吞吐),但一些小量级的增删查,我还是喜欢用mybatis,为此我摸索了一下。
针对我在测试的时候遇到的问题,现把经验分享出来。
遇到的问题:
1.启动项目提示:testWhileIdle is true, validationQuery not set。
2023-04-26 14:05:39.282 ERROR 13864 --- [ main] com.alibaba.druid.pool.DruidDataSource : testWhileIdle is true, validationQuery not set
原因:没有在配置文件中设置(最先的作者可能没遇到这个,不过报错也能用,可以不管)
druid: validation-query: 连接测试语句
2.查询一直报错
2.1错误一:mismatched input ‘<EOF>,’ excepting ‘{FROM,INTO}‘
反复检查:是因为validation-query:的连接测试语句不能写成网络上大家正对mysql设置的select 1;
2.2错误二:java.lang.NullPointerException
原因:返回结果集的时候类型不能是jdbcType,改成JavaType问题解决,但是...
2.3错误三:Error attempting to get column “Time” from result set
原因:不管你需不需要Time字段(需要也不能在select后面写),查询结果都会返回Time字段的值,这是iotdb特有的主键,但是本人试了LONG,VARCHAR,DATE等能想到的类型,都无济于事,但是可以通过Java.lang.String接收到返回的Long类型时间值,通过resultMapper就是无法实现。
最终解决:通过Map<String,Object>类型将所有数据接收出来,然后再处理(目前我只能这样操作,希望有更好办法的兄弟交流学习)
3.删除操作,提示成功,但是去库里查询,还在!!!
我这就无语了,没删除就没删除呗,有错你就提呗,你来个成功,然后结果未实现。
原因:删除的时候,比如要删除某个时间段的一组数据,必须在设备id后面添加.*,如:
delete from root.XXX.XXX.demo20130424_4.* where time > XXXXXX
最后总算成功通过mybatis实现了自己想要的功能,不过还是有很多不足,还希望有兴趣的同学一起研究。
接下来上代码:
实现过程:
--------------------------------------------------------------------------------------
1.主要依赖:
<dependency>
<groupId>org.apache.iotdb</groupId>
<artifactId>iotdb-jdbc</artifactId>
<version>0.13.0</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.21</version>
</dependency>
2.数据库配置
spring:
datasource:
username: ****
password: *******
driver-class-name: org.apache.iotdb.jdbc.IoTDBDriver
url: jdbc:iotdb://localhost:6667/
druid:
validation-query: select * from *****
initial-size: 5
min-idle: 10
max-active: 50
max-wait: 60000
remove-abandoned: true
remove-abandoned-timeout: 30
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
test-while-idle: false
test-on-borrow: false
test-on-return: false
mybatis:
mapper-locations: classpath:/mapper/*.xml
#输出sql日志
logging:
level:
com.****.iotdb.mapper.IotdbMapper: debug
3.controller,测试用没有入参,实际情况可以自己加
import com.***.iotdb.dao.DeviceDao;
import com.***.iotdb.dao.SaveIotParam;
import com.***.iotdb.dao.SearchIotParam;
import com.***.iotdb.service.IotdbService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @author xp
* @ClassName iotdbDemoController
* @Description TODO
* @date 2023/04/24 9:06
*/
@Slf4j
@RestController
@RequestMapping("/iotdbjdbcdemo")
@RequiredArgsConstructor
public class IotdbDemoController {
@Autowired
private IotdbService service;
/** * 新增 * @param data * @return * @throws Exception */
@PostMapping("/insert")
public String insert() throws Exception {
service.insert(data);
return "SUCCESS";
}
/** * 删除 * @param data * @throws Exception */
@PostMapping("/delete")
public void delete() throws Exception {
service.deleteByParam();
}
/** * 查询 * @param data * @return * @throws Exception */
@GetMapping("/queryOrder")
public List<DeviceDao> queryOrder() throws Exception {
try {
List<DeviceDao> v = service.queryOrder();
return v;
} catch (Exception e) {
log.info("查询失败!" + e);
return null;
}
}
}
4.service
4.1接口
/**
* @author xp
* @ClassName IotdbService
* @Description TODO
* @date 2023/04/24 9:26
*/
import com.***.iotdb.dao.DeviceDao;
import com.***.iotdb.dao.SaveIotParam;
import com.***.iotdb.dao.SearchIotParam;
import java.util.*;
public interface IotdbService {
public void insert();
public void deleteByParam();
List<DeviceDao> queryOrder();
}
4.2实现类
/**
* @author xp
* @ClassName IotdbService
* @Description TODO
* @date 2023/04/24 9:26
*/
import com.***.iotdb.dao.DeviceDao;
import com.***.iotdb.dao.SaveIotParam;
import com.***.iotdb.dao.SearchIotParam;
import com.***.iotdb.mapper.IotdbMapper;
import com.***.iotdb.service.IotdbService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
public class IotdbServiceImpl implements IotdbService {
@Autowired
private IotdbMapper mapper;
@Override
public void insert() {
mapper.insert();
}
@Override
public void deleteByParam() {
mapper.deleteByParam();
}
@Override
public List<DeviceDao> queryOrder(){
final List<Map<String, Object>> mapList = mapper.queryOrder();
final List<DeviceDao> result = mapList.stream().map(s -> {
final DeviceDao deviceDao = new DeviceDao();
deviceDao.setTime((Date) s.get("Time"));
deviceDao.setMeasurementTemperature(s.get("temperature").toString());
deviceDao.setMeasurementWeight(s.get("weight").toString());
deviceDao.setMeasurementFlow(s.get("flow").toString());
deviceDao.setMeasurementNumber(s.get("Number").toString());
return deviceDao;
}).collect(Collectors.toList());
return result;
}
}
5.mapper
import com.***.iotdb.dao.DeviceDao;
import com.***.iotdb.dao.SaveIotParam;
import com.***.iotdb.dao.SearchIotParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
* @author xp
* @InterfaceName IotdbMapper
* @Description TODO
* @date 2023/04/24 14:29
*/
public interface IotdbMapper {
void insert();
void deleteByParam();
List<Map<String, Object>> queryOrder();
}
6.mapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.***.***.mapper.IotdbMapper">
<resultMap id="BaseResult" type="com.***.***.dao.DeviceDao">
<collection property="measurementNumber" column="Number" javaType="INTEGER"/>
<collection property="measurementWeight" column="weight" javaType="DOUBLE"/>
<collection property="measurementTemperature" column="temperature" javaType="DOUBLE"/>
<collection property="measurementFlow" column="flow" javaType="DOUBLE"/>
<collection property="time" column="Time" javaType="DATE"/>
</resultMap>
<!-- resultMap没有走通,请大神指导-->
<insert id="insert">
insert into root.***.***.demo20130424_1 (timestamp, Number, weight, temperature,flow)
values(2023-04-25T18:28:20.689+08:00,9,7.77,37.99,2.66);
</insert>
<delete id="deleteByParam">
delete from root.***.***.demo20130424_1.* where time > 1682317200000
</delete>
<select id="queryOrder" resultType="java.util.Map">
select Number as Number,temperature as temperature,weight as weight,flow as flow from root.zssy.zkj.demo20130424_1 limit 1 offset 0
</select>
</mapper>
7.记得启动类哦
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
/**
* @author xp
* @ClassName IotdbApplication
* @Description TODO
* @date 2023/04/24 8:53
*/
@SpringBootApplication
@MapperScan("com.***.iotdb.mapper")
public class IotdbApplication {
public static void main(String[] args) {
SpringApplication.run(IotdbApplication.class, args);
System.out.println("iotdb Demo程序启动成功!");
}
}
8.测试可行




注意:利用postman测试时,传入的string类型的属性值和整合mysql的用法有区别:
平时传入的json如下:
{
"timestamp":"2023-05-04T18:28:20.689+08:00",
"name":"小明",
"age":20,
"sex":"男",
"address":"西安108号"
}
但是这里json传参需要给String类型加上单引号' ',否则,运行会报sql错误
{
"timestamp":"2023-05-04T18:28:20.689+08:00",
"name":"'小明'",
"age":20,
"sex":"'男'",
"address":"'西安108号'"
}
写在最后:
出自物联网新人之手,有什么不对的还请赐教,欢迎感兴趣的小伙伴提出自己宝贵的意见。
参考文献:
1.https://blog.csdn.net/weixin_42103983/article/details/121580689
更多推荐




所有评论(0)