【wiki知识库】02.wiki知识库SpringBoot后端的准备
📝个人主页:哈__
期待您的关注
目录
一、🔥今日目标
二、📂打开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.Driverurl: jdbc:mysql://localhost:3306/wiki?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT&allowPublicKeyRetrieval=truetype: com.zaxxer.hikari.HikariDataSourceusername: rootpassword: 你的数据库密码 logging:config: classpath:logback-spring.xmllevel:com.my.hawiki.mapper: trace
在上方的配置信息你看到了一个名字叫做logging的配置,这个是用来配置我们的日志输出的,日志信息的配置类使用的是一个xml文件。内容具体如下。首先你要在你的项目的根目录下创建一个名字叫做log的文件夹,这样以后的日志信息就会保存到这个文件夹下的两个文件中,一个叫做error.log,一个叫做trace.log。
<?xml version="1.0" encoding="UTF-8"?> <configuration><!-- <!– 修改一下路径--><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();//是否需要lombokstrategyConfig.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;@Overridepublic 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 {@Beanpublic 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 {@ResourceEbookService 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 {@ResourceEbookMapper ebookMapper;@Overridepublic 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);}}
接下来在重新启动项目试试看。
大功告成, 电子书查询接口的功能已经测试成功了。
相关文章:

【wiki知识库】02.wiki知识库SpringBoot后端的准备
📝个人主页:哈__ 期待您的关注 目录 一、🔥今日目标 二、📂打开SpringBoot项目 2.1 导入所需依赖 2.2修改application.yml配置文件 2.3导入MybatisPlus逆向工程工具 2.4创建一个公用的返回值 2.5创建CopyUtil工具类 2.6创建…...
python tuple(元组)
python list(列表)、创建、访问、内置index、判断in、not in、添加元素、insert、append、extend、列表排序、颠倒顺序、删除元素、remove、pop、clear-CSDN博客 目录 tuple: 元组的主要特点包括: tuple的创建 单个元组需要注…...
opencv调用摄像头保存视频
opencv调用摄像头保存视频 文章目录 opencv调用摄像头保存视频保存视频(采用默认分辨率640 x 480)保存视频(指定分辨率,例1280720) 保存视频(采用默认分辨率640 x 480) import cv2 import time # 定义视频捕捉对象 cap cv2.Vide…...

STM32定时器四大功能之定时器编码接口
1什么是编码器接口? 编码器接口接受编码器的正交信号,根据编码器产生的正交信号脉冲控制CNT的自增和自减,从而指示编码器的旋转方向和旋转速度。 每个高级定时器和通用定时器都有一个编码器接口,同时正交编码器产生的正交信号分…...

全国各城市间驾车耗时和距离矩阵数据集(更新至2022年)
数据简介:城市之间距离越远,耗时越长。经济发达地区的交通状况较好。各城市之间的驾车耗时和距离存在差异。有些城市之间的交通非常便捷,而有些城市之间的交通则较为不便。这表明中国的交通网络发展尚不平衡,需进一步优化。特别是…...

推荐二轮电动车仪表盘蓝牙主芯片方案-HS6621CGC
随着国内二轮电动车的火热开启,电动车的智能化程度越来越高;电动车的智能操控需求也越来越高,现在介绍蓝牙控制面板的一些功能;例如:定位(GNSS),设防,实时上报数据&#…...

