【wiki知识库】02.wiki知识库SpringBoot后端的准备

news2024/11/14 21:58:19

  📝个人主页:哈__

期待您的关注 

目录

一、🔥今日目标

二、📂打开SpringBoot项目 

2.1 导入所需依赖

2.2修改application.yml配置文件

 2.3导入MybatisPlus逆向工程工具

 2.4创建一个公用的返回值

 2.5创建CopyUtil工具类

 2.6创建MybatisPlus的配置类

三、使用MybatisPlus逆向工程生成Ebook

四、Ebook查询功能的开发


一、🔥今日目标

上一篇文章已经带领大家把前后端的SpringBoot和Vue的架子搭了起来,今天呢我就要带大家开始上手开发我们的wiki知识库了,今天主要是带领大家把后端中一些基本的东西写出来,例如依赖、部分的工具类等,还会带大家实现电子书模块的查询功能,但是通过PostMan进行地测试的。

二、📂打开SpringBoot项目 

2.1 导入所需依赖

这里大家可能使用的不是阿里云服务器创建的SpringBoot项目,所以我把整个的POM文件复制了上来。依赖呢我现在只用到了这么多,如果后边我们缺了什么依赖的话还会在加的。

<?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>
    <groupId>com.my</groupId>
    <artifactId>hawiki</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>hawiki</name>
    <description>hawiki</description>
    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.7.16</spring-boot.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--aop切面-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

        <!--整合redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!--数据校验-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <!--websocket通信-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.3.1</version>
        </dependency>
        <!--    mybatisplus逆向工程    -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.3.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity</artifactId>
            <version>1.7</version>
        </dependency>
        <!--    数据库驱动    -->
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.70</version>
        </dependency>

        <!--    工具类    -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.18</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!--日志-->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <configuration>
                    <mainClass>com.my.hawiki.HawikiApplication</mainClass>
                    <skip>true</skip>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

2.2修改application.yml配置文件

在application.yml配置文件中,我们要配置数据库的连接信息,还要配置redis的连接信息

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/wiki?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT&allowPublicKeyRetrieval=true
    type: com.zaxxer.hikari.HikariDataSource
    username: root
    password: 你的数据库密码
logging:
  config:  classpath:logback-spring.xml
  level:
    com.my.hawiki.mapper: trace

 在上方的配置信息你看到了一个名字叫做logging的配置,这个是用来配置我们的日志输出的,日志信息的配置类使用的是一个xml文件。内容具体如下。首先你要在你的项目的根目录下创建一个名字叫做log的文件夹,这样以后的日志信息就会保存到这个文件夹下的两个文件中,一个叫做error.log,一个叫做trace.log。

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
 <!--   &lt;!&ndash; 修改一下路径-->
    <property name="PATH" value="./log"></property>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <!--            <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) %blue(%-50logger{50}:%-4line) %thread %green(%-18X{LOG_ID}) %msg%n</Pattern>-->
            <Pattern>%d{ss.SSS} %highlight(%-5level) %blue(%-30logger{30}:%-4line) %thread %green(%-18X{LOG_ID})
                %msg%n
            </Pattern>
        </encoder>
    </appender>

    <appender name="TRACE_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${PATH}/trace.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>${PATH}/trace.%d{yyyy-MM-dd}.%i.log</FileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <layout>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %-50logger{50}:%-4line %green(%-18X{LOG_ID}) %msg%n</pattern>
        </layout>
    </appender>

    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${PATH}/error.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>${PATH}/error.%d{yyyy-MM-dd}.%i.log</FileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <layout>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %-50logger{50}:%-4line %green(%-18X{LOG_ID}) %msg%n</pattern>
        </layout>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <root level="ERROR">
        <appender-ref ref="ERROR_FILE"/>
    </root>

    <root level="TRACE">
        <appender-ref ref="TRACE_FILE"/>
    </root>

    <root level="INFO">
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>

 2.3导入MybatisPlus逆向工程工具

