springboot配置多数据源mysql+TDengine保姆级教程

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录


前言

Mybatis-plus管理多数据源,数据库为mysql和TDengine。

一、pom文件

xml 复制代码
 <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
<!--            <scope>runtime</scope>-->
        </dependency>
        <!--connection pool-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.8</version>
        </dependency>
        <dependency>
            <groupId>com.taosdata.jdbc</groupId>
            <artifactId>taos-jdbcdriver</artifactId>
            <version>3.2.7</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.7</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>

二、yaml

yaml 复制代码
spring:
  datasource:
#    driver-class-name: com.mysql.cj.jdbc.Driver
#    url: jdbc:mysql://127.0.0.1:3306/wh_vehicles?useUnicode=true&characterEncoding=UTF-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&serverTimezone=Asia/Shanghai
#    username: root
#    password: Lucky#2024
    dynamic:
      primary: master # 设置默认的数据源
      strict: false # 严格按照路由规则从主库读取数据,如果主库不可用,则从从库读取数据。
      datasource:
        master:
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://127.0.0.1:3306/wh_vehicles?useUnicode=true&characterEncoding=UTF-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&serverTimezone=Asia/Shanghai
          username: root
          password: 123
        slave:
          driver-class-name: com.taosdata.jdbc.rs.RestfulDriver
          url: jdbc:TAOS-RS://localhost:6041?timezone=UTC-8&charset=utf-8&useSSL=false&user=root&password=123
          # using connection pools
          type: com.alibaba.druid.pool.DruidDataSource
          druid:
            initial-size: 5
            min-idle: 5
            max-active: 20
            max-wait: 60000
            time-between-eviction-runs-millis: 60000
            min-evictable-idle-time-millis: 300000
            validation-query: SELECT 1
            pool-prepared-statements: true
            max-pool-prepared-statement-per-connection-size: 20
# mybatis
mybatis-plus:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: org.zqh.jt808.server.model

DataSourceConfig

java 复制代码
package org.zqh.jt808.server.config;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.sql.DataSource;

@Configuration
public class DataSourceConfig {

    // 主数据源 master
    @Bean(name = "masterDataSource")
    @ConfigurationProperties(prefix = "spring.dynamic.datasource.master")
    public DataSource masterDataSource() {
        return DataSourceBuilder.create().build();
    }

    // 从数据源 slave
    @Bean(name = "slaveDataSource")
    @ConfigurationProperties(prefix = "spring.dynamic.datasource.slave")
    public DataSource slaveDataSource() {
        return DataSourceBuilder.create().build();
    }
    // 主数据源的 SqlSessionFactory
    @Primary
    @Bean(name = "masterSqlSessionFactory")
    public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        // 这里可以添加其他 MyBatis 配置,如 mapperLocations, typeAliases 等
        String locationPattern = "classpath*:/mapper/*.xml";
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        sqlSessionFactoryBean.setMapperLocations(resolver.getResources(locationPattern));
        return sqlSessionFactoryBean.getObject();
    }

    // 从数据源的 SqlSessionFactory
    @Bean(name = "slaveSqlSessionFactory")
    public SqlSessionFactory slaveSqlSessionFactory(@Qualifier("slaveDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        // 这里可以添加其他 MyBatis 配置,如 mapperLocations, typeAliases 等
        // 注意:通常从数据源的 mapperLocations 和 typeAliases 应该与主数据源分开配置
        String locationPattern = "classpath*:/mapper/*.xml";
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        sqlSessionFactoryBean.setMapperLocations(resolver.getResources(locationPattern));
        return sqlSessionFactoryBean.getObject();
    }
}

Service

java 复制代码
package org.zqh.jt808.server.service;

import cn.hutool.json.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DS;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.zqh.jt808.server.mapper.TDMapper;
import org.zqh.jt808.server.model.LocationInfo;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class TDService {

    // 超级表名称和子表模板
    private static final String SUPER_TABLE_NAME = "device_locations";
    private static final String SUB_TABLE_PREFIX = "device_";

    @Autowired
    private TDMapper tdMapper;

    /**
     * 保存坐标数据
     * @param locationInfo
     */
    @DS("slave")
    public void saveLocation(LocationInfo locationInfo) {
        tdMapper.saveLocation(locationInfo);
    }

    /**
     * 查询实时位置-全部
     * @return
     */
    @DS("slave")
    public List<LocationInfo> queryLocationAll() {
        return tdMapper.queryLocationAll();
    }

    /**
     * 查询历史轨迹
     * @param deviceId 设备id
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return
     */
    @DS("slave")
    public List<LocationInfo> queryLocationHistory(String deviceId, Long startTime, Long endTime) {
        return tdMapper.queryLocationHistory(deviceId,startTime,endTime);
    }

    /**
     * 查询实时位置-指定设备列表
     * @param deviceIds 设备id列表
     * @return
     */
    @DS("slave")
    public List<LocationInfo> queryLocations(List<String> deviceIds) {
        if(deviceIds.size()>0){
            return tdMapper.queryLocations(deviceIds);
        }else {
            return new ArrayList<>();
        }
    }

    @DS("slave")
    public JSONObject queryLocation(String deviceId) {
        return tdMapper.queryLocation(deviceId);
    }
}

