IoTDB数据库整合MyBatis实现SpringBoot项目CRUD

遇到的问题:

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

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>1.3.0</version>
		</dependency>
		<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatis-plus-boot-starter</artifactId>
			<version>3.5.3.1</version>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid-spring-boot-starter</artifactId>
			<version>1.2.16</version>
		</dependency>

2.数据库配置

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      driver-class-name: org.apache.iotdb.jdbc.IoTDBDriver
      url: jdbc:iotdb://127.0.0.1:6667/
      username: root
      password: root
      initial-size: 5
      max-active: 20
      min-idle: 1
      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-plus:
  mapper-locations: classpath:/mapper/*.xml
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

WeatherEntity

package com.example.wys.entity;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * 添加说明
 *
 * @author kit
 * @version 1.0
 * @date 2023/11/7 17:02
 */
@Data
@Builder
public class WeatherEntity {
    /**
     * 固定对应Time字段
     */
    private long timestamp;

    /**
     * 采样时间时间戳
     */
    private String samplingTime;

    /**
     * 采样时间字符
     */
    private String samplingTimeStr;

    /**
     * 城市编码
     */
    private Integer cityKey;

    /**
     * 城市
     */
    private String city;

    /**
     * 温度 ℃
     */
    private float temperature;

    /**
     * 湿度 %
     */
    private float humidity;

    /**
     * pm10
     */
    private float pm10;

    /**
     * pm10
     */
    private float pm25;

    /**
     * 空气质量
     */
    private String quality;

    /**
     * 天气描述
     */
    private String remark;


}

Rst

package com.example.wys.utils;

import java.io.Serializable;
import java.util.LinkedHashMap;

/**
 * 返回结果
 *
 * @author kit
 * @version 1.0
 * @date 2023/11/9 11:23
 */
public class Rst extends LinkedHashMap<String, Object> implements Serializable {

    private static final long serialVersionUID = 1L;    // 序列化版本号
    public static final int CODE_SUCCESS = 200;
    public static final int CODE_ERROR = 500;

    public Rst() {
    }

    public Rst(int code, String msg, Object data) {
        this.setCode(code);
        this.setMsg(msg);
        this.setData(data);
    }

    /**
     * 获取code
     *
     * @return code
     */
    public Integer getCode() {
        return (Integer) this.get("code");
    }

    /**
     * 获取msg
     *
     * @return msg
     */
    public String getMsg() {
        return (String) this.get("msg");
    }

    /**
     * 获取data
     *
     * @return data
     */
    public Object getData() {
        return (Object) this.get("data");
    }

    /**
     * 给code赋值,连缀风格
     *
     * @param code code
     * @return 对象自身
     */
    public Rst setCode(int code) {
        this.put("code", code);
        return this;
    }

    /**
     * 给msg赋值,连缀风格
     *
     * @param msg msg
     * @return 对象自身
     */
    public Rst setMsg(String msg) {
        this.put("msg", msg);
        return this;
    }

    /**
     * 给data赋值,连缀风格
     *
     * @param data data
     * @return 对象自身
     */
    public Rst setData(Object data) {
        this.put("data", data);
        return this;
    }

    // 构建成功
    public static Rst ok() {
        return new Rst(CODE_SUCCESS, "ok", null);
    }

    public static Rst ok(String msg) {
        return new Rst(CODE_SUCCESS, msg, null);
    }

    public static Rst code(int code) {
        return new Rst(code, null, null);
    }

    public static Rst data(Object data) {
        return new Rst(CODE_SUCCESS, "ok", data);
    }

    // 构建失败
    public static Rst error() {
        return new Rst(CODE_ERROR, "error", null);
    }

    public static Rst error(String msg) {
        return new Rst(CODE_ERROR, msg, null);
    }

    @Override
    public String toString() {
        return "{"
                + "\"code\": " + this.getCode()
                + ", \"msg\": " + transValue(this.getMsg())
                + ", \"data\": " + transValue(this.getData())
                + "}";
    }