我在项目中创建了一个名字为util的软件包。别的包大家可以先不用管,这些我之后都会说到的,这个util包呢主要就是保存我们的一些工具类。

MybatisPlus逆向工程的代码如下。我另一篇文章也有些过这个逆向工程【Spring】SpringBoot整合MybatisPlusGernerator,MybatisPlus逆向工程-CSDN博客

要注意的是你一定要修改其中的数据库连接信息。

public class MybatisGenerator {
    public static void main(String[] args) {
        AutoGenerator autoGenerator = new AutoGenerator();

        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setDbType(DbType.MYSQL);
        dataSourceConfig.setDriverName("com.mysql.cj.jdbc.Driver");
        dataSourceConfig.setUsername("root");
        dataSourceConfig.setPassword("你的数据库课密码");
        dataSourceConfig.setUrl("jdbc:mysql://localhost:3306/wiki?useUnicode=true&characterEncoding=UTF-8");
        autoGenerator.setDataSource(dataSourceConfig);

        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig.setOpen(false);
        globalConfig.setOutputDir(System.getProperty("user.dir")+"/src/main/java");
        globalConfig.setAuthor("CSDN__哈");
        globalConfig.setServiceName("%sService");
        autoGenerator.setGlobalConfig(globalConfig);

        PackageConfig packageConfig = new PackageConfig();
        packageConfig.setParent("com.my.hawiki");
        packageConfig.setEntity("domain");
        packageConfig.setMapper("mapper");
        //packageConfig.setController("controller");
        packageConfig.setService("service");
        packageConfig.setServiceImpl("service.impl");
        autoGenerator.setPackageInfo(packageConfig);

        StrategyConfig strategyConfig = new StrategyConfig();
        //是否需要lombok
        strategyConfig.setEntityLombokModel(true);
        //设置命名格式
        strategyConfig.setNaming(NamingStrategy.underline_to_camel);
        strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);
        //设置我们的表名  你到底要生成哪张表的框架
        strategyConfig.setInclude("ebook");
        autoGenerator.setStrategy(strategyConfig);
        autoGenerator.execute();
    }
}

 2.4创建一个公用的返回值

你可能不太理解这句话是什么意思,在SpringBoot项目当中,我们的每一个请求可能都会返回给前端数据,返回的数据一定是一个字符串。但这种方式并不适合我们的需求,比如我想返回的信息不仅仅是数据,还有一些其他的状态信息。例如当我们程序没出错的时候,我想在返回一句话,查询成功,如果出错了我就返回查询失败,这样返回多个参数信息,我们就不能使用字符串返回了。

我们需要的是这样的返回值。这是一个JSON类型的数据,也可以说是一个对象类型的数据,我们直接返回一个对象的话也可以达到这种效果,前提是导入了fastjson依赖。

创建的CommonResp如下。这个类在util包下创建的我。

@Data
@AllArgsConstructor
public class CommonResp<T> {

    /**
     * 业务上的成功或失败
     */
    private boolean success = true;

    /**
     * 返回信息
     */
    private String message;

    /**
     * 返回泛型数据,自定义类型
     */
    private T content;


    @Override
    public String toString() {
        final StringBuffer sb = new StringBuffer("ResponseDto{");
        sb.append("success=").append(success);
        sb.append(", message='").append(message).append('\'');
        sb.append(", content=").append(content);
        sb.append('}');
        return sb.toString();
    }
}

 2.5创建CopyUtil工具类

这个工具类的作用就是把一个类转换为另一个类的形式。也是在util包下。

import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
public class CopyUtil {
    /**
     * 单体复制
     */
    public static <T> T copy(Object source, Class<T> clazz) {
        if (source == null) {
            return null;
        }
        T obj = null;
        try {
            obj = clazz.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        BeanUtils.copyProperties(source, obj);
        return obj;
    }
    /**
     * 列表复制
     */
    public static <T> List<T> copyList(List source, Class<T> clazz) {
        List<T> target = new ArrayList<>();
        if (!CollectionUtils.isEmpty(source)) {
            for (Object c : source) {
                T obj = copy(c, clazz);
                target.add(obj);
            }
        }
        return target;
    }
}

