SpringBoot3+最新MybatisPlus+Mysql与TDengine双数据源

news2024/11/23 12:30:50

前言

       昨天写的idea+Apifox uploader插件+apifox新年第一天上班就上榜了,真是不错。今天来补一篇,本来应该是在前一篇之前发的。实际上就是最新的springBoot集成最新的mybatisPlus,加双数据源:mysql、TDengine,一个关系型数据库,一个时序数据库。文末有独家demo的git地址。
       springBoot3集成的哦,其他依赖也都是最新版本,独家的哦。好了,不废话,直接上重点。


一、新建最新springBoot3项目

       这个没有啥好说的,就是选择spring项目了,下一步下一步,直接看引入的包吧。
pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.0.1</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.xiaotian</groupId>
    <artifactId>data-trans</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>data-trans</name>
    <description>data-trans</description>

    <properties>
        <java.version>17</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <tlog.version>1.4.3</tlog.version>
        <skipTests>true</skipTests>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- undertow容器支持 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-undertow</artifactId>
            <version>3.0.1</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>3.0.1</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.3.1</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
            <version>3.5.3.1</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-extension</artifactId>
            <version>3.5.3.1</version>
        </dependency>

        <dependency>
            <groupId>com.taosdata.jdbc</groupId>
            <artifactId>taos-jdbcdriver</artifactId>
            <version>3.0.3</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.30</version>
        </dependency>

        <!-- 多数据源支持 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
            <version>3.3.6</version>
        </dependency>


        <!--redis -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <version>2.7.5</version>
        </dependency>
        <!-- Lettuce redis支持 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>

        <!-- TLog引入支持 -->
        <dependency>
            <groupId>com.yomahub</groupId>
            <artifactId>tlog-all-spring-boot-starter</artifactId>
            <version>${tlog.version}</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.5.3.1</version>
        </dependency>

        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.3</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>

            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>3.0.1</version>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

项目结构:
在这里插入图片描述

二、关键代码

1.多数据源配置

application.yml

#容器配置
server:
  port: 8199
  servlet:
    context-path: /datatrans
  shutdown: graceful
#spring基础配置

spring:
  application:
    name: dataTrans
  freemarker:
    check-template-location: false
    cache: false
  global:
    date-format: yyyy-MM-dd HH:mm:ss
  mvc:
    throw-exception-if-no-handler-found: true
    static-path-pattern: /**
  web:
    resources:
      static-locations: classpath:/resources/,classpath:/static/,classpath:/templates/
  profiles:
    active: dev
  servlet:
    multipart:
      max-file-size: 300MB
      max-request-size: 500MB
  thymeleaf:
    cache: false
    prefix: classpath:/templates/
    check-template-location: true
    suffix: .html
    encoding: UTF-8
    servlet:
      content-type: text/html
    mode: HTML
  main:
    allow-circular-references: true

#日志配置
logging:
  config: classpath:logback-spring.xml
  file:
    name: ./logs/dataTrans.log
  level:
    com:
      xiaotian:
        datagenius:
          mapper: debug
    root: info
path:
  log: ./logs/dataTrans/

#TLog轻量级日志追踪
tlog:
  pattern: '[$preApp][$preIp][$spanId][$traceId]'


#放行url配置
web:
  pass:
    url: /**,/**/actuator/**

application-dev.yml

spring:
  datasource:
    dynamic:
      primary: mysql-service
    mysql-service:
      driver-class-name: com.mysql.cj.jdbc.Driver
      jdbc-url: jdbc:mysql://localhost:3306/wz?useUnicode=true&serverTimezone=Asia/Shanghai&allowMultiQueries=true&allowMultiQueries=true
      username: root
      password: 123456
      type: com.zaxxer.hikari.HikariDataSource
      minimum-idle: 5                 #最小连接
      maximum-pool-size: 15        #最大连接
      auto-commit: true        #自动提交
      idle-timeout: 30000        #最大空闲时常
      pool-name: MysqlDruidCP        #连接池名
      max-lifetime: 1800000        #最大生命周期
      connection-timeout: 30000        #连接超时时间
    tdengine-service:
      driver-class-name: com.taosdata.jdbc.TSDBDriver
      jdbc-url: jdbc:TAOS://ip:6030/test?user=root&password=taosdata&timezone=GMT%2b8
      username: root
      password: taosdata
      pool-name: Data_trans_HikariCP
      minimum-idle: 10 #最小空闲连接数量
      idle-timeout: 600000 #空闲连接存活最大时间,默认600000(10分钟)
      maximum-pool-size: 100 #连接池最大连接数,默认是10
      auto-commit: true  #此属性控制从池返回的连接的默认自动提交行为,默认值:true
      max-lifetime: 1800000 #此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认1800000即30分钟
      connection-timeout: 30000 #数据库连接超时时间,默认30秒,即30000
      connection-test-query: SELECT 1

  #缓存配置
  data:
    redis:
      password: password
      cluster:
        max-redirects: 3
        nodes: 127.0.0.1:6379
      host: ip
      port: 6379
      database: 0
      timeout: 6000

#redis连接配置
redis:
  hostName: ${spring.data.redis.host}
  minIdle: 10
  maxIdle: 300
  maxTotal: 1000
  maxWaitMillis: 1000
  minEvictableIdleTimeMillis: 300000
  numTestsPerEvictionRun: 1024
  password: ${spring.data.redis.password}
  port: ${spring.data.redis.port}
  testOnBorrow: true
  testWhileIdle: true
  timeBetweenEvictionRunsMillis: 30000
  timeout: 10000

2.核心代码

mysql数据源配置类(MysqlServerConfig):

package com.xiaotian.datatrans.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
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 org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;
import java.util.Collections;


/**
 * mysql配置类
 * @author zhengwen
 */