    private String transValue(Object value) {
        if (value instanceof String) {
            return "\"" + value + "\"";
        }
        return String.valueOf(value);
    }
}

3.controller,

package com.example.wys.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;

import com.example.wys.entity.WeatherEntity;
import com.example.wys.service.WeatherService;
import com.example.wys.utils.Constant;
import com.example.wys.utils.Rst;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.math.RoundingMode;
import java.util.Date;

/**
 * 添加说明
 *
 * @author kit
 * @version 1.0
 * @date 2023/11/7 16:50
 */
@RestController
@RequestMapping("/weather")
public class WeatherController {

    @Resource
    WeatherService weatherService;

    /**
     * 新增
     *
     * @return
     */
    @GetMapping("add")
    public Rst add() {
        Date date = new Date();
        Long dateTime = date.getTime();
        // 模拟数据
        // 此处涉及到的字符串的,必须前后加',如下面的city字段,quality字段, remark字段
        WeatherEntity testEntity = WeatherEntity.builder()
                .samplingTime(dateTime.toString())
                .samplingTimeStr("'" + DateUtil.format(date, "yyyy-MM-dd HH:mm:ss") + "'")
                .cityKey(101190101)
                .city("'南京'")
                .temperature(NumberUtil.parseFloat(StrUtil.toString(RandomUtil.randomDouble(-18.2, 30.5, 1, RoundingMode.HALF_UP))))
                .humidity(NumberUtil.parseFloat(StrUtil.toString(RandomUtil.randomDouble(1, 100, 1, RoundingMode.HALF_UP))))
                .pm10(NumberUtil.parseFloat(StrUtil.toString(RandomUtil.randomDouble(0, 300, 0, RoundingMode.HALF_UP))))
                .pm25(NumberUtil.parseFloat(StrUtil.toString(RandomUtil.randomDouble(0, 300, 1, RoundingMode.HALF_UP))))
                .quality("'" + Constant.QUALITY_OPTIONS[RandomUtil.randomInt(0, 3)] + "'")
                .remark("'模拟插入'").build();
        return Rst.data(weatherService.addWeather(testEntity));
    }

    /**
     * 分页
     *
     * @param page     第几页
     * @param pageSize 每页多少条
     * @return
     */
    @GetMapping("page")
    public Rst page(Integer page, Integer pageSize) {
        return Rst.data(weatherService.pageWeather(page, pageSize));
    }

    /**
     * 删除数据
     * 对于delete语句,其中子句只能包含时间表达式,目前不支持值筛选
     *
     * @param startTime 需要固定格式为yyyy-MM-dd HH:mm:ss
     * @param endTime   需要固定格式为yyyy-MM-dd HH:mm:ss
     * @return
     */
    @GetMapping("delete")
    public Rst delete(String startTime, String endTime) {
        // 官方对于delete语句,其中子句只能包含时间表达式,目前不支持其他值筛选
        return Rst.data(weatherService.deleteWeather(startTime, endTime));
    }
}

4.service

package com.example.wys.service;



import com.example.wys.entity.WeatherEntity;

import java.util.List;

/**
 * 添加说明
 *
 * @author kit
 * @version 1.0
 * @date 2023/11/7 16:50
 */
public interface WeatherService {

    Integer addWeather(WeatherEntity weatherEntity);

    List<WeatherEntity> pageWeather(Integer page, Integer pageSize);

    Integer deleteWeather(String startTime, String endTime);
}

4.2实现类

package com.example.wys.service.impl;


import com.example.wys.entity.WeatherEntity;
import com.example.wys.mapper.WeatherMapper;
import com.example.wys.service.WeatherService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * 添加说明
 *
 * @author kit
 * @version 1.0
 * @date 2023/11/7 16:50
 */
@Service
public class WeatherServiceImpl implements WeatherService {

    @Resource
    WeatherMapper weatherMapper;

    @Override
    public Integer addWeather(WeatherEntity testEntity) {
        return weatherMapper.addWeather(testEntity);
    }