 2.6创建MybatisPlus的配置类

这个类写到了我创建出来的config包下

@Configuration
public class MyBatisPlusConfig {

    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(false));
        return paginationInterceptor;
    }
}

 到了这一步,我们今天的目标就完成的快差不多了,后端的工具类我们今天用到的也差不多就是这些。接下来我就带大家实现电子书接口的查询功能。

 这是我们的ebook的数据库,接下来我就要写接口去查询这些内容了。

三、🌼使用MybatisPlus逆向工程生成Ebook

 打开我给大家的逆向工程的工具类,把你要生成的表的名称填写到对应的位置,上边我已经给了注释了,这里不再展示到底写在哪里了,把表名改成ebook,然后右键运行工具类,等一段时间后就会生成以下几个结构。

  • controller
  • service
    • impl
  • domain
  • mapper
    • xml

四、🤖Ebook查询功能的开发

我们需要的都已经写完了,接下来就去实现具体的功能,在这之前呢,我还需要写两个Param类,这两个类的作用就是接收前端给后端传输的一些参数。


PageParam

@Data
public class PageParam {
    @NotNull(message = "【页码】不能为空")
    private Integer page;
    @NotNull(message = "【每页条数】不能为空")
    @Max(value = 1000, message = "【每页条数】不能超过1000")
    private Integer size;

}

EbookQueryParam

@EqualsAndHashCode(callSuper = true)
@Data
public class EbookQueryParam extends PageParam {
    private Long id;
    private String name;
    private Long categoryId2;
}

除了这两个Param外还需要两个VO,VO的作用就是把我们的查询结果进行一个二次封装,然后在传给前端,比如说你开发登录功能,用户成功登陆后,你不能把用户的密码直接返回给前端,而是要把这个密码的字段删掉在返回给前端。


PageVo

@Data
public class PageVo<T> {
    private long total;
    private List<T> list;
}

EbookQueryVo 

@Data
public class EbookQueryVo {
    private Long id;
    private String name;
    private Long category1Id;
    private Long category2Id;
    private String description;
    private String cover;
    private Integer docCount;
    private Integer viewCount;
    private Integer voteCount;
}

打开我们的EbookController,写入以下代码。

@RestController
@RequestMapping("/ebook")
public class EbookController {
    @Resource
    EbookService ebookService;

    /**
     * 查询电子书 带有模糊查询
     * @param ebookQueryParam 带有数据校验
     * @return
     */
    @RequestMapping("/list")
    public CommonResp list(@Validated EbookQueryParam ebookQueryParam){
        PageVo<EbookQueryVo> list = ebookService.list(ebookQueryParam);
        return new CommonResp<>(true,"查找成功",list);
    }
}

EbookService代码如下。

public interface EbookService extends IService<Ebook> {

    PageVo<EbookQueryVo> list(EbookQueryParam ebookQueryParam);
}

 EbookMapper代码如下。

/**
 * <p>
 * 电子书 Mapper 接口
 * </p>
 *
 * @author CSDN__哈
 * @since 2024-05-26
 */
public interface EbookMapper extends BaseMapper<Ebook> {

}

 EbookServiceImpl代码如下。

package com.my.hawiki.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.my.hawiki.domain.Ebook;
import com.my.hawiki.mapper.EbookMapper;
import com.my.hawiki.param.EbookQueryParam;
import com.my.hawiki.service.EbookService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.my.hawiki.utils.CopyUtil;
import com.my.hawiki.vo.EbookQueryVo;
import com.my.hawiki.vo.PageVo;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 电子书 服务实现类
 * </p>
 *
 * @author CSDN__哈
 * @since 2024-05-26
 */
@Service
public class EbookServiceImpl extends ServiceImpl<EbookMapper, Ebook> implements EbookService {

