springboot配置多数据源mysql+TDengine保姆级教程
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 前言
- 一、pom文件
- 二、yaml
- DataSourceConfig
- Service
- Mapper.xml
- 测试
- 总结
前言
Mybatis-plus管理多数据源,数据库为mysql和TDengine。
一、pom文件
<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
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#2024dynamic:primary: master # 设置默认的数据源strict: false # 严格按照路由规则从主库读取数据,如果主库不可用,则从从库读取数据。datasource:master:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/wh_vehicles?useUnicode=true&characterEncoding=UTF-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&serverTimezone=Asia/Shanghaiusername: rootpassword: 123slave:driver-class-name: com.taosdata.jdbc.rs.RestfulDriverurl: jdbc:TAOS-RS://localhost:6041?timezone=UTC-8&charset=utf-8&useSSL=false&user=root&password=123# using connection poolstype: com.alibaba.druid.pool.DruidDataSourcedruid:initial-size: 5min-idle: 5max-active: 20max-wait: 60000time-between-eviction-runs-millis: 60000min-evictable-idle-time-millis: 300000validation-query: SELECT 1pool-prepared-statements: truemax-pool-prepared-statement-per-connection-size: 20
# mybatis
mybatis-plus:mapper-locations: classpath:mapper/*.xmltype-aliases-package: org.zqh.jt808.server.model
DataSourceConfig
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
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_";@Autowiredprivate 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 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_locationswhere 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_locationsgroup by tbname;</select><select id="queryLocation" resultType="cn.hutool.json.JSONObject">select last_row(deviceId),deviceId,ts,longitude,latitude,height,speed,directionfrom wh_special_equipment.device_locationswhere deviceId = #{deviceId}</select>
</mapper>
测试
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 {@Resourceprivate ApiService apiService;@Resourceprivate TDService tdService;@Testpublic void td() {System.out.println(apiService.queryTD());}@Testpublic void mysql() {log.debug("{}",apiService.queryMySql());}/*** 查询所有坐标*/@Testpublic void testLocationAll() {log.debug("{}",tdService.queryLocationAll());}/*** 查询所有坐标-设备列表*/@Testpublic void testLocations() {List<String> list = new ArrayList<>();list.add("00000000000040904004");log.debug("{}",tdService.queryLocations(list));}/*** 查询实时坐标-单设备*/@Testpublic void testLocation() {log.info("{}",tdService.queryLocation("00000000000040904004"));}/*** 查询历史轨迹*/@Testpublic 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));}
}
总结
直接执行测试类,执行成功查看数据库即可
相关文章:
springboot配置多数据源mysql+TDengine保姆级教程
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、pom文件二、yamlDataSourceConfigServiceMapper.xml测试总结 前言 Mybatis-plus管理多数据源,数据库为mysql和TDengine。 一、pom文件 <de…...
dns实验2:反向解析
启动服务: 给虚拟机网卡添加IP地址: 查看有几个IP地址: 打开配置文件: 重启服务,该宽松模式,关闭防火墙: 本机测试: windows测试:(本地shell)...
ZooKeeper 基础知识总结
先赞后看,Java进阶一大半 ZooKeeper 官网这样介绍道:ZooKeeper 是一种集中式服务,用于维护配置信息、命名、提供分布式同步和提供组服务。 各位hao,我是南哥,相信对你通关面试、拿下Offer有所帮助。 ⭐⭐⭐一份南哥编写…...
npm库xss依赖的使用方法和vue3 中Web富文本编辑器 wangeditor 使用xss库解决 XSS 攻击的方法
npm库xss依赖的使用方法和vue3 中Web富文本编辑器 wangeditor 使用xss库解决 XSS 攻击的方法 1. npm库xss依赖的使用方法1.1 xss库定义1.2 xss库功能 2. vue3 中 wangeditor 使用xss库解决 XSS 攻击的方法和示例2.1 在终端执行如下命令安装 xss 依赖2.2 在使用 wangeditor 的地…...
微信小程序蓝牙writeBLECharacteristicValue写入数据返回成功后,实际硬件内信息查询未存储?
问题:连接蓝牙后,调用小程序writeBLECharacteristicValue,返回传输数据成功,查询硬件响应发现没有存储进去? 解决:一直以为是这个write方法的问题,找了很多相关贴,后续进行硬件日志…...
5G NR:带宽与采样率的计算
100M 带宽是122.88Mhz sampling rate这是我们都知道的,那它是怎么来的呢? 采样率 子载波间隔 * 采样长度 38.211中对于Tc的定义, 在LTE是定义了Ts,在NR也就是5G定义了Tc。 定义这个单位会对我们以后工作中的计算至关重要。 就是在…...
go 和java 编写方式的理解
1. go 推荐写流水账式的代码(非贬义),自己管自己。java喜欢封装各种接口供外部调用,让别人来管自己。 2. 因为协程的存在, go的变量作用域聚集在方法内部,即函数不可重入,而java线程的限制&…...
C# 7.1 .Net Framwork4.7 VS2017环境下,方法的引用与调用
方法的调用比较好理解,就是给方法传递实参,执行方法代码。 方法引用涉及委托,委托签名与其引用的方法必须一致。以下demo说明方法调用与引用在写程序时的区别: using System; using System.Collections.Generic; using System.L…...
etcd、kube-apiserver、kube-controller-manager和kube-scheduler有什么区别
在我们部署K8S集群的时候 初始化master节点之后(在master上面执行这条初始化命令) kubeadm init --apiserver-advertise-address10.0.1.176 --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.16.0 --service…...
每日一题 LCR 057. 存在重复元素 III
LCR 057. 存在重复元素 III 滑动窗口二分查找 有序集合 有lower_bound(num) ,可以找到第一个大于其的数字 class Solution { public:bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {set<long> win;for(int i0;i<nums.size();i){a…...
使用IDEA编写测试用例,复杂度校验
最近我们公司要求开发人员必须写测试用例,组织了TDD培训,测试驱动开发,同时衡量代码的圈复杂度,我记录下初次使用的过程。 编写测试用例,查看用例覆盖度 1、要编写测试用例,并看下测试用例的覆盖度&#…...
搭建私有云存储
1、安装LNMP环境 yum install nginx -y yum install -y nginx mariadb-server php php-fpm php-mysqlnd systemctl restart nginx.service --- 启动Nginx systemctl start mariadb.service ---启动数据库 mysql -e create database lxdb character set utf8 ---创建数据库 my…...
【从零开始的LeetCode-算法】3304. 找出第 K 个字符 I
Alice 和 Bob 正在玩一个游戏。最初,Alice 有一个字符串 word "a"。 给定一个正整数 k。 现在 Bob 会要求 Alice 执行以下操作 无限次 : 将 word 中的每个字符 更改 为英文字母表中的 下一个 字符来生成一个新字符串,并将其 追加 到原始的…...
深入解析分布式遗传算法及其Python实现
目录 深入解析分布式遗传算法及其Python实现目录第一部分:分布式遗传算法的背景与原理1.1 遗传算法概述1.2 分布式遗传算法的引入1.3 分布式遗传算法的优点与挑战优点:挑战:第二部分:分布式遗传算法的通用Python实现2.1 基本组件的实现第三部分:案例1 - 基于多种交叉与变异…...
gitee:创建仓库,存入本地文件至仓库
一、git下载 git:下载与安装-CSDN博客https://blog.csdn.net/weixin_46001736/article/details/144107485?sharetypeblogdetail&sharerId144107485&sharereferPC&sharesourceweixin_46001736&spm1011.2480.3001.8118 二、创建仓库 1、主页面->右上角新增…...
计算分数的浮点数值
计算分数的浮点数值 C语言代码C 代码Java代码Python代码 💐The Begin💐点点关注,收藏不迷路💐 两个整数a和b分别作为分子和分母,既分数 a/b ,求它的浮点数值(双精度浮点数,保留小数点…...
在 C/C++ 中,volatile 关键字的作用是什么?.volatile 关键字与 const 关键字有什么区别?
volatile关键字用于告诉编译器,被修饰的变量可能会被程序以外的因素(如硬件、操作系统等)修改,因此每次访问该变量时都应该从内从中读取他的值,而不是使用可能存在的缓存之,这在多线程编程,与硬…...
golang debug调试
1. 本地调试 1:Add Configurations 添加配置文件(Run kind :Directory) 2:进入run运行窗口 3:debug断点调试模式 1. Resume Program (继续运行) 图标: ▶️ 或 ► 快捷键: F9(Windows/Linux&a…...
自动化运维(k8s)之微服务信息自动抓取:namespaceName、deploymentName等全解析
前言:公司云原生k8s二开工程师发了一串通用性命令用来查询以下数值,我想着能不能将这命令写成一个自动化脚本。 起初设计的 版本一:开头加一条环境变量,执行脚本后,提示输入:需要查询的命名空间,…...
07 初始 Oracle 优化器
查询优化器,简称优化器,是数据库最核心的组件之一。我们在这个系列的第一篇文章中已经给大家介绍了,优化器会参与到SQL语句的解析过程中,用来生成SQL语句的执行计划,直接决定SQL语句执行性能的优劣。 什么是执行计划 …...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...
HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
PostgreSQL——环境搭建
一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在࿰…...
