快速搭建一个SpringCloud、SpringBoot项目 || 项目搭建要点

news2024/11/27 14:31:20

1. 基本结构

在这里插入图片描述

  • 建立springcloud项目从表入手,分析好需求建立表结构后,使用mybatis-plux生成POJO类,在对应的model模块中。

2. 微服务部分架构

在这里插入图片描述

2.1 依赖

  • service 微服务模块的依赖仅包含如下,数据库等依赖包含在model中,service引入了model模块,因此也可以调用数据库服务。
<dependencies>
        <!-- 引入依赖模块,有model和common -->
        <dependency>
            <groupId>com.heima</groupId>
            <artifactId>heima-leadnews-model</artifactId>
        </dependency>
        <dependency>
            <groupId>com.heima</groupId>
            <artifactId>heima-leadnews-common</artifactId>
        </dependency>
        <dependency>
            <groupId>com.heima</groupId>
            <artifactId>heima-leadnews-feign-api</artifactId>
        </dependency>
        <!-- Spring boot starter -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
    </dependencies>

2.2 配置

  • 建立UserApplication启动类
    @SpringBootApplication 注解是在 Spring Boot 应用程序的入口类上使用的,它组合了多个注解的功能,包括 @Configuration、@EnableAutoConfiguration 和 @ComponentScan。
    @EnableDiscoveryClient 注解用于在 Spring Cloud 应用中启用服务发现功能,它会向服务注册中心注册服务,并且能够从服务注册中心获取其他服务的信息。
    @MapperScan 注解是 MyBatis 框架提供的,在 Spring Boot 项目中使用它可以指定要扫描的 MyBatis Mapper 接口的包路径,以便 MyBatis 能够找到这些接口并创建对应的代理对象。具体来说,当使用 @MapperScan 注解指定了要扫描的 Mapper 接口所在的包路径后,MyBatis 在启动时会扫描这些包,找到其中的接口,并根据接口中的方法定义和注解来自动生成对应的实现类(代理对象)。这些代理对象会通过动态代理的方式将接口中的方法映射为对数据库的具体操作,从而实现了接口方法与 SQL 操作的绑定。
@SpringBootApplication
@EnableDiscoveryClient
@MapperScan("com.heima.user.mapper")
public class UserApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserApplication.class,args);
    }
}
  • 建立微服务配置文件bootstrap.yml
    bootstrap.yml 是 Spring Cloud 微服务架构中用于进行应用程序初始化的配置文件。与 application.yml 或 application.properties 不同,bootstrap.yml 主要用于以下两个方面:

    1. 用于连接配置服务器:在微服务架构中,通常会使用配置中心(如Spring Cloud Config Server)来集中管理各个微服务的配置信息。bootstrap.yml 中的配置将会在应用程序启动时最先被加载,用于连接配置服务器并获取应用程序所需的配置信息。

    2. 用于加载外部配置:除了连接配置服务器外,bootstrap.yml 中还可以定义一些应用程序启动时所需的基础配置,例如连接数据库、设置日志级别等。这些配置项将在应用程序启动时优先加载,以确保应用程序能够正常初始化。

server:
  port: 51801
spring:
  application:
    name: leadnews-user
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
      config:
        server-addr: 127.0.0.1:8848
        file-extension: yml

bootstrap.yml 仅仅加了基本的配置,在nacos中继续配置,这里面的mysql、mybatis-plus的依赖就是2.1说的依赖

在这里插入图片描述
后期取出依赖使用@Value注解取出,例如下面
在这里插入图片描述

2.3 客户端通过post请求访问后端程序(controller)

在微服务的controller层中进行对应配置,让外界能够访问通提供的服务。注意四个注解

前端发送的必须是Post请求的请求体,且必须要是json格式(@RequestBody注解用于从HTTP请求体中获取数据,并将其映射到方法的参数上。通常与Spring框架中的RESTful风格的控制器方法一起使用,用于接收来自客户端的JSON或XML格式的数据。)

@RestController
@RequestMapping("/api/v1/login")
public class UserController {
    @PostMapping("/login_auth")
    public ResponseResult login(@RequestBody LoginDto loginDto){
        String  phone = loginDto.getPhone();
        String password = loginDto.getPassword();
        System.out.println(phone  + " , " + password);
        return ResponseResult.okResult("token");
    }
}