    @Resource
    EbookMapper ebookMapper;
    @Override
    public PageVo<EbookQueryVo> list(EbookQueryParam ebookQueryParam) {
        // 这里创建了一个wrapper用于sql语句条件的拼接
        LambdaQueryWrapper<Ebook> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 拼接我们传过来的id 就相当于 where id = ??
        lambdaQueryWrapper.eq(ebookQueryParam.getId()!=null,Ebook::getId,ebookQueryParam.getId())
                // 相当于 where categoryid2 = ??
                .eq(ebookQueryParam.getCategoryId2()!=null,Ebook::getCategory2Id,ebookQueryParam.getCategoryId2())
                // 相当于 where name like %???%
                .like(StringUtils.isNotBlank(ebookQueryParam.getName()),Ebook::getName,ebookQueryParam.getName());
        // 这里使用MybataisPlus的page类,接收一下前端传来了页号和页的大小
        Page<Ebook> page = new Page<>(ebookQueryParam.getPage(),ebookQueryParam.getSize());
        // 这里我们将从数据库中查询的结果封装到一个Page类下
        Page<Ebook> resultPage = ebookMapper.selectPage(page, lambdaQueryWrapper);
        // 这里我创建了一个PageVo,用于返回给前端信息
        PageVo<EbookQueryVo> pageVo = new PageVo<>();
        List<EbookQueryVo> list = new ArrayList<>();
        // 从resultPage中获取从数据库中去除的结果,然后把数据插入到list中
        for (Ebook record : resultPage.getRecords()) {
            EbookQueryVo ebookQueryVo = CopyUtil.copy(record, EbookQueryVo.class);
            list.add(ebookQueryVo);
        }
        pageVo.setList(list);
        pageVo.setTotal(resultPage.getTotal());
        return pageVo;
    }
}

好了这里就写的差不多了,我们可以使用PostMan工具测试一下,这里大家需要自己安装一下。

启动我们的启动类,并且在启动类上加上一个mapper扫描。之后启动项目

@MapperScan("com.my.hawiki.mapper")

 可以看到我传入的page是1,size是5,查询出来的结果没问题。

但大家别忘了,我还有一个数据校验呢,page和size不能为空。那我们什么也不传入试一试。现在直接查不出来了。

我们看一下后台日志。这里给我们报了个错,说明我们的数据校验是有作用的,那我不想让他报错,这我该怎么做呢?我还想使用CommomResp返回一个信息,告诉前端错误是什么。

54.346 WARN  o.s.w.s.m.s.DefaultHandlerExceptionResolver:208  http-nio-8080-exec-7                   
                Resolved [org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 2 errors<EOL>Field error in object 'ebookQueryParam' on field 'page': rejected value [null]; codes [NotNull.ebookQueryParam.page,NotNull.page,NotNull.java.lang.Integer,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [ebookQueryParam.page,page]; arguments []; default message [page]]; default message [【页码】不能为空]<EOL>Field error in object 'ebookQueryParam' on field 'size': rejected value [null]; codes [NotNull.ebookQueryParam.size,NotNull.size,NotNull.java.lang.Integer,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [ebookQueryParam.size,size]; arguments []; default message [size]]; default message [【每页条数】不能为空]]

 这里我就要创建一个handler包,包下创建一个GlobalExceptionHandler。

GlobalExceptionHandler代码如下。这个类的作用就是捕获我们程序中的异常,然后作出处理。

import com.my.hawiki.utils.CommonResp;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class GlobalExceptionHandler {
    /**
     * 校验异常
     */
    @ExceptionHandler(BindException.class)
    public CommonResp<String> handleBindException(BindException e) {
        StringBuilder errorMessage = new StringBuilder();
        for (FieldError fieldError : e.getFieldErrors()) {
            // 这里可以自定义错误信息的格式
            errorMessage.append(fieldError.getField()).append(":").append(fieldError.getDefaultMessage()).append("; ");
        }
        // 去掉最后一个分号和空格
        if (errorMessage.length() > 0) {
            errorMessage.setLength(errorMessage.length() - 2);
        }
        return new CommonResp<>(false, errorMessage.toString(), null);
    }

}