    @Override
    public List<WeatherEntity> pageWeather(Integer page, Integer pageSize) {
        if (page == null || page < 1) {
            page = 1;
        }
        if (pageSize == null || pageSize < 1) {
            pageSize = 10;
        }
        int offset = (page - 1) * pageSize;

        List<WeatherEntity> entityList = weatherMapper.pageWeather(pageSize, offset);

        System.out.println(entityList);
        return entityList;
    }

    @Override
    public Integer deleteWeather(String startTime, String endTime) {
        return weatherMapper.deleteWeather(startTime, endTime);
    }
}

5.mapper

package com.example.wys.mapper;

import com.example.wys.entity.WeatherEntity;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * 添加说明
 *
 * @author kit
 * @version 1.0
 * @date 2023/11/7 16:52
 */
@Mapper
public interface WeatherMapper {

    Integer addWeather(WeatherEntity weatherEntity);

    List<WeatherEntity> pageWeather(@Param("pageSize") Integer pageSize, @Param("offset") Integer offset);

    Integer deleteWeather(@Param("startTime") String startTime, @Param("endTime") String endTime);
}

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.example.wys.mapper.WeatherMapper">

    <resultMap id="BaseResultMap" type="com.example.wys.entity.WeatherEntity">
        <result column="Time" property="timestamp" />
        <result column="root.ln.weather.samplingTime" property="samplingTime"/>
        <result column="root.ln.weather.samplingTimeStr" property="samplingTimeStr"/>
        <result column="root.ln.weather.cityKey" property="cityKey"/>
        <result column="root.ln.weather.city" property="city"/>
        <result column="root.ln.weather.temperature" property="temperature"/>
        <result column="root.ln.weather.humidity" property="humidity"/>
        <result column="root.ln.weather.pm10" property="pm10"/>
        <result column="root.ln.weather.pm25" property="pm25"/>
        <result column="root.ln.weather.quality" property="quality"/>
        <result column="root.ln.weather.remark" property="remark"/>
    </resultMap>

    <insert id="addWeather" parameterType="com.example.wys.entity.WeatherEntity">
        insert into root.ln.weather(samplingTime, samplingTimeStr, cityKey, city, temperature, humidity, pm10, pm25,
                                    quality, remark)
        values (#{samplingTime}, #{samplingTimeStr}, #{cityKey}, #{city}, #{temperature}, #{humidity}, #{pm10}, #{pm25},
                #{quality}, #{remark})
    </insert>

    <select id="pageWeather" resultMap="BaseResultMap">
        select amplingTime, samplingTimeStr,city, temperature, humidity, pm10, pm25,quality, remark from root.ln.weather
    </select>

    <delete id="deleteWeather" parameterType="java.lang.String">
        delete
        from root.ln.weather.*
        where time <![CDATA[ >= ]]> ${startTime}
          and time <![CDATA[ <= ]]> ${endTime};
    </delete>

</mapper>

postman 测试

127.0.0.1:8083/weather/page

注意:利用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号'"

}
相关推荐
问道飞鱼2 小时前
【知识科普】认识正则表达式
数据库·mysql·正则表达式
HaiFan.2 小时前
SpringBoot 事务
java·数据库·spring boot·sql·mysql
水根LP492 小时前
linux系统上SQLPLUS的重“大”发现
数据库·oracle
途途途途2 小时前
精选9个自动化任务的Python脚本精选
数据库·python·自动化
04Koi.3 小时前
Redis--常用数据结构和编码方式
数据库·redis·缓存
silver98863 小时前
mongodb和Cassandra
数据库
PersistJiao3 小时前
3.基于 Temporal 的 Couchbase 动态 SQL 执行场景
数据库·sql
上山的月3 小时前
MySQL -函数和约束
数据库·mysql
zhcf4 小时前
【MySQL】十三,关于MySQL的全文索引
数据库·mysql
极限实验室4 小时前
Easysearch Chart Admin 密码自定义
数据库