查看bootstrap中配置文件配置的服务端口:51801
在这里插入图片描述
访问:
在这里插入图片描述

2.4 使用mybatis_plus访问数据库(sercvice、mapper)

  1. 在model部分构建实体类,以及实体类的Dto对象。实体类其实就是表中的接口,可以直接使用mp生成代码,而dto就是data transform object,仅保留实际需要交互的。如用户登入仅需要前端传输 手机号、密码 即可。
  2. 在2.3 部分,前端已经可以访问通controller层了,现在需要访问service层和mapper层。其实可以直接代码生成,这里细致一点。
    mapper:
@Mapper
public interface ApUserMapper extends BaseMapper<ApUser> {}

serviceInterface:

public interface ApUserLoginService extends IService<ApUser> {
    public ResponseResult login(LoginDto loginDto);
}

serviceImpl:

@Service
@Transactional
@Slf4j //加了之后可以直接使用log对象来输出日志,而无需手动创建和初始化Logger对象。
public class ApUserLoginServiceImpl extends ServiceImpl<ApUserMapper,ApUser> implements ApUserLoginService {
    @Override
    public ResponseResult login(LoginDto loginDto) {...}
}
  1. 在service中如何访问数据库?原理是什么?
    简单一句话访问数据库
ApUser dbUser = getOne(Wrappers.<ApUser>lambdaQuery().eq(ApUser::getPhone, dto.getPhone()));

能直接调用getOne的原因:serviceInterface中 extends IService,IService中有getOne 方法,而Interface的实现类Impl那必然也能够直接访问这个子类方法。
下面是IService中的源码
在这里插入图片描述

参数: Wrappers.<ApUser>lambdaQuery().eq(ApUser::getPhone, dto.getPhone()) 其中Wrappers 是一个类

  • Wrappers.:Wrappers是 MyBatis-Plus 提供的用于构建查询条件的工具类,部分表示指定操作的实体类为ApUser。这里使用了泛型的语法,用于在运行时指定实体类的类型。

  • lambdaQuery():这是 MyBatis-Plus 中的一种链式调用方式,用于创建一个 LambdaQueryWrapper 对象,LambdaQueryWrapper 是用于构建带有 Lambda 表达式的查询条件的工具类。

  • .eq(ApUser::getPhone, dto.getPhone()):这是 LambdaQueryWrapper 的方法之一,表示添加一个等于条件。在这个例子中,它表示查询ApUser表中phone字段等于dto.getPhone()的记录。

3. common模块部分

application.yml

# 全局端口定义server:
# 全局字符集设置
spring:
  http:
    encoding:
      force: true
      charset: utf-8
      enabled: true
  aop:
    proxy-target-class: true
server:
  tomcat:
    uri-encoding: utf-8

3.1 springboot自动装配,使用 META-INF/spring.factories

springboot自动配置(简单来说就是自动把第三方组件的bean装载到IOC容器中,不需要开发人员再去写bean相关的一些配置,只要在启动类中加上@SpringbootApplication注解就可以实现自动装配。约定是第三方的starter启动依赖组件里面,必须有一个configuration配置类,在配置类里面声明@Bean代表是要被注册到IOC容器中的bean)

在这里插入图片描述
在这里插入图片描述

  • 当使用 META-INF/spring.factories 来自动加载 Swagger 配置时,我们需要遵循以下步骤:

创建 Swagger 配置类:编写一个配置类,用于配置 Swagger 相关的信息,例如扫描的包路径、API 文档信息、文档页面的访问路径等。这个配置类通常使用 @EnableSwagger2 或 @EnableSwagger3 注解来启用 Swagger。

package com.heima.common.swagger;
@Configuration
@EnableSwagger2
public class SwaggerConfiguration {

   @Bean
   public Docket buildDocket() {
      return new Docket(DocumentationType.SWAGGER_2)
              .apiInfo(buildApiInfo())
              .select()
              // 要扫描的API(Controller)基础包
              .apis(RequestHandlerSelectors.basePackage("com.heima"))
              .paths(PathSelectors.any())
              .build();
   }

   private ApiInfo buildApiInfo() {
      Contact contact = new Contact("黑马程序员","","");
      return new ApiInfoBuilder()
              .title("头条-平台管理API文档")
              .description("头条后台api")
              .contact(contact)
              .version("1.0.0").build();
   }
}