接下来在重新启动项目试试看。

大功告成, 电子书查询接口的功能已经测试成功了。

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

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

相关文章

06.深入学习Java 线程

1 线程的状态/生命周期 Java 的 Thread 类对线程状态进行了枚举&#xff1a; public class Thread implements Runnable {public enum State {NEW,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING,TERMINATED;} } 初始(NEW)&#xff1a;新创建了一个线程对象&#xff0c;但还没有调用…

设计模式八股文

什么是设计模式&#xff1f; 设计模式是软件开发过程中经常遇到的问题的通用解决方案。类似于前人总结的经验&#xff0c;遇到相似问题的时候有个参考。 设计模式七大基本原则&#xff1f; 单一职责&#xff1a;一个类应该只作一件事情。将功能分为小的独立的单元。开放封闭…

【mysql】更新操作是如何执行的

现有一张表&#xff0c;建表语句如下&#xff1a; mysql> create table T(ID int primary key, c int);如果要将 ID2 这一行的a字段值加 1&#xff0c;SQL语句会这么写&#xff1a; mysql> update T set c c 1 where ID 2;上面这条sql执行时&#xff0c;分析器会通过词…

springboot发送短信验证码,结合redis 实现限制,验证码有效期2分钟,有效期内禁止再次发送,一天内发送超3次限制

springboot结合redis发送短信验证码,实现限制发送操作 前言(可忽略)实现思路正题效果图示例手机号不符合规则校验图成功发送验证码示例图redis中缓存随机数字验证码&#xff0c;2分钟后失效删除redis缓存图验证码有效期内 返回禁止重复发送图验证码24小时内发送达到3次&#xf…

精通C++ STL(二):string类的模拟实现

目录 string类各函数接口总览 默认成员函数 构造函数 拷贝构造函数 赋值运算符重载函数 析构函数 迭代器相关函数 begin和end 容量和大小相关函数 size和capacity reserve和resize empty 修改字符串相关函数 push_back append operator insert erase clear swap c_str 访…

spring boot 之 结合aop整合日志

AOP 该切面仅用于请求日志记录&#xff0c;若有其他需求&#xff0c;在此基础上扩展即可&#xff0c;不多逼逼&#xff0c;直接上代码。 引入切面依赖 <!-- 切面 --> <dependency><groupId>org.springframework.boot</groupId><artifactId>sp…

云主机选购指南:如何选择适合自己的云主机

一、认识移动云 移动云是中国移动提供的专业云服务品牌&#xff0c;基于移动云计算技术构建。它实现了云网一体化&#xff0c;确保客户享有安全可控的服务。通过充分利用移动云计算能力&#xff0c;打造了N31X资源布局&#xff0c;结合各省级数据中心&#xff0c;通过专线互联…

基于Vue的前端加载中页面动画——弹跳动画Loading组件的设计与实现

基于Vue的前端加载中页面动画——弹跳动画Loading组件的设计与实现 摘要 随着技术的飞速进步&#xff0c;前端开发的复杂性日益提升。传统的开发方式通常将整个系统构建为一个整体&#xff0c;导致即使是微小的改动或功能的增加也可能引起整体逻辑的变动。为了解决这个问题&a…

【蓝桥杯】国赛普及-

题目列表 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) P9420 [蓝桥杯 2023 国 B] 子 2023 / 双子数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) #include<bits/stdc.h> using llunsigned long long; #define int ll const int N2e510; int k0; std::string s; int…

嵌入式UI开发-lvgl+wsl2+vscode系列:1、资料收集以及Windows下WSL2模拟环境运行示例demo

文章目录 一、前言二、资料收集三、Windows下WSL2上编译运行lvgl的demo程序1、lvgl简介2、lvgl特性3、配置要求4、Windows下vscodewsl2模拟环境搭建4.1、安装vscodewsl24.2、下载获取项目&#xff1a;4.3、安装显卡驱动4.4、下载lvgl并编译运行示例demo 四、最后 一、前言 UI界…