@Configuration
@MapperScan(basePackages = {"com.xiaotian.datatrans.mapper.mysql"}, sqlSessionTemplateRef  = "mysqlSqlSessionTemplate")
public class MysqlServerConfig {

    @Autowired
    private PaginationInnerInterceptor paginationInnerInterceptor;

    private static final String MAPPER_LOCATION = "classpath:mapper/tdengine/*.xml";
    @Bean(name = "mysqlDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.mysql-service")
    @Primary
    public DataSource mysqlDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "mysqlSqlSessionFactory")
    @Primary
    public SqlSessionFactory mysqlSqlSessionFactory(@Qualifier("mysqlDataSource") DataSource dataSource) throws Exception {
        //注意这里一定要用MybatisSqlSessionFactoryBean,如果用SqlSessionFactory,配置无效
        MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCATION));

        //不在这里注入分页插件,会失效,(MyBatisPlusConfig只负责注册分页插件)
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        paginationInnerInterceptor.setMaxLimit(-1L);
        paginationInnerInterceptor.setDbType(DbType.MYSQL);
        // 开启 count 的 join 优化,只针对部分 left join
        paginationInnerInterceptor.setOptimizeJoin(true);
        mybatisPlusInterceptor.setInterceptors(Collections.singletonList(paginationInnerInterceptor));
        bean.setPlugins(mybatisPlusInterceptor);

        return bean.getObject();
    }

    @Bean(name = "mysqlTransactionManager")
    @Primary
    public DataSourceTransactionManager mysqlTransactionManager(@Qualifier("mysqlDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "mysqlSqlSessionTemplate")
    @Primary
    public SqlSessionTemplate mysqlSqlSessionTemplate(@Qualifier("mysqlSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

TDengine数据源配置类(TDengineServerConfig):

package com.xiaotian.datatrans.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
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.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;
import java.util.Collections;


/**
 * TDengine配置类
 *
 * @author zhengwen
 */
@Configuration
@MapperScan(basePackages = "com.xiaotian.datatrans.mapper.tdengine", sqlSessionTemplateRef = "tdengineSqlSessionTemplate")
public class TDengineServerConfig {

    @Autowired
    private PaginationInnerInterceptor paginationInnerInterceptor;

    private static final String MAPPER_LOCATION = "classpath:mapper/tdengine/*.xml";

    @Bean(name = "tdengineDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.tdengine-service")
    public DataSource tdengineDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "tdengineSqlSessionFactory")
    public SqlSessionFactory tdengineSqlSessionFactory(@Qualifier("tdengineDataSource") DataSource dataSource) throws Exception {
        MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCATION));

        //不在这里注入分页插件,会失效,(MyBatisPlusConfig只负责注册分页插件)
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        paginationInnerInterceptor.setMaxLimit(-1L);
        paginationInnerInterceptor.setDbType(DbType.TDENGINE);
        // 开启 count 的 join 优化,只针对部分 left join
        paginationInnerInterceptor.setOptimizeJoin(true);
        mybatisPlusInterceptor.setInterceptors(Collections.singletonList(paginationInnerInterceptor));
        bean.setPlugins(mybatisPlusInterceptor);

        return bean.getObject();
    }

    @Bean(name = "tdengineTransactionManager")
    public DataSourceTransactionManager tdengineTransactionManager(@Qualifier("tdengineDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }


    @Bean(name = "tdengineSqlSessionTemplate")
    public SqlSessionTemplate tdengineSqlSessionTemplate(@Qualifier("tdengineSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }


}

Mapper上注意指定数据源,例如:

package com.xiaotian.datatrans.mapper.tdengine;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiaotian.datatrans.entity.Student;
import org.apache.ibatis.annotations.Param;

/**
 * @author zhengwen
 */
@DS("tdengine-service")  //指定数据源注解,名称与配置数据源名称一致
public interface StudentMapper extends BaseMapper<Student> {

    /**
     * 插入
     * @param record
     * @return
     */
    int insertStudent(Student record);

    /**
     * 列表
     * @param page
     * @param customQueryParams
     * @return
     */
    IPage<Student> selectStudentPage(Page page,@Param("student") Student customQueryParams);
}

3.核心注意点

先看启动类:

package com.xiaotian.datatrans;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;

/**
 * @author zhengwen
 */

@EntityScan("com.xiaotian")
@SpringBootApplication
public class DataTransApplication {

    public static void main(String[] args) {
        SpringApplication.run(DataTransApplication.class, args);
        System.out.println("--数据精灵启动成功--");
    }

}

1、Mapper扫描问题:
       细心的小伙伴可能知道,一般springboot的,要么在配置里配置mapper的包路径,要么在启动类上写注解@MapperScan(“包路径”),如果是多个@MapperScan(basePackages = {“com.xx..mapper","com.xxx..dao”}),但是我这里配置里没有配置,启动类也没有注解,为什么呢?
       原因其实很简单,这些预制的基础配置都是给单数据源用的,如果用多数据源,那么各个mapper就要对应不同的数据源,所以这些mapper扫描,在数据源配置类上设置了。大家可以回头看看我的2个数据源配置类是不是有注解@MapperScan。
2、分页插件问题
       一般单数据源,那么只需要一个分页插件配置类就行,例如我这里的MyBatisPlusConfig.java。
       但是这里因为是多数据源,所以插件的设置需要在数据源上做拦截,大家可以看看我2个数据源里的sessionFactory里的MybatisPlusInterceptor设置。
       另外这里要注意的是最新版本的mybatisPlus已经用PaginationInnerInterceptor拦截器了,原先的PaginationInterceptor已经废除了。


总结

  • mybatisPlus真香,支持的数据源真多
  • mybatisPlus、分页插件支持TDengine不久,TDengine的更新是用insert操作的,只是时间挫是一致的就行,但是mybatisPlus的BaseMapper里的update方法并不会根据数据源使用insert组织sql。
  • mybatisPlus在3.4.2时移除了Rest Api
  • CSDN的gitcode也真香啊
  • 本次案例的整个demo就在我的gitcode里,公开的,git下载以后,改改配置里的数据源ip、账号、密码,建表就可以看到效果了。地址:https://gitcode.net/zwrlj527/data-trans.git
           好了,就到这里,希望可以帮到大家,uping!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/185531.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

kvm虚拟机克隆

kvm虚拟机克隆链接克隆和完整克隆的区别完整克隆自动克隆手动克隆的步骤1.复制模板vm磁盘为新vm的磁盘2.复制模板vm配置文件为新vm的配置文件3.修改新vm配置文件中的信息为新vm的信息4.导入新vm的配置文件5.启动新vm链接克隆1.生成链接克隆虚拟机磁盘文件2.后续流程与手动克隆一…

【算法练习】链表中环的入口结点

题源&#xff1a;牛客描述给一个长度为n链表&#xff0c;若其中包含环&#xff0c;请找出该链表的环的入口结点&#xff0c;否则&#xff0c;返回null。数据范围&#xff1a;n≤10000&#xff0c;1<结点值<10000要求&#xff1a;空间复杂度 O(1)&#xff0c;时间复杂度O(…

1、数据库概述

文章目录1 为什么要使用数据库2 数据库与数据库管理系统2.1 数据库的相关概念2.2 数据库与数据库管理系统的关系2.3 常见的数据库管理系统排名(DBMS)2.4 常见的数据库介绍3 MySQL介绍3.1 概述3.2 MySQL发展史重大事件3.3 关于MySQL 8.03.4 为什么选择MySQL3.5 Oracle vs MySQL4…

学成在线项目开发技巧整理---第二部分

1.静态资源处理通常项目会采用动静分离架构,利用Nginx作为静态资源服务器,存放所有静态资源:#访问动态资源时,将请求负载均衡到多个服务器实例或者多个网关实例 upstream webservice{server 192.168.200.146:8080; }server {listen 80;server_name localhost;#动态资源l…

C++基础知识点整理笔记(一)

一直想尝试自己动手构建一个简单的深度学习训练框架&#xff0c;包括数据读取与处理、PS、NN前后向传播、模型save和load、不同训练方式&#xff08;offline/online .etc&#xff09;、指标监控、模型部署等部分, 去深入研究内部深度学习训练框架及horovod、byteps、pslite、te…

深刻理解状态机设计需要避免的冒险;时序电路可能存在essential hazard;处理单元里的control和datapath;竞争冒险【SV】【VLSI】

深刻理解状态机设计需要避免的冒险&#xff1b;时序电路可能存在essential hazard&#xff1b;处理单元里的control和datapath&#xff1b;竞争冒险【SV】【VLSI】0. 前言&#xff1a;时序电路可能存在essential hazard1. 理解control和datapath1.1 Datapath control2. 硬件电路…

MFC|创建一个对话框及窗体各个属性介绍

参考&#xff1a; VS2015 建立一个C的MFC简易窗体程序项目&#xff08;https://www.cnblogs.com/xingboy/p/11059721.html&#xff09; 对话框中各项属性介绍&#xff08;https://blog.csdn.net/u012350993/article/details/26093051&#xff09; MFC窗口风格 WS_style/WS_EX_s…

【Hadoop】YARN简述

文章目录1. YARN总述2. YARN调度器2.1 FIFO Scheduler2.2 Capacity Scheduler2.3 Fair Scheduler1. YARN总述 YARN是Hadoop资源管理器&#xff0c;它是一个通用资源管理系统&#xff0c;可为上层应用提供统一的资源管理和调度&#xff0c;它的引入为集群在利用率、资源统一管理…

关于栈和队列

目录栈&#xff08;Stack&#xff09;什么是栈栈的使用栈的模拟实现队列&#xff08;Queue&#xff09;什么是队列队列的使用队列的模拟实现循环队列双端队列 (Deque)栈&#xff08;Stack&#xff09; 什么是栈 栈是一种特殊的线性表&#xff0c;它只允许在固定的一端进行插入…

JavaScriptArray和String对象~

初识Array&#xff1a; 定义&#xff1a; 方式1 var 变量名new Array(元素列表);举例&#xff1a; <script>var arraynew Array(1,2,3);alert(array); </script>显示如下&#xff1a; 方式2 var 变量名[元素列表];举例&#xff1a; <script>var array[…

App Inspector使用 (macaca移动端元素检查器)

App Inspector安装说明&#xff1a;https://macacajs.github.io/app-inspector/zh/guide/install.html#%E7%8E%AF%E5%A2%83%E9%9C%80%E8%A6%81 依赖安装说明&#xff1a; 1、node环境&#xff1a;这里安装的时候和初始化的时候报错使用了两个版本&#xff0c;所以这里使用nvm…

Python-模块、包和发布模块

1.模块1.1模块的概念模块是python程序架构的一个核心概念每一个以扩展名.py结尾的python源代码文件都是一个模块模块名同样也是一个标识符&#xff0c;需要符合标识符的命名规则在模块中定义的全局变量、函数、类都是提供给外界直接使用的工具模块就好比工具包&#xff0c;要想…

世界坐标系->相机坐标系详细推导

基变换 理论部分 在n维的线性空间中&#xff0c;任意n个线性无关的向量都可以作为线性空间的基&#xff0c;即空间基不唯一。对于不同的基&#xff0c;同一个向量的坐标一般是不同的。因为在计算机图形学中&#xff0c;主要研究三维的空间&#xff0c;所以可以简化问题倒三维…

Hi3861鸿蒙物联网项目实战:智能测距仪

华清远见FS-Hi3861开发套件&#xff0c;支持HarmonyOS 3.0系统。开发板主控Hi3861芯片内置WiFi功能&#xff0c;开发板板载资源丰富&#xff0c;包括传感器、执行器、NFC、显示屏等&#xff0c;同时还配套丰富的拓展模块。开发板配套丰富的学习资料&#xff0c;包括全套开发教程…

真假流量卡区别,一篇文章教你怎么区分流量卡和物联卡!

真假流量卡区别&#xff0c;小编教你怎么区分流量卡和物联卡&#xff0c;近年来&#xff0c;市面上的流量卡种类繁多&#xff0c;其中不乏有一些虚假的、有套路的套餐&#xff0c;那么&#xff0c;我们如何辨别流量卡的正规性呢&#xff0c;接下来&#xff0c;跟着小编一块来了…

114.简单的动态切换app的图标,两种方式

第一种方式&#xff1a; 1.第一步 通过activity-alias别名实现&#xff0c;manifest 这里写的是一个默认的图标Default和一个需要切换的图标Test&#xff0c;以及一个默认的首页面HomeActivity&#xff1a; <!-- 默认的图标--> <activity-aliasandroid:name".ac…

基于java SSM springboot+redis网上水果超市商城设计和实现以及文档

基于java SSM springbootredis网上水果超市商城设计和实现以及文档 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java毕设项目精品实战案例《500套》 欢迎点赞 收藏 ⭐留…

java8中stream流式编程的使用大全

一、概述 Stream流操作是Java 8提供一个重要新特性&#xff0c;它允许开发人员以声明性方式处理集合&#xff0c;其核心类库主要改进了对集合类的API和新增Stream操作。Stream类中每一个方法都对应集合上的一种操作。将真正的函数式编程引入到Java中&#xff0c;能 让代码更加简…

Node.js教程笔记(四)数据库与身份认证

学习目标 1、能够知道如何配置Mysql数据库环境 2、能够认识并使用常见的SQL语句操作数据库 3、能够在Express中操作Mysql数据库 4、能够了解Session的实现原理 5、能够了解JWT的实现原理 目录 1、数据库的基本概念 2、安装并配置Mysql 3、Mysql的基本使用 4、在Expre…

全球数十万客户选择亚马逊云科技数据库服务构建自己的应用

日前&#xff0c;全球市场分析机构Gartner发布《2022云数据库管理系统魔力象限》报告&#xff08;2022 Gartner Magic Quadrant™ for Cloud Database Management Systems&#xff09;。Gartner数据显示&#xff0c;整个数据库管理系统市场在2021年实现强劲增长22.3%&#xff0…