将配置类添加到 META-INF/spring.factories 文件中:在 META-INF 目录下创建一个名为 spring.factories 的文件,然后将配置类的全限定名添加到文件中,以实现自动加载和执行 Swagger 相关的配置。

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.config.SwaggerConfig

在上面的示例中,com.example.config.SwaggerConfig 是配置类的全限定名,通过将它添加到 spring.factories 文件中,Spring Boot 在启动时会自动加载和执行这个配置类,从而实现对 Swagger 的自动配置和集成。

总的来说,使用 META-INF/spring.factories 来自动加载 Swagger 配置的过程包括创建配置类并将其添加到 spring.factories 文件中,这样在应用程序启动时就会自动加载并执行 Swagger 相关的配置,无需手动初始化和配置,提高了集成的便捷性和效率。

  • 如果不使用 META-INF/spring.factories 来自动加载 Swagger 配置,你可以手动加载 SwaggerConfig 配置类。以下是一般的手动加载步骤:

在主应用程序类上添加 @Import 注解:打开主应用程序类(通常是带有 @SpringBootApplication 注解的类),并在类上方添加@Import(SwaggerConfig.class) 注解,将 SwaggerConfig 手动引入到应用程序中。


@SpringBootApplication
@Import(SwaggerConfig.class)
public class YourApplication {
    public static void main(String[] args) {
        SpringApplication.run(YourApplication.class, args);
    }
}

创建 Swagger 配置类:创建一个配置类,用于配置 Swagger 相关的信息,例如扫描的包路径、API 文档信息、文档页面的访问路径等。这个配置类应该使用 @Configuration 和 @EnableSwagger2 注解来标识。

@Configuration
@EnableSwagger2
public class SwaggerConfig {
    @Bean
    public Docket api() {
        return new Docket(DocumentationType.SWAGGER_2)
            .select()
            .apis(RequestHandlerSelectors.basePackage("com.example.controllers"))
            .paths(PathSelectors.any())
            .build();
    }
}

启动应用程序:启动应用程序后,Swagger 将会根据手动引入的 SwaggerConfig 类进行配置,并生成 API 文档信息。
通过以上步骤,你可以手动加载 SwaggerConfig 配置类,实现对 Swagger 的手动配置和集成。这种方式能够明确地控制配置类的加载过程,并且适用于一些特定的场景和需求。

3.2 接口工具 swagger、knife4j

Spring已经将Swagger纳入自身的标准,建立了Spring-swagger项目,现在叫Springfox。通过在项目中引入Springfox ,即可非常简单快捷的使用Swagger。

  1. 引入依赖
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
</dependency>
  1. knife4j配置
package com.heima.common.swagger;
@Configuration //作用是定义配置类
@EnableSwagger2
@EnableKnife4j
@Import(BeanValidatorPluginsConfiguration.class)
public class Swagger2Configuration {

    @Bean(value = "defaultApi2")
    public Docket defaultApi2() {
        Docket docket=new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                //分组名称
                .groupName("1.0")
                .select()
                //这里指定Controller扫描包路径
                .apis(RequestHandlerSelectors.basePackage("com.heima"))
                .paths(PathSelectors.any())
                .build();
        return docket;
    }
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("黑马头条API文档")
                .description("黑马头条API文档")
                .version("1.0")
                .build();
    }
}
  1. 在工程中进行配置(common模块下)
    文件:resources/META-INF/Spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.heima.common.exception.ExceptionCatch,\
  com.heima.common.swagger.SwaggerConfiguration,\
  com.heima.common.swagger.Swagger2Configuration
  1. 在微服务模块对应controller与Model中的Dto中加上对应的注解

我们在ApUserLoginController中添加Swagger注解,代码如下所示:

@RestController
@RequestMapping("/api/v1/login")
@Api(value = "app端用户登录", tags = "ap_user", description = "app端用户登录API")
public class ApUserLoginController {

    @Autowired
    private ApUserService apUserService;

    @PostMapping("/login_auth")
    @ApiOperation("用户登录")
    public ResponseResult login(@RequestBody LoginDto dto){
        return apUserService.login(dto);
    }
}

LoginDto