Python数据分析-心脏病(随机森林预测分析)

本次案例分析用心脏病数据集来做随机森林模型预测 导入基本的数据分析包 import pandas as pd import numpy as np from sklearn.model_selection import train_test_split from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import accuracy_score…

云计算-关系型数据库(Relational Database)

关系数据库服务&#xff08;RDS&#xff09;&#xff08;Relational Database Service (RDS)&#xff09; Amazon RDS 可用于在云中设置和运行关系数据库。它支持多种数据库实例类型以及多个数据库引擎&#xff0c;如 Amazon Aurora、PostgreSQL、MySQL、MariaDB、Oracle 数据库…

基于Vue的应届毕业生财务管理系统-计算机毕业设计源码82886

摘 要 随着互联网大趋势的到来&#xff0c;社会的方方面面&#xff0c;各行各业都在考虑利用互联网作为媒介将自己的信息更及时有效地推广出去&#xff0c;而其中最好的方式就是建立网络管理系统&#xff0c;并对其进行信息管理。由于现在网络的发达&#xff0c;应届毕业生财务…

c# sqlite使用

安装包 使用 const string strconn "Data Sourcedata.db"; using (SQLiteConnection conn new SQLiteConnection(strconn)) {conn.Open();var cmd conn.CreateCommand();//创建表cmd.CommandText "create table t1(id int,name varchar(10))";var obj…

二百三十八、Hive——Hive中为每条数据创建唯一ID

一、目的 由于Kafka的JSON中缺少唯一的ID标识字段&#xff0c;因此发现后面的需求中DWD层表需要有一个唯一ID字段&#xff0c;这样才能与数据质量表更好的关联 二、Hive版本 尚硅谷的3.1.2版本 三、Hive创建唯一ID方法 网上的创建唯一ID方法有很多&#xff0c;这里展示一些…

子网划分,交换机原理与配置

子网划分 IP地址 IPv4由32位二进制数组成&#xff0c;一般用点分十进制来表示 IPv4是由32位二进制数组成&#xff0c;分成四组,第组八位。例如:11000000.10101000.00000000.00000010 为了便于配置通常表示成点分十进制形式例如:192.168.0.2 255.255.255.0 IPv6由128位组成&…

HDR视频相关标准-HDR vivid(二)

上文介绍了HDRvivid的一些技术。今天从全局角度来看看HDR视频的处理流程&#xff0c;HDR视频系统&#xff0c;即建立一个比SDR视频更大的色彩/亮度坐标体系&#xff0c;并改变系统的传输函数&#xff0c;以再现更大的色域(WCG)和更高的亮度动态范围。 菁彩 HDR技术的专业术语 …

充电宝哪个牌子好用?充电宝品牌怎么选?充电宝最好的牌子排名

现在市面上的充电宝品牌琳琅满目&#xff0c;但并不是所有的充电宝都安全可靠。据央视的一个报道&#xff0c;市面上有35%充电宝质量是不过关的!充电宝买不对就非常容易出现爆炸的一个情况&#xff0c;所以大家对选充电宝不仅能保障设备的安全。那么&#xff0c;充电宝哪个牌子…

TypeScript学习日志-第三十二天(infer关键字)

infer关键字 一、作用与使用 infer 的作用就是推导泛型参数&#xff0c;infer 声明只能出现在 extends 子语句中&#xff0c;使用如下&#xff1a; 可以看出 已经推导出类型是 User 了 二、协变 infer 的 协变会返回联合类型&#xff0c;如图&#xff1a; 三、逆变 infer…

FusionCharts 隐藏试用图标

1、找到fusioncharts.js文件 2、搜索“raphael-group-” 3、找到此处进行替换黄线部分 将&#xff1a;"a.setAttribute("class","raphael-group-"t)" 替换成"(a.setAttribute("class","raphael-group-"t),a.setAttr…