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号'"

}
相关推荐
超级小忍38 分钟前
如何配置 MySQL 允许远程连接
数据库·mysql·adb
吹牛不交税1 小时前
sqlsugar WhereIF条件的大于等于和等于查出来的坑
数据库·mysql
hshpy1 小时前
setting up Activiti BPMN Workflow Engine with Spring Boot
数据库·spring boot·后端
李少兄2 小时前
解决MyBatis参数绑定中参数名不一致导致的错误问题
mybatis
文牧之2 小时前
Oracle 审计参数:AUDIT_TRAIL 和 AUDIT_SYS_OPERATIONS
运维·数据库·oracle
篱笆院的狗2 小时前
如何使用 Redis 快速实现布隆过滤器?
数据库·redis·缓存
洛神灬殇3 小时前
【LLM大模型技术专题】「入门到精通系列教程」基于ai-openai-spring-boot-starter集成开发实战指南
网络·数据库·微服务·云原生·架构
小鸡脚来咯3 小时前
redis分片集群架构
数据库·redis·架构
christine-rr4 小时前
征文投稿:如何写一份实用的技术文档?——以软件配置为例
运维·前端·网络·数据库·软件构建
海尔辛4 小时前
SQL 基础入门
数据库·sql