@Data
public class LoginDto {

    /**
     * 手机号
     */
    @ApiModelProperty(value="手机号",required = true)
    private String phone;

    /**
     * 密码
     */
    @ApiModelProperty(value="密码",required = true)
    private String password;
}

启动user微服务,访问地址:http://localhost:51801/swagger-ui.html

3.3 全局异常处理

  • 全局异常处理:@ControllerAdvice 注解可以配合 @ExceptionHandler 注解,用于统一处理应用程序中抛出的异常。通过在@ControllerAdvice类中定义@ExceptionHandler方法,可以捕获特定类型的异常,并进行统一的处理,比如返回特定的错误页面或者 JSON 响应。
@ControllerAdvice  //控制器增强类,就是标明,这个类就是用来统一处理异常的一个类
@Slf4j
public class ExceptionCatch {

    @ExceptionHandler(Exception.class) //里面加上想要捕获的异常
    @ResponseBody
    public ResponseResult exception(Exception e){
        e.printStackTrace();
        log.error("catch exception:{}",e.getMessage());

        return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR);
    }

    /**
     * 处理可控异常  自定义异常
     * @param e
     * @return
     */
    @ExceptionHandler(CustomException.class) //想捕获的异常是自定义异常
    @ResponseBody
    public ResponseResult exception(CustomException e){
        log.error("catch exception:{}",e);
        return ResponseResult.errorResult(e.getAppHttpCodeEnum());
    }
}

当遇到异常被try catch抛出的时候会被自定义类全局异常类捕获,进行我们自定义的操作,就不会返回一个500错误页面,而是自定义的页面

4. 网关部分

4.1 pom文件导入配置类

4.2 在heima-leadnews-gateway下创建heima-leadnews-app-gateway微服务,写好Application启动类,bootstrap.yml 配置文件,在nacos中写yml配置(如下)