『香橙派』基于Orange Pi AIpro打造高效个人云存储解决方案
读完这篇文章里你能收获到 了解Orange Pi AIpro硬件优势,为构建高效云存储基础设施的理想平台。学会使用Orange Pi AIpro硬件平台,搭载Ubuntu Server系统,打造云存储环境。掌握利用Kodbox软件,享受文件管理、多格式预览及编辑的全…...
Sylvester矩阵、子结式、辗转相除法的三者关系(第二部分)
【三者的关系】 首先,辗转相除法可以通过Sylvester矩阵进行,过程如下(以 m 8 、 l 7 m 8、l 7 m8、l7为例子)。 首先调整矩阵中 a a a系数到最后面几行,如下所示: S ( a 8 a 7 a 6 a 5 a 4 a 3 a 2 …...

PyTorch的数据处理
💥今天看一下 PyTorch数据通常的处理方法~ 一般我们会将dataset用来封装自己的数据集,dataloader用于读取数据 Dataset格式说明 💬dataset定义了这个数据集的总长度,以及会返回哪些参数,模板: from tor…...

第14章-蓝牙遥控小车 手把手做蓝牙APP遥控小车 蓝牙串口通讯讲解
本文讲解手机蓝牙如何遥控小车,如何编写串口通信指令 第14章-手机遥控功能 我们要实现蓝牙遥控功能,蓝牙遥控功能要使用:1.单片机的串口、2.蓝牙通信模块 所以我们先调试好:单片机的串口->蓝牙模块->接到一起联调 14.1-电脑控制小车 完成功能…...
【补充1】字节对齐
文章目录 1.字节对齐的基本概念2.字节对齐规则3.实践出真知(加大难度)4 位域 1.字节对齐的基本概念 (1)现代计算机中内存空间都是按照byte划分的, 从理论上讲似乎对任何类型的变量的访问可以从任何地址开始࿰…...
Java数据库连接(JDBC)
一、引言 在Java应用程序中,经常需要与数据库进行交互以存储、检索和处理数据。Java数据库连接(JDBC)是Java平台中用于执行这一任务的标准API。JDBC允许Java程序连接到关系数据库,并使用SQL语句来执行查询和更新操作。本教程将详…...
记录一次cas单点登录的集成
主要思路:浏览器访问CAS服务器登录,拿到凭证给后端,后端用此凭证到CAS服务器验证登录并拿到用户信息,之后基于该凭证维持用户的登录状态。 主要流程: 1.浏览器访问后端需认证登录地址(不带ticket…...

【吊打面试官系列】Java高并发篇 - 什么是乐观锁和悲观锁?
大家好,我是锋哥。今天分享关于 【什么是乐观锁和悲观锁?】面试题,希望对大家有帮助; 什么是乐观锁和悲观锁? 1、乐观锁: 就像它的名字一样,对于并发间操作产生的线程安全问题持乐观状态, 乐观锁认为竞争…...
机器学习之词袋模型
目录 1 词袋模型基本概念 2 词袋模型的表示方法 2.1 三大方法 1 独热表示法(One-Hot) 2 词频表示法(Term Frequency, TF) 3 词频-逆文档频率表示法(TF-IDF) 2.2 例子 1 词袋模型基本概念 词袋模型&a…...

【C++/STL】vector(常见接口、模拟实现、迭代器失效)
🌈个人主页:秦jh_-CSDN博客🔥 系列专栏: https://blog.csdn.net/qinjh_/category_12575764.html?spm1001.2014.3001.5482 目录 简单使用 常见接口 find insert vector模板 模拟实现 尾插 构造 迭代器失效 使用memcpy拷贝问…...
Spring Boot Web 开发:MyBatis、数据库连接池、环境配置与 Lombok 全面解析
推荐一个AI网站,免费使用豆包AI模型,快去白嫖👉海鲸AI 1.0 MyBatis 概述 MyBatis 是一个优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 可以帮助我们将数据库操作抽象出来,使得我们的代码更加简洁…...

【UE5.1 多线程 异步】“Async Blueprints Extension”插件使用记录
目录 一、异步生成Actor示例 二、异步计算示例 参考视频 首先需要在商城中下载“Async Blueprints Extension”插件 一、异步生成Actor示例 2. 创建一个线程类,这里要指定父类为“LongAsyncTask”、“InfiniteAsyncTask”、“ShortAsyncTask”中的一个 在线程类…...

【已解决】在jupyter里运行torch.cuda.is_available(),显示True,在pycharm中运行却显示false。
文章目录 问题概述1、在Jupyter中GPU运行true2、在pycharm中GPU运行false3、个人解决方案仅供参考 问题概述 在jupyter里运行torch.cuda.is_available(),显示True,在pycharm中运行却显示false。原因在于jupyter 运行环境和pycharm 运行环境不同…...
Flutter 中的 Scrollbar 小部件:全面指南
Flutter 中的 Scrollbar 小部件:全面指南 在Flutter中,滚动条(Scrollbar)是一种常见的UI组件,用于提供对滚动内容的快速访问和控制。Scrollbar 小部件可以附加到任何可滚动的widget上,如ListView、GridVie…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...

dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...
GitHub 趋势日报 (2025年06月06日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...

Visual Studio Code 扩展
Visual Studio Code 扩展 change-case 大小写转换EmmyLua for VSCode 调试插件Bookmarks 书签 change-case 大小写转换 https://marketplace.visualstudio.com/items?itemNamewmaurer.change-case 选中单词后,命令 changeCase.commands 可预览转换效果 EmmyLua…...

JDK 17 序列化是怎么回事
如何序列化?其实很简单,就是根据每个类型,用工厂类调用。逐个完成。 没什么漂亮的代码,只有有效、稳定的代码。 代码中调用toJson toJson 代码 mapper.writeValueAsString ObjectMapper DefaultSerializerProvider 一堆实…...

链式法则中 复合函数的推导路径 多变量“信息传递路径”
非常好,我们将之前关于偏导数链式法则中不能“约掉”偏导符号的问题,统一使用 二重复合函数: z f ( u ( x , y ) , v ( x , y ) ) \boxed{z f(u(x,y),\ v(x,y))} zf(u(x,y), v(x,y)) 来全面说明。我们会展示其全微分形式(偏导…...

leetcode73-矩阵置零
leetcode 73 思路 记录 0 元素的位置:遍历整个矩阵,找出所有值为 0 的元素,并将它们的坐标记录在数组zeroPosition中置零操作:遍历记录的所有 0 元素位置,将每个位置对应的行和列的所有元素置为 0 具体步骤 初始化…...

如何把工业通信协议转换成http websocket
1.现状 工业通信协议多数工作在边缘设备上,比如:PLC、IOT盒子等。上层业务系统需要根据不同的工业协议做对应开发,当设备上用的是modbus从站时,采集设备数据需要开发modbus主站;当设备上用的是西门子PN协议时…...