Mapper.xml

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="org.zqh.jt808.server.mapper.TDMapper">
    <insert id="saveLocation">
        INSERT INTO wh_special_equipment.device_locations (tbname, ts, longitude, latitude, height, speed, direction, deviceid)
        VALUES (#{tname}, #{ts}, #{longitude}, #{latitude}, #{height}, #{speed}, #{direction}, #{deviceId})
    </insert>
    <select id="queryLocationHistory" resultType="org.zqh.jt808.server.model.LocationInfo">
        <![CDATA[
        select * from wh_special_equipment.device_locations where deviceid= #{deviceId} and ts >= #{startTime} and ts <= #{endTime};
        ]]>
    </select>
    <select id="queryLocations" resultType="org.zqh.jt808.server.model.LocationInfo">
        select last_row(deviceId),* from wh_special_equipment.device_locations
        where deviceId IN
        <foreach item="deviceId" index="index" collection="list" open="(" separator="," close=")">
            #{deviceId}
        </foreach>
        group by deviceId;
    </select>
    <select id="queryLocationAll" resultType="org.zqh.jt808.server.model.LocationInfo">
        select tbname,last_row(deviceId),* from wh_special_equipment.device_locations
        group by tbname;
    </select>
    <select id="queryLocation" resultType="cn.hutool.json.JSONObject">
        select last_row(deviceId),deviceId,ts,longitude,latitude,height,speed,direction
        from wh_special_equipment.device_locations
        where deviceId = #{deviceId}
    </select>
</mapper>

测试

java 复制代码
package org.zqh.jt808.server.test;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.zqh.jt808.server.service.ApiService;
import org.zqh.jt808.server.service.TDService;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@SpringBootTest
@Slf4j
class DBTest {
    @Resource
    private ApiService apiService;
    @Resource
    private TDService tdService;

    @Test
    public void td() {
        System.out.println(apiService.queryTD());
    }
    @Test
    public void mysql() {
        log.debug("{}",apiService.queryMySql());
    }

    /**
     * 查询所有坐标
     */
    @Test
    public void testLocationAll() {
        log.debug("{}",tdService.queryLocationAll());
    }

    /**
     * 查询所有坐标-设备列表
     */
    @Test
    public void testLocations() {
        List<String> list = new ArrayList<>();
        list.add("00000000000040904004");
        log.debug("{}",tdService.queryLocations(list));
    }

    /**
     * 查询实时坐标-单设备
     */
    @Test
    public void testLocation() {
        log.info("{}",tdService.queryLocation("00000000000040904004"));
    }

    /**
     * 查询历史轨迹
     */
    @Test
    public void testLocationHistory() {
        List<String> list = new ArrayList<>();
        list.add("00000000000040904004");
        Map<String, List<String>> map = new HashMap<>();
        map.put("deviceIds",list);
        String deviceId = "00000000000040904004";
        long startTime = System.currentTimeMillis();
        long endTime = System.currentTimeMillis();
        log.debug("{}",tdService.queryLocationHistory(deviceId,startTime,endTime));
    }
}

总结

直接执行测试类,执行成功查看数据库即可

相关推荐
Zhu7585 小时前
在k8s集群部署MySQL单实例,支持多个主流发行版
android·mysql·kubernetes
io无心9 小时前
Shardingsphere5分库分表
数据库·mysql
wWYy.9 小时前
Mysql:主键索引 唯一索引 普通索引 前缀索引
数据库·mysql
xiaoqiMikko14 小时前
Dependabot 面板全绿,不代表你的 Tomcat 没洞
java·spring boot
摇滚侠15 小时前
SpringBoot 官网 阅读笔记 启用生产就绪功能 端点
spring boot·笔记·后端
evans在进步15 小时前
HashMap 为什么线程不安全?ConcurrentHashMap 如何解决?
java·spring boot·spring
在世修行16 小时前
Windows 上 Docker Desktop 部署 MySQL + TDengine 全过程(含 WSL 报错与镜像加速排障实战)
windows·mysql·docker·tdengine
自律最差的编程狗18 小时前
从零搭建:VMware + Ubuntu + Docker + MySQL 完整指南
mysql·ubuntu·docker
tianyu23419 小时前
MySQL字符串处理函数完全指南:从入门到实战
mysql·字符串·函数·截取
天空之外13619 小时前
Docker安装MySQL 8.4 LTS、Docker安装Redis 7.4.x、Docker安装MinIO
java·mysql·docker