spring:
  cloud:
    gateway:
      globalcors:
        add-to-simple-url-handler-mapping: true
        corsConfigurations:
          '[/**]':
            allowedHeaders: "*"
            allowedOrigins: "*"
            allowedMethods:
              - GET
              - POST
              - DELETE
              - PUT
              - OPTION
      routes:
        # 平台管理
        - id: user
          uri: lb://leadnews-user
          predicates: 
            - Path=/user/**
          filters:
            - StripPrefix= 1
  • id: user:给这个路由规则指定一个唯一的标识符。
  • uri: lb://leadnews-user:将匹配到的请求转发到名为leadnews-user的负载均衡服务,lb://表示使用负载均衡。
  • predicates:定义路由规则的谓词(predicate),这里使用Path=/user/**表示只有请求路径以/user/开头的请求会匹配到这个路由规则。
  • filters:配置过滤器,这里使用StripPrefix=1表示去除请求路径中的第一个路径段,例如将/user/foo转发到目标服务时会变成/foo。
    通过上述配置,当有请求路径以/user/开头时,Spring Cloud Gateway会将该请求转发到leadnews-user服务,并去除请求路径中的第一个路径段。你可以根据实际需求添加更多的路由规则和过滤器来构建复杂的网关功能。
    在这里插入图片描述

客户端向Spring Cloud Gateway发出请求。如果网关处理程序映射确定请求与路由匹配,则会将其发送到网关Web处理程序。此处理程序通过特定于请求的筛选器链来运行请求。过滤器被虚线分隔的原因是过滤器可以在发送代理请求之前和之后运行逻辑。执行所有“预”过滤器逻辑。然后进行代理请求。在发出代理请求后,将运行“post”过滤器逻辑。

4.3 全局过滤器JWT

在Spring Cloud Gateway中,你可以使用两种方式来定义过滤器链:

filters属性:通过在路由配置中使用filters属性,你可以直接在路由配置中指定过滤器集合。这些过滤器仅适用于特定的路由。示例如下:

spring:
  cloud:
    gateway:
      routes:
        - id: user
          uri: lb://leadnews-user
          predicates:
            - Path=/user/**
          filters:
            - StripPrefix=1
          # 其他过滤器...

在上述示例中,filters属性定义了一个过滤器集合,其中包含了StripPrefix过滤器。

GlobalFilter接口:通过实现GlobalFilter接口来编写全局过滤器,全局过滤器会应用于所有进入网关的请求。全局过滤器能够对所有路由生效,并且可以在请求和响应阶段进行修改或添加额外的处理逻辑。

@Component
public class CustomGlobalFilter implements GlobalFilter, Ordered {
    // 实现过滤器逻辑...
}
  • 总结一下两者的区别:
    filters属性用于在路由配置中为特定路由指定过滤器集合,仅对指定路由生效。
    GlobalFilter接口用于定义全局过滤器,对所有路由生效。
    你可以根据具体需求选择使用哪种方式来配置和定义过滤器。如果需要对所有路由应用相同的过滤逻辑,可以使用全局过滤器。如果只需对特定路由应用特定的过滤器链,可以使用filters属性。
    在这里插入图片描述

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

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

相关文章

【解决视觉引导多个位置需要标定多个位置的问题】

** 以下只针对2D定位&#xff0c;就是只有X、Y、Rz三个自由度的情况。** 假设一种情况&#xff0c;当视觉给机器人做引导任务时&#xff0c;零件有多个&#xff0c;分布在料框里&#xff0c;视觉需要走多个位置去拍&#xff0c;那么只需要对第一个位置确定拍照位&#xff0c;确…

力扣6:N字形变化

代码&#xff1a; class Solution { public:string convert(string s, int numRows){int lens.size();if(numRows1){return s;}int d2*numRows-2;int count0;string ret;//第一行&#xff01;for(int i0;i<len;id){rets[i];}//第k行&#xff01;for(int i1;i<numRows-1;…

智能优化算法应用:基于教与学算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于教与学算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于教与学算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.教与学算法4.实验参数设定5.算法结果6.参考文献7.…

超越GPT-4,拥有联网能力,Kimi-Chat大模型已免费使用,国内直接访问

目前ChatGPT的所有免费用户都已可以使用带有语音功能的ChatGPT。 人吧&#xff0c;总是贪婪的&#xff0c;我还想要ChatGPT Plus用户独享的“联网”功能。 目前对于ChatGPT来说&#xff0c;不想交钱&#xff0c;别拥有“联网”能力了&#xff0c;于是我找到了一个后起之秀&…

【差旅游记】新疆哈密回王府印象

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 2023年11月4号&#xff0c;那天的风的确挺大&#xff0c;逛完哈密博物馆考虑要不要去旁边的哈密回王府逛逛。想着来都来了&#xff0c;虽然网上评价不太好&#xff0c;还是去溜达一圈吧&#xff0c;于是决定自己去转转…

为啥网络安全那么缺人,但很多人却找不到工作?

文章目录 一、学校的偏向于学术二、学的东西太基础三、不上班行不行 为什么网络安全的人才缺口那么大&#xff0c;但是大学毕业能找到网安工作的人却很少&#xff0c;就连招聘都没有其他岗位多&#xff1f; 明明央视都说了网络安全的人才缺口还有300多万&#xff0c;现在找不到…

C++ 用ifstream读文件

输入流的继承关系: C++ 使用标准库类来处理面向流的输入和输出: iostream 处理控制台 IOfstream 处理命名文件 IOstringstream 完成内存 string 的 IO每个IO 对象都维护一组条件状态 flags (eofbit, failbit and badbit),用来指出此对象上是否可以进行 IO 操作。如果遇到错误…

vue实战——登录【详解】(含自适配全屏背景,记住账号--支持多账号,显隐密码切换,登录状态保持)

效果预览 技术要点——自适配全屏背景 https://blog.csdn.net/weixin_41192489/article/details/119992992 技术要点——密码输入框 自定义图标切换显示隐藏 https://blog.csdn.net/weixin_41192489/article/details/133940676 技术要点——记住账号&#xff08;支持多账号&…

「江鸟中原」有关HarmonyOS-ArkTS的Http通信请求

一、Http简介 HTTP&#xff08;Hypertext Transfer Protocol&#xff09;是一种用于在Web应用程序之间进行通信的协议&#xff0c;通过运输层的TCP协议建立连接、传输数据。Http通信数据以报文的形式进行传输。Http的一次事务包括一个请求和一个响应。 Http通信是基于客户端-服…

进程等待讲解

今日为大家分享有关进程等待的知识&#xff01;希望读完本文&#xff0c;大家能有一定的收获&#xff01; 正文开始&#xff01; 进程等待的引进 既然我们今天要讲进程等待这个概念&#xff01;那么只有我们把下面这三个方面搞明白&#xff0c;才能真正的了解进程等待&#x…

形象建设、生意经营、用户运营,汽车品牌如何在小红书一举多得?

随着小红书在多领域的持续成长&#xff0c;现在来小红书看汽车的用户&#xff0c;需求逐渐多元化与专业化。近1年的时间&#xff0c;有超过1亿人在小红书「主动搜索」过汽车内容&#xff0c;大家已经不仅限于玩车、用车&#xff0c;更是扩展到了百科全书式的看、选、买、学各个…

Python3 selenium 设置元素等待的三种方法

为什么要设置元素等待&#xff1f; 当你的网络慢的时候&#xff0c;打开网页慢&#xff0c;网页都没完全打开&#xff0c;代码已经在执行了&#xff0c;但是没找到你定位的元素&#xff0c;此时python会报错。 当你的浏览器或电脑反应慢&#xff0c;网页没完全打开&#xff0c;…

12、模块化编程

模块化编程 1、传统方式编程&#xff1a;所有的函数均放在main.c里&#xff0c;若使用的模块比较多&#xff0c;则一个文件内会有很多的代码&#xff0c;不利于代码的组织和管理&#xff0c;而且很影响便朝着的思路 2、模块化编程&#xff1a;把各个模块的代码放在不同的.c文件…

java--单继承、Object

java是单继承的&#xff0c;java中的类不支持多继承&#xff0c;但是支持多层继承。 反证法&#xff1a; 如果一个类同时继承两个类&#xff0c;然后两个类中都有同样的一个方法&#xff0c;哪当我创建这个类里的方法&#xff0c;是调用哪父类的方法 所以java中的类不支持多继…

PostgreSQL + SQL Server = WiltonDB

WiltonDB 是一个基于 PostgreSQL 的开源数据库&#xff0c;通过 Babelfish 插件支持 Microsoft SQL Server 协议以及 T-SQL 语句。 Babelfish 是亚马逊提供的一个开源项目&#xff0c;使得 PostgreSQL 数据库同时具有 Microsoft SQL Server 数据查询和处理的能力。Babelfish 可…

11、动态数码管显示

数码管驱动方式 1、单片机直接扫描&#xff1a;硬件设备简单&#xff0c;但会消耗大量的单片机CPU时间 2、专用驱动芯片&#xff1a;内部自带显存、扫描电路&#xff0c;单片机只需告诉他显示什么即可 #include <REGX52.H> //数组代表显示亮灯的内容0、1、2、3、4、5、…

单车模型及其线性化

文章目录 1 单车模型2 线性化3 实现效果4 参考资料 1 单车模型 这里讨论的是以后轴为中心的单车运动学模型&#xff0c;由下式表达&#xff1a; S ˙ [ x ˙ y ˙ ψ ˙ ] [ v c o s ( ψ ) v s i n ( ψ ) v t a n ( ψ ) L ] \dot S \begin{bmatrix} \dot x\\ \dot y\\ \d…

C++ : 初始化列表 类对象作为类成员

传统方式初始化 C 提供了初始化列表语法&#xff0c;用来初始化属性 初始化列表 语法&#xff1a; 构造函数()&#xff1a;属性1(值1), 属性2&#xff08;值2&#xff09;... {} class Person { public://传统方式初始化 Person(int a, int b, int c) {m_A a;m_B b;m_C c…

python之pyqt专栏6-信号与槽2

上一篇python之pyqt专栏5-信号与槽1-CSDN博客&#xff0c;我们通过信号与槽实现了点击Button&#xff0c;改变Label的文本内容。可以知道 信号是在类中定义的&#xff0c;是类的属性 槽函数是信号通过connect连接的任意成员函数&#xff0c;当信号发生时&#xff0c;执行与信号…

FFmpeg架构全面分析

一、简介 它的官网为&#xff1a;https://ffmpeg.org/&#xff0c;由Fabrice Bellard&#xff08;法国著名程序员Born in 1972&#xff09;于2000年发起创建的开源项目。该人是个牛人&#xff0c;在很多领域都有很大的贡献。 FFmpeg是多媒体领域的万能工具。只要涉及音视频领…