SpringBoot入门实战(项目搭建、配置、功能接口实现等一篇通关)
🤟致敬读者
- 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉
📘博主相关
- 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息
文章目录
- SpringBoot入门实战(项目搭建、配置、功能接口实现等一篇通关)
- 1. 环境准备
- 2. 项目创建和初始化
- 2.1 创建项目
- 2.2 项目依赖配置
- 2.3 项目包结构预设
- 2.4 项目启动类创建
- 2.5 启动项目
- 3. 配置文件(application.yml)
- 4. 数据库MySQL集成
- 4.1 依赖引入
- 4.2 参数配置
- 5. 数据库框架MyBatis集成(自动生成代码配置)
- 5.1 依赖引入
- 5.2 代码生成配置(generatorConfig.xml)
- 5.3 数据库配置文件jdbc.properties
- 5.4 建表
- 5.5 生成代码
- 5.6 添加注解
- 5.7 调用测试
- 6. 数据库Redis集成
- 6.1 依赖引入(pom.xml)
- 6.2 参数配置(application.yml)
- 6.3 配置类(RedisConfig.java)
- 6.4 工具类(RedisUtils.java)
- 6.5 接口代码
- 6.6 调用测试
- 7. 项目接口
- 7.1 用户管理接口
- 7.1.1 UserInfoController.java
- 7.1.2 接口测试
- 7.2 登录接口
- 7.2.1 UserLogin.java
- 7.2.2 接口测试
- 7.3 商品管理接口
- 7.3.1 建表
- 7.3.2 接口创建(GoodsInfoController.java)
- 7.3.3 接口测试
- 7.4 订单管理接口
- 7.4.1 建表
- 7.4.2 接口创建(OrderInfoController.java)
- 7.4.3 接口测试
📃文章前言
- 🔷文章均为学习工作中整理的笔记。
- 🔶如有错误请指正,共同学习进步。
SpringBoot入门实战(项目搭建、配置、功能接口实现等一篇通关)
SpringBoot入门实战系列篇专栏
SpringBoot入门实战(第一篇:环境准备和项目初始化)
SpringBoot入门实战(第二篇:MySQL集成配置)
SpringBoot入门实战(第三篇:MyBatis集成配置,自动生成代码配置)
SpringBoot入门实战(第四篇:Redis集成配置)
SpringBoot入门实战(第五篇:项目接口-用户管理)
SpringBoot入门实战(第六篇:项目接口-登录)
SpringBoot入门实战(第七篇:项目接口-商品管理)
SpringBoot入门实战(第八篇:项目接口-订单管理)完结篇
SpringBoot入门实战(项目搭建、配置、功能接口实现等一篇通关)
1. 环境准备
- Java环境配置:Java JDK 下载安装和配置环境变量
- Maven安装和配置:Maven安装配置教程(精简版)
- 开发工具-IDEA社区版:IntelliJ IDEA Community 下载安装和使用指南
- IDEA配置maven仓库:IDEA配置MAVEN本地仓库
2. 项目创建和初始化
使用IDEA开发工具创建spring boot项目
2.1 创建项目
打开idea社区版
左上角菜单栏打开,选择File
—New
—Project...
创建界面如下(默认打开的界面)
按照顺序定义或者修改配置参数
1
新建项目类型 默认Java2
项目名称(Name) 默认untitled 自定义为sb_demo3
-4
项目位置(Location) 自定义项目位置,下方一行提示信息中会有创建后的项目路径5
构建系统(Build system) 默认Maven,如果不是,则选择Maven6
Java JDK选择(JDK) 选择自己安装的JDK版本,这里选择的是1.8版本7
新增示例代码(Add sample code) 默认不勾选,这里无需示例代码8
项目组织架构(Advanced Settings)
GroupId默认org.example这里自定义为com.xh
ArtifactId默认项目名称,这里无需修改9
最后选择Create创建项目
参数配置后如下
创建后的项目界面如下
2.2 项目依赖配置
配置spring boot相关依赖,这里直接配置三个依赖,分别对应spring boot的依赖、lombok依赖、fastjson依赖。
注1
:lombok依赖通过注解方式简化样板代码的编写,可自动生成getter、setter、构造函数、toString等方法
注2
:fastjson依赖是为了实现Java对象和json格式字符转之间的相互转换
在pom.xml中配置如下代码
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.7.18</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.30</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.83</version></dependency>
配置后的完整代码
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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.xh</groupId><artifactId>sb_demo</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.7.18</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.30</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.83</version></dependency></dependencies></project>
配置依赖后不要忘了右上角maven刷新按钮点一下
如图
2.3 项目包结构预设
提前创建项目的包结构,这里简单创建几个常用包,后续有需要可继续新建包
打开src/main/java包,在Java包下创建如下包
com.xh.user
com.xh.product
com.xh.analystic
创建后如下
2.4 项目启动类创建
在com.xh包下创建启动类
SbApplication.java
package com.xh;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;/*** @func: 项目启动类* @author: LiBai* @version: v1.0* @createTime: 2025/4/10 10:45*/
@SpringBootApplication
public class SbApplication {public static void main(String[] args) {SpringApplication.run(SbApplication.class, args);}}
2.5 启动项目
鼠标选中启动类文件右键选择Run’SbApplication()'执行项目
如下,表示项目正常启动,一切配位配置的参数都为默认,如默认端口8080
3. 配置文件(application.yml)
在src/main/resources
包下创建文件application.yml
(右键New
—File
,然后填写文件名,带后缀)
在application.yml中配置端口号如下
server:port: 8088
配置后重启服务,右上角有启动类名和绿色启动按钮,现在项目正在运行,直接点击可重启
服务端口即变为8088
如下
4. 数据库MySQL集成
4.1 依赖引入
pom.xml中引入所需依赖
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.31</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId><version>2.7.18</version></dependency>
引入后重新加载依赖
完整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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.xh</groupId><artifactId>sb_demo</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.7.18</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.30</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.83</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.31</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId><version>2.7.18</version></dependency></dependencies></project>
4.2 参数配置
在配置文件application.yml中配置MySQL连接参数
localhost
是本机地址,也可换成远程IP地址
3306
是端口号,根据自己mysql服务配置
sb_demo
是数据库名称,根据自己数据名称配置
spring:datasource:url: jdbc:mysql://localhost:3306/sb_demo?useUnicode=true&characterEncoding=utf-8&useSSL=falsedriver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: 1234
完整application.yml
server:port: 8088spring:datasource:url: jdbc:mysql://localhost:3306/sb_demo?useUnicode=true&characterEncoding=utf-8&useSSL=falsedriver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: 1234
5. 数据库框架MyBatis集成(自动生成代码配置)
5.1 依赖引入
引入相关依赖和插件
依赖部分
<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.2.2</version></dependency>
插件部分
<build><finalName>app</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId>
<!-- <version>2.3.4.RELEASE</version>--></plugin><!--添加mybatis generator maven插件--><plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><version>1.3.7</version><configuration><!--generatorConfig.xml位置--><configurationFile>src/main/resources/generatorConfig.xml</configurationFile><verbose>true</verbose><!-- 如果本来就有mapper、dao文件了就覆盖--><overwrite>true</overwrite></configuration><executions><execution><id>Generate MyBatis Artifacts</id><phase>deploy</phase><goals><goal>generate</goal></goals></execution></executions><!--此处必须添加mysql驱动包--><dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope><version>8.0.31</version></dependency></dependencies></plugin></plugins><resources><resource><directory>src/main/java</directory><includes><include>**/*.csv</include><include>**/*.yml</include><include>**/*.xml</include><include>**/*.properties</include><include>**/*.json</include><include>**/*.js</include></includes><filtering>false</filtering></resource><resource><directory>src/main/resources</directory><includes><include>**/*.csv</include><include>**/*.yml</include><include>**/*.xml</include><include>**/*.properties</include><include>**/*.json</include><include>**/*.js</include></includes><filtering>false</filtering></resource></resources></build>
引入后完整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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.xh</groupId><artifactId>sb_demo</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.7.18</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.30</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.83</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.31</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId><version>2.7.18</version></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.2.2</version>
<!-- <version>1.3.2</version>--></dependency></dependencies><build><finalName>app</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId>
<!-- <version>2.3.4.RELEASE</version>--></plugin><!--添加mybatis generator maven插件--><plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><version>1.3.7</version><configuration><!--generatorConfig.xml位置--><configurationFile>src/main/resources/generatorConfig.xml</configurationFile><verbose>true</verbose><!-- 如果本来就有mapper、dao文件了就覆盖--><overwrite>true</overwrite></configuration><executions><execution><id>Generate MyBatis Artifacts</id><phase>deploy</phase><goals><goal>generate</goal></goals></execution></executions><!--此处必须添加mysql驱动包--><dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope><version>8.0.31</version></dependency></dependencies></plugin></plugins><resources><resource><directory>src/main/java</directory><includes><include>**/*.csv</include><include>**/*.yml</include><include>**/*.xml</include><include>**/*.properties</include><include>**/*.json</include><include>**/*.js</include></includes><filtering>false</filtering></resource><resource><directory>src/main/resources</directory><includes><include>**/*.csv</include><include>**/*.yml</include><include>**/*.xml</include><include>**/*.properties</include><include>**/*.json</include><include>**/*.js</include></includes><filtering>false</filtering></resource></resources></build></project>
5.2 代码生成配置(generatorConfig.xml)
自动生成代码的配置文件在resources包下创建generatorConfig.xml
内容如下
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfigurationPUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"><generatorConfiguration><properties resource="jdbc.properties"/><context id="sqlserverTables" targetRuntime="MyBatis3"><!-- 生成的pojo,将implements Serializable--><plugin type="org.mybatis.generator.plugins.SerializablePlugin"></plugin><!--替换默认生成的dao-Example--><plugin type="org.mybatis.generator.plugins.RenameExampleClassPlugin"><property name="searchString" value="Example$" /><property name="replaceString" value="Impl" /></plugin><commentGenerator><!-- 是否去除自动生成的注释 true:是 : false:否 --><property name="suppressAllComments" value="true" /></commentGenerator><!-- 数据库链接URL、用户名、密码 --><jdbcConnection driverClass="${spring.datasource.driverClassName}"connectionURL="${spring.datasource.url}"userId="${spring.datasource.username}"password="${spring.datasource.password}"></jdbcConnection><!--默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer--><!--true,把JDBC DECIMAL 和 NUMERIC 类型解析为java.math.BigDecimal--><javaTypeResolver><property name="forceBigDecimals" value="false" /></javaTypeResolver><!--生成model模型,对应的包路径,以及文件存放路径(targetProject),targetProject可以指定具体的路径,如./src/main/java,--><!--也可以使用“MAVEN”来自动生成,这样生成的代码会在target/generatord-source目录下--><!--<javaModelGenerator targetPackage="com.joey.mybaties.test.pojo" targetProject="MAVEN">--><!--<javaModelGenerator targetPackage="${daopackage}" targetProject="./src/main/java">--><javaModelGenerator targetPackage="${daopackage}" targetProject="./src/main/java"><property name="enableSubPackages" value="true"/><!-- 从数据库返回的值被清理前后的空格 --><property name="trimStrings" value="true" /></javaModelGenerator><!--对应的mapper.xml文件 --><sqlMapGenerator targetPackage="${daopackage}" targetProject="./src/main/java"><property name="enableSubPackages" value="true"/></sqlMapGenerator><!-- 对应的Mapper接口类文件 --><javaClientGenerator type="XMLMAPPER" targetPackage="${daopackage}" targetProject="./src/main/java"><property name="enableSubPackages" value="true"/></javaClientGenerator><table tableName="${tableName}"enableCountByExample="false"enableUpdateByExample="true"enableDeleteByExample="true"enableSelectByExample="true"selectByExampleQueryId="false"><property name="useActualColumnNames" value="false"/></table></context>
</generatorConfiguration>
5.3 数据库配置文件jdbc.properties
resources包下创建文件jdbc.properties
spring.datasource.driverLocation=mysql-connector-java-8.0.21.jar
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/sb_demo?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=1234daopackage = com.user.dao
tableName = tb_user
其中daopackage是生成代码后存储的位置
tableName是表名
5.4 建表
在MySQL表中新建用户表tb_user
建表语句
CREATE TABLE tb_user(id INT AUTO_INCREMENT PRIMARY KEY,username VARCHAR(255) NOT NULL COMMENT "密码",pass_word VARCHAR(255) NOT NULL COMMENT "账号",gender VARCHAR(255) NOT NULL COMMENT "性别",address VARCHAR(255) NOT NULL COMMENT "地址",p_number VARCHAR(255) NOT NULL COMMENT "手机号",vip_class INT DEFAULT 0 COMMENT "vip等级,共4级,0-1-2-3"
);
执行后建表完成
5.5 生成代码
修改jdbc.properties中的daopackage和tableName,然后到IDEA工具找到Maven工具窗口,一般在右侧
打开sb_demo—Plugins—mybatis-generator—mybatis-generator:generate,如下(双击即可)
生成成功的控制台界面
或者在终端窗口(Terminal)使用maven命令
mvn mybatis-generator:generate
生成的代码文件如下
5.6 添加注解
分别对TbUser.java、TbUserImpl.java、TbUserMapper.interface添加注解
TbUser.java添加@Component注解
TbUserImpl.java添加@Service注解
TbUserMapper.interface添加@Mapper注解
完成以上即可进行数据库表相关操作的代码编写
5.7 调用测试
代码编写:
编写接口进行数据添加
在user包下创建controller包,并在controller包下新建Java代码
代码如下
package com.user.controller;import com.alibaba.fastjson.JSONObject;
import com.user.dao.TbUser;
import com.user.dao.TbUserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** @func:* @author: LiBai* @version: v1.0* @createTime: 2025/4/16 15:36*/
@RestController
@RequestMapping(value = "/xh/v1/user")
public class UserAddTest {@AutowiredTbUserMapper tbUserMapper;@PostMapping(value = "/addUser")public JSONObject addUser(@RequestBody JSONObject requestBody){System.out.println("add user info ----> ");TbUser tbUser = new TbUser();tbUser.setUsername(requestBody.getString("username"));tbUser.setPassWord(requestBody.getString("passWord"));tbUser.setGender(requestBody.getString("gender"));tbUser.setAddress(requestBody.getString("address"));tbUser.setpNumber(requestBody.getString("pNumber"));tbUser.setVipClass(requestBody.getInteger("vipClass"));tbUserMapper.insert(tbUser);return requestBody;}}
接口调用:
postman调用接口
URL地址
127.0.0.1:8088/xh/v1/user/addUser
请求体内容
{"username":"libai","passWord":"352894","gender":"男","address":"上海市浦东新区","pNumber":"13122993366","vipClass":2
}
如下(postman中截图)
数据查看:
在mysql表中查看数据是否成功添加
mysql可用,生成代码可用
6. 数据库Redis集成
6.1 依赖引入(pom.xml)
所需依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><version>2.7.18</version></dependency>
6.2 参数配置(application.yml)
配置文件中配置redis相关参数
application.yml
spring:redis:host: 127.0.0.1port: 6379password: xh.1234database: 0jedis:pool:max-idle: 8min-idle: 1max-active: 8max-wait: -1timeout: 20000
6.3 配置类(RedisConfig.java)
在com.xh.common.config包下创建redis配置类RedisConfig.java
package com.xh.common.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;/*** @func:* @author: LiBai* @version: v1.0* @createTime: 2025/4/17 9:47*/
@Configuration
public class RedisConfig {@Bean@SuppressWarnings("all")public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory connectionFactory){RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(connectionFactory);StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();template.setKeySerializer(stringRedisSerializer);template.setValueSerializer(stringRedisSerializer);GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();template.setHashKeySerializer(stringRedisSerializer);template.setHashValueSerializer(genericJackson2JsonRedisSerializer);template.afterPropertiesSet();return template;}
}
6.4 工具类(RedisUtils.java)
在com.xh.common.utils包下创建Redis工具类RedisUtils.java
package com.xh.common.utils;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import javax.annotation.PostConstruct;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;/*** @func:* @author: LiBai* @version: v1.0* @createTime: 2025/4/17 9:46*/
@Component
public class RedisUtils {@AutowiredRedisTemplate<String, Object> redisTemplate;public static RedisTemplate<String, Object> _redisTemplate;@PostConstructpublic void init(){_redisTemplate = redisTemplate;}// =============================common============================/** 设置失效时间 */public static void setexpire(String key, long time) {_redisTemplate.expire(key, time, TimeUnit.SECONDS);}/** 获取过期时间 */public static long getexpire(String key) {return _redisTemplate.getExpire(key, TimeUnit.SECONDS);}/** 判断key是否存在 */public static boolean haskey(String key) {return _redisTemplate.hasKey(key);}/** 查询key */public static Set<String> search(String keyword){return _redisTemplate.keys(keyword);}/** 删除key */@SuppressWarnings("unchecked")public static void delete(String... key) {if (key.length == 1) {_redisTemplate.delete(key[0]);} else {_redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));}}// =============================String============================/** 获取普通类型缓存 */public static Object get(String key) {return key == null ? null : _redisTemplate.opsForValue().get(key);}/** 设置普通类型缓存 */public static void set(String key, Object value) {_redisTemplate.opsForValue().set(key, value);}/** 设置普通类型缓存 带失效时间*/public static void set(String key, Object value, long time) {_redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);}// =============================Hash==============================/** 从hashmap中返回键位item的值 */public static Object hget(String key, String item) {return _redisTemplate.opsForHash().get(key, item);}/** 向hashmap写入一个键值对 */public static void hset(String key, String item, Object value) {_redisTemplate.opsForHash().put(key, item, value);}/** 从hashmap中删除名为item的key */public static void hremove(String key, Object... item) {_redisTemplate.opsForHash().delete(key, item);}/** 判断hashmap里面是否包含item的key */public static boolean hhasitem(String key, String item) {return _redisTemplate.opsForHash().hasKey(key, item);}/** 一次性从hashmap中返回所有的键值对 */public static Map<Object, Object> hmget(String key) {return _redisTemplate.opsForHash().entries(key);}/** 向hashmap写入多个个键值对 */public static void hmset(String key, Map<String, Object> map) {_redisTemplate.opsForHash().putAll(key, map);}// =============================List==============================/** 返回一个list的长度 */public static long lgetsize(String key) {return _redisTemplate.opsForList().size(key);}/** 返回一个list 给定开始index和结束index */public static List<Object> lget(String key, long start, long end) {return _redisTemplate.opsForList().range(key, start, end);}/*** jwh-20241022-获取列表第一个元素并从redis中移除* @param key redis数据的键* @return 返回移除的数据*/public static Object lGetPop(String key) {return _redisTemplate.opsForList().leftPop(key);}/** 通过索引index获取list中的值 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素 */public static Object lgetindex(String key, long index) {return _redisTemplate.opsForList().index(key, index);}/** 将list放入缓存 */public static void lset(String key, Object value) {_redisTemplate.opsForList().rightPush(key, value);}/** 将list放入缓存 */public static void lset(String key, List<Object> value) {_redisTemplate.opsForList().rightPushAll(key, value);}/** 根据索引修改list中的某条数据 */public static void lupdateindex(String key, long index, Object value) {_redisTemplate.opsForList().set(key, index, value);}/** 移除N个值为value */public static long lRemove(String key, long count, Object value) {return _redisTemplate.opsForList().remove(key, count, value);}// =============================Set===============================/** 获取set的长度 */public static long sgetsetsize(String key) {return _redisTemplate.opsForSet().size(key);}/** 获取set中的全部元素 */public static Set<Object> sget(String key) {return _redisTemplate.opsForSet().members(key);}/** 判断set中是否包含value */public static boolean shaskey(String key, Object value) {return _redisTemplate.opsForSet().isMember(key, value);}/** set中添加对象*/public static long sset(String key, Object... values) {return _redisTemplate.opsForSet().add(key, values);}/** 删除set中的values元素*/public static long sremove(String key, Object... values) {return _redisTemplate.opsForSet().remove(key, values);}}
6.5 接口代码
创建接口,新增数据到redis中,以存储字符串类型数据为例
com.xh.user.controller包下创建RedisTest.java
package com.xh.user.controller;import com.alibaba.fastjson.JSONObject;
import com.xh.common.utils.RedisUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** @func:* @author: LiBai* @version: v1.0* @createTime: 2025/4/17 9:59*/
@RestController
@RequestMapping(value = "/xh/v1/redis")
public class RedisTest {@RequestMapping(value = "/strAdd")public JSONObject strAdd(){RedisUtils.set("RedisTest001","this is a test for redis util");System.out.println("this is a test for redis util");return null;}
}
6.6 调用测试
请求地址
127.0.0.1:8088/xh/v1/redis/strAdd
请求参数为空
调用后并查看redis客户端
可以看到数据已存入,其余方法类似
以上就是spring boot集成redis内容
7. 项目接口
完成以上配置集成,可进行项目接口编写
7.1 用户管理接口
在com.xh.user.controller包下创建用户管理类UserInfoController.java
7.1.1 UserInfoController.java
UserInfoController.java代码
package com.xh.user.controller;import com.alibaba.fastjson.JSONObject;
import com.xh.user.dao.TbUser;
import com.xh.user.dao.TbUserImpl;
import com.xh.user.dao.TbUserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.List;/*** @func:* @author: LiBai* @version: v1.0* @createTime: 2025/4/17 10:53*/
@CrossOrigin
@RestController
@RequestMapping(value = "/xh/v1/user")
public class UserInfoController {@AutowiredTbUserMapper tbUserMapper;@RequestMapping(value = "/addUserInfo")public JSONObject addUserInfo(@RequestBody JSONObject requestBody){TbUser tbUser = JSONObject.parseObject(requestBody.toJSONString(), TbUser.class);tbUserMapper.insert(tbUser);JSONObject result = new JSONObject();result.put("code", 200);result.put("data", requestBody);result.put("msg", "新增用户数据");return result;}@GetMapping(value = "/readUserInfo")public JSONObject readUserInfo(){TbUserImpl tbUserImpl = new TbUserImpl();List<TbUser> tbUsers = tbUserMapper.selectByExample(tbUserImpl);JSONObject result = new JSONObject();if (!tbUsers.isEmpty()){result.put("code", 200);result.put("data", tbUsers);result.put("msg", "查询所有用户数据");}else{result.put("code", 4000);result.put("data", "");result.put("msg", "数据为空");}return result;}@PutMapping(value = "/changeUserInfo")public JSONObject changeUserInfo(@RequestBody JSONObject requestBody){String username = requestBody.getString("username");TbUserImpl tbUserImpl = new TbUserImpl();TbUserImpl.Criteria criteria = tbUserImpl.createCriteria();criteria.andUsernameEqualTo(username);List<TbUser> tbUsers = tbUserMapper.selectByExample(tbUserImpl);JSONObject result = new JSONObject();if (!tbUsers.isEmpty()){// 这里使用updateByExampleSelective// 不能使用updateByExample,不然必须要含有id参数才能插入成功tbUserMapper.updateByExampleSelective(JSONObject.parseObject(requestBody.toJSONString(),TbUser.class), tbUserImpl);result.put("code", 200);result.put("data", requestBody);result.put("msg", "修改用户数据");return result;}else {result.put("code", 4000);result.put("data", "");result.put("msg", "修改用户数据失败,未找到对应数据");return result;}}@DeleteMapping(value = "/removeUserInfo")public JSONObject removeUserInfo(@RequestBody JSONObject requestBody){String username = requestBody.getString("username");TbUserImpl tbUserImpl = new TbUserImpl();TbUserImpl.Criteria criteria = tbUserImpl.createCriteria();criteria.andUsernameEqualTo(username);List<TbUser> tbUsers = tbUserMapper.selectByExample(tbUserImpl);JSONObject result = new JSONObject();if (!tbUsers.isEmpty()){tbUserMapper.deleteByExample(tbUserImpl);result.put("code", 200);result.put("data", requestBody);result.put("msg", "删除用户数据");return result;}else {result.put("code", 4000);result.put("data", "");result.put("msg", "删除用户数据失败,未找到对应数据");return result;}}}
7.1.2 接口测试
添加数据(注册账号)
url
127.0.0.1:8088/xh/v1/user/addUserInfo
请求类型
POST
请求参数
{"username":"baijuyi","passWord":"965825","gender":"男","address":"上海市长宁区","pNumber":"18898985858","vipClass":1
}
postman截图
查询数据
url
127.0.0.1:8088/xh/v1/user/readUserInfo
请求类型
GET
请求参数 空
postman截图
更新数据
url
127.0.0.1:8088/xh/v1/user/updateUserInfo
请求类型
PUT
请求参数
{"username":"baijuyi","passWord":"965825","gender":"男","address":"上海市杨浦区","pNumber":"18898985858","vipClass":1
}
postman截图
移除数据
url
127.0.0.1:8088/xh/v1/user/removeUserInfo
请求类型
DELETE
请求参数
{"username":"libai"
}
postman截图
7.2 登录接口
在com.xh.user.controller包下创建类UserLogin.java
7.2.1 UserLogin.java
UserLogin.java代码
package com.xh.user.controller;import com.alibaba.fastjson.JSONObject;
import com.xh.user.dao.TbUser;
import com.xh.user.dao.TbUserImpl;
import com.xh.user.dao.TbUserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;/*** @func:* @author: LiBai* @version: v1.0* @createTime: 2025/4/17 10:33*/
@CrossOrigin
@RestController
@RequestMapping(value = "/xh/v1/user")
public class UserLoginController {@AutowiredTbUserMapper tbUserMapper;@RequestMapping(value = "/login")public JSONObject login(@RequestBody JSONObject requestBody){String username = requestBody.getString("username");String passWord = requestBody.getString("passWord");TbUserImpl tbUserImpl = new TbUserImpl();TbUserImpl.Criteria criteria = tbUserImpl.createCriteria();criteria.andUsernameEqualTo(username);criteria.andPassWordEqualTo(passWord);List<TbUser> tbUsers = tbUserMapper.selectByExample(tbUserImpl);JSONObject result = new JSONObject();if (!tbUsers.isEmpty()){result.put("code", 200);result.put("data", tbUsers.get(0));result.put("msg", "账号密码正确,校验通过");return result;}else{result.put("code", 4000);result.put("data", "");result.put("msg", "账号密码错误,校验未通过,请确认账号密码并重新输入");return result;}}
}
注意,登录前必须先注册,注册接口包含在下一步的用户管理类中
7.2.2 接口测试
url
127.0.0.1:8088/xh/v1/user/login
请求类型
POST
请求参数
{"username":"libai","passWord":"352894"
}
postman截图
7.3 商品管理接口
商品管理部分
7.3.1 建表
创建商品表tb_goods
CREATE TABLE tb_goods(id INT AUTO_INCREMENT PRIMARY KEY,g_id INT NOT NULL COMMENT "商品id",g_name VARCHAR(255) NOT NULL COMMENT "商品名称",g_category VARCHAR(255) NOT NULL COMMENT "商品分类",g_price DOUBLE NOT NULL COMMENT "商品价格",g_inventory INT NOT NULL COMMENT "商品库存",g_status VARCHAR(255) NOT NULL COMMENT "商品状态"
);
7.3.2 接口创建(GoodsInfoController.java)
原来项目的商品包名叫product,不是很准确,现在改成goods
在com.xh.goods.dao包下根据表tb_goods生成代码,配置好注解后
在com.xh.goods.controller包下创建商品管理类GoodsInfoController.java
代码如下
package com.xh.goods.controller;import com.alibaba.fastjson.JSONObject;
import com.xh.goods.dao.TbGoods;
import com.xh.goods.dao.TbGoodsImpl;
import com.xh.goods.dao.TbGoodsMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.List;/*** @func:* @author: LiBai* @version: v1.0* @createTime: 2025/4/18 10:55*/
@CrossOrigin
@RestController
@RequestMapping(value = "/xh/v1/goods")
public class GoodsInfoController {@AutowiredTbGoodsMapper tbGoodsMapper;@PostMapping(value = "/addGoodsInfo")public JSONObject addGoodsInfo(@RequestBody JSONObject requestBody){String gName = requestBody.getString("gName");TbGoodsImpl tbGoodsImpl = new TbGoodsImpl();TbGoodsImpl.Criteria criteria = tbGoodsImpl.createCriteria();criteria.andGNameEqualTo(gName);List<TbGoods> tbGoodsList = tbGoodsMapper.selectByExample(tbGoodsImpl);JSONObject result = new JSONObject();if (tbGoodsList.isEmpty()){tbGoodsMapper.insert(JSONObject.parseObject(requestBody.toJSONString(),TbGoods.class));result.put("code", 200);result.put("data", requestBody);result.put("msg", "新增商品信息");}else{result.put("code", 4000);result.put("data", "");result.put("msg", "新增商品信息失败,此商品数据已存在");}return result;}@GetMapping(value = "/readGoodsInfo")public JSONObject readGoodsInfo(){TbGoodsImpl tbGoodsImpl = new TbGoodsImpl();List<TbGoods> tbGoodsList = tbGoodsMapper.selectByExample(tbGoodsImpl);JSONObject result = new JSONObject();if (!tbGoodsList.isEmpty()){result.put("code", 200);result.put("data", tbGoodsList);result.put("msg", "查询商品信息");}else{result.put("code", 4000);result.put("data", "");result.put("msg", "查询商品信息失败,无商品数据");}return result;}@PutMapping(value = "/changeGoodsInfo")public JSONObject changeGoodsInfo(@RequestBody JSONObject requestBody){int gId = requestBody.getInteger("gId");TbGoodsImpl tbGoodsImpl = new TbGoodsImpl();TbGoodsImpl.Criteria criteria = tbGoodsImpl.createCriteria();criteria.andGIdEqualTo(gId);List<TbGoods> tbGoodsList = tbGoodsMapper.selectByExample(tbGoodsImpl);JSONObject result = new JSONObject();if (!tbGoodsList.isEmpty()){tbGoodsMapper.updateByExampleSelective(JSONObject.parseObject(requestBody.toJSONString(), TbGoods.class),tbGoodsImpl);result.put("code", 200);result.put("data", requestBody);result.put("msg", "更新商品数据");}else{result.put("code", 4000);result.put("data", "");result.put("msg", "更新商品数据失败,无此商品数据");}return result;}@DeleteMapping(value = "/removeGoodsInfo")public JSONObject removeGoodsInfo(@RequestBody JSONObject requestBody){int gId = requestBody.getInteger("gId");TbGoodsImpl tbGoodsImpl = new TbGoodsImpl();TbGoodsImpl.Criteria criteria = tbGoodsImpl.createCriteria();criteria.andGIdEqualTo(gId);List<TbGoods> tbGoodsList = tbGoodsMapper.selectByExample(tbGoodsImpl);JSONObject result = new JSONObject();if (!tbGoodsList.isEmpty()){tbGoodsMapper.deleteByExample(tbGoodsImpl);result.put("code", 200);result.put("data", requestBody);result.put("msg", "删除商品数据");}else{result.put("code", 4000);result.put("data", "");result.put("msg", "删除商品数据失败,无此商品数据");}return result;}
}
7.3.3 接口测试
新增商品数据
url
127.0.0.1:8088/xh/v1/goods/addGoodsInfo
请求类型
POST
请求参数
{"gId": 100001,"gName": "海洋至尊洗面奶","gCategory": "护肤品","gPrice": 46.90,"gInventory": 98,"gStatus": "上架"}
postman截图
查询商品数据
url
127.0.0.1:8088/xh/v1/goods/readGoodsInfo
请求类型
GET
请求参数 空
postman截图
更新商品数据
url
127.0.0.1:8088/xh/v1/goods/updateGoodsInfo
请求类型
PUT
请求参数
{"gId": 100002,"gName": "韩束男士补水保湿乳","gCategory": "护肤品","gPrice": 90.98,"gInventory": 58,"gStatus": "上架"}
postman截图
移除商品数据
url
127.0.0.1:8088/xh/v1/goods/removeGoodsInfo
请求类型
DELETE
请求参数
{"gId":"100001"
}
postman截图
7.4 订单管理接口
7.4.1 建表
创建商品表tb_order
CREATE TABLE tb_order(id INT AUTO_INCREMENT PRIMARY KEY,o_id INT NOT NULL COMMENT "订单号(订单id)",username VARCHAR(255) NOT NULL COMMENT "客户名称",o_price DOUBLE NOT NULL COMMENT "订单价格",o_time VARCHAR(255) NOT NULL COMMENT "下单时间",o_status VARCHAR(255) NOT NULL COMMENT "订单状态"
);
7.4.2 接口创建(OrderInfoController.java)
在com.xh.order.dao包下根据表tb_order生成代码,配置好注解后
在com.xh.order.controller包下创建商品管理类OrderInfoController.java
代码如下
package com.xh.order.controller;import com.alibaba.fastjson.JSONObject;
import com.xh.order.dao.TbOrder;
import com.xh.order.dao.TbOrderImpl;
import com.xh.order.dao.TbOrderMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.List;/*** @func:* @author: LiBai* @version: v1.0* @createTime: 2025/4/18 14:10*/
@CrossOrigin
@RestController
@RequestMapping(value = "/xh/v1/order")
public class OrderInfoController {@AutowiredTbOrderMapper tbOrderMapper;@PostMapping(value = "/addOrderInfo")public JSONObject addOrderInfo(@RequestBody JSONObject requestBody){TbOrderImpl tbOrderImpl = new TbOrderImpl();TbOrderImpl.Criteria criteria = tbOrderImpl.createCriteria();criteria.andOIdEqualTo(requestBody.getString("oId"));List<TbOrder> tbOrders = tbOrderMapper.selectByExample(tbOrderImpl);JSONObject result = new JSONObject();if (tbOrders.isEmpty()){tbOrderMapper.insert(JSONObject.parseObject(requestBody.toJSONString(), TbOrder.class));result.put("code", 200);result.put("data", requestBody);result.put("msg", "新增订单数据");}else{result.put("code", 4000);result.put("data", "");result.put("msg", "新增订单数据失败,此订单数据已存在");}return result;}@GetMapping(value = "/readOrderInfo")public JSONObject readOrderInfo(){TbOrderImpl tbOrderImpl = new TbOrderImpl();List<TbOrder> tbOrders = tbOrderMapper.selectByExample(tbOrderImpl);JSONObject result = new JSONObject();if (!tbOrders.isEmpty()){result.put("code", 200);result.put("data", tbOrders);result.put("msg", "查询订单数据");}else{result.put("code", 4000);result.put("data", "");result.put("msg", "查询订单数据失败,未查询到订单数据");}return result;}@PutMapping(value = "/changeOrderInfo")public JSONObject changeOrderInfo(@RequestBody JSONObject requestBody){TbOrderImpl tbOrderImpl = new TbOrderImpl();TbOrderImpl.Criteria criteria = tbOrderImpl.createCriteria();criteria.andOIdEqualTo(requestBody.getString("oId"));List<TbOrder> tbOrders = tbOrderMapper.selectByExample(tbOrderImpl);JSONObject result = new JSONObject();if (!tbOrders.isEmpty()){tbOrderMapper.updateByExampleSelective(JSONObject.parseObject(requestBody.toJSONString(), TbOrder.class),tbOrderImpl);result.put("code", 200);result.put("data", requestBody);result.put("msg", "更新订单数据");}else{result.put("code", 4000);result.put("data", "");result.put("msg", "更新订单数据失败,未查询到此订单数据");}return result;}@DeleteMapping(value = "/removeOrderInfo")public JSONObject removeOrderInfo(@RequestBody JSONObject requestBody){TbOrderImpl tbOrderImpl = new TbOrderImpl();TbOrderImpl.Criteria criteria = tbOrderImpl.createCriteria();criteria.andOIdEqualTo(requestBody.getString("oId"));List<TbOrder> tbOrders = tbOrderMapper.selectByExample(tbOrderImpl);JSONObject result = new JSONObject();if (!tbOrders.isEmpty()){tbOrderMapper.deleteByExample(tbOrderImpl);result.put("code", 200);result.put("data", requestBody);result.put("msg", "移除订单数据");}else{result.put("code", 4000);result.put("data", "");result.put("msg", "移除订单数据失败,此订单数据不存在");}return result;}}
7.4.3 接口测试
新增商品数据
url
127.0.0.1:8088/xh/v1/order/addOrderInfo
请求类型
POST
请求参数
{"oId": "20250418152634000001","username": "libai","oPrice": 121.20,"oTime": "2025-04-18,15:26:34","oStatus": "配送中"}
postman截图
查询商品数据
url
127.0.0.1:8088/xh/v1/order/readOrderInfo
请求类型
GET
请求参数 空
postman截图
更新商品数据
url
127.0.0.1:8088/xh/v1/order/updateOrderInfo
请求类型
PUT
请求参数
{"oId": "20250418154624000002","username": "liqingzhao","oPrice": 166.89,"oTime": "2025-04-18,15:46:24","oStatus": "未配送"}
postman截图
移除商品数据
url
127.0.0.1:8088/xh/v1/order/removeOrderInfo
请求类型
DELETE
请求参数
{"oId": "20250418154624000002"}
postman截图
以上就是入门实战全部内容
📜文末寄语
- 🟠关注我,获取更多内容。
- 🟡技术动态、实战教程、问题解决方案等内容持续更新中。
- 🟢《全栈知识库》技术交流和分享社区,集结全栈各领域开发者,期待你的加入。
- 🔵加入开发者的《专属社群》,分享交流,技术之路不再孤独,一起变强。
- 🟣点击下方名片获取更多内容🍭🍭🍭👇
相关文章:
SpringBoot入门实战(项目搭建、配置、功能接口实现等一篇通关)
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 SpringBoot入门实战(项目搭建、配…...
昆仑万维开源SkyReels-V2,解锁无限时长电影级创作,总分83.9%登顶V-Bench榜单
昆仑万维开源了全球首个基于扩散强迫框架(Diffusion-forcing)的无限时长视频生成模型——SkyReels-V2。这一模型以总分83.9%的优异成绩登顶权威评测V-Bench1.0榜单,并在质量维度获得84.7%的评分,刷新了开源视频生成技术的天花板。…...
精选面试题
1、js中set和map的作用和区别? 在 JavaScript 中,Set 和 Map 是两种非常重要的集合类型 1、Set 是一种集合数据结构,用于存储唯一值。它类似于数组,但成员的值都是唯一的,没有重复的值。Set 中的值只能是唯一的,任何…...
【技术派后端篇】技术派中 Session/Cookie 与 JWT 身份验证技术的应用及实现解析
在现代Web应用开发中,身份验证是保障系统安全的重要环节。技术派在身份验证领域采用了多种技术方案,其中Session/Cookie和JWT(JSON Web Token)是两种常用的实现方式。本文将详细介绍这两种身份验证技术在技术派中的应用及具体实现…...
【CAPL实战:以太网】对IPv4报文的Payload部分进行分片并创建分片包
As we know,TCP/IP协议栈网络层接收到来自上层的数据时,并不是简单地添加报头发送出去,而是会受到来自网卡配置参数MTU的约束。也就是从网卡上发送出去的以太网帧报文的数据部分的长度不能大于MTU值。即网络层头部 + 有效载荷不能大于MTU。 所以网络层在发送上层的数据时,…...
Spring Security认证流程
认证是Spring Security的核心功能之一,Spring Security所提供的认证可以更好地保护系统的隐私数据与资源,只有当用户的身份合法后方可访问该系统的资源。Spring Security提供了默认的认证相关配置,开发者也可以根据自己实际的环境进行自定义身…...
Spring Security基础入门
本入门案例主要演示Spring Security在Spring Boot中的安全管理效果。为了更好地使用Spring Boot整合实现Spring Security安全管理功能,体现案例中Authentication(认证)和Authorization(授权)功能的实现,本案…...
Axure疑难杂症:母版菜单设置打开链接后菜单选中效果
亲爱的小伙伴,在您浏览之前,烦请关注一下,在此深表感谢! Axure产品经理精品视频课已登录CSDN可点击学习https://edu.csdn.net/course/detail/40420 课程主题:菜单打开链接后子菜单选中效果 主要内容:母版设计、选中效果 应用场景:页面赋值 案例展示: 案例视频:...
4月份最新---Meta发明了一种很新的Transformer
在自然语言处理领域,当模型处理长上下文时,如何在纷繁的 Token 中精准捕捉关键信息、过滤无关干扰,始终是注意力机制优化的核心方向。标准多头注意力(Multi-Head Attention, MHA)通过查询 - 键 - 值(Q-K-V)的点积相似性计算注意力权重,虽能定位单个 Token 级别的语义关…...
Spring Boot知识点详解
打包部署 <!‐‐ 这个插件,可以将应用打包成一个可执行的jar包;‐‐> <build><plugins> <plugin> <groupId>org.springframework.boot</groupId><artifactId>spring‐boot‐maven‐plugin</artifactId&g…...
基于 EFISH-SBC-RK3588 的无人机多光谱/红外热成像边缘计算方案
一、硬件架构设计 核心算力平台(EFISH-SBC-RK3588) 处理器性能:搭载 8 核 ARM 架构(4Cortex-A762.4GHz 4Cortex-A551.8GHz),集成 6 TOPS NPU 与 Mali-G610 GPU,支持多光谱图像实时融…...
字典与集合——测试界的黑话宝典与BUG追捕术
主题:“字典是测试工程师的暗号手册,集合是BUG的照妖镜” 一、今日目标 ✅ 掌握字典的「键值对暗号体系」与集合的「去重妖法」✅ 开发《测试工程师黑话词典》,让新人秒变老司机✅ 统计自动化测试结果中的高频BUG类型(附赠甩锅指…...
QT构建即时通讯应用--WebSocket全面解析与实战指南
概述 WebSocket协议因其低延迟和双向通信的能力而成为了现代Web和桌面应用程序的首选,Qt框架提供了强大的WebSocket支持,使得开发者可以轻松地集成这一技术到自己的项目中 WebSocket简介 WebSocket是一种在单个TCP连接上进行全双工通信的协议。它允许服务器主动向客户端推…...
复杂性决策-思维训练
思维训练 1.模式识别 观察、复杂、不确定、波动、模糊 –找出必要和非必要因素 –识别重大威胁和机遇 2.系统分析 为复杂情景构建系统心智模型 利用模型识别模式做出预测,指定有效策略 3.心智敏锐度 利用不同层次的分析探索挑战的能力,对其他利益相关方在…...
缓存集群技术深度解析:从原理到实战
缓存集群技术深度解析:从原理到实战 一、缓存集群核心定位与架构选型 1. 集群模式核心价值 缓存集群通过数据分片、高可用保障、水平扩展解决单节点瓶颈,核心能力包括: 数据分片:将数据分散到多个节点,突破单节点内…...
Qt C++/Go/Python 面试题(持续更新)
目录 1、封装、继承、多态是什么? 2、final标识符的作用是什么? 3、介绍一下虚函数 4、介绍一下智能指针 5、介绍一下左值、右值、左值引用、右值引用 6、指针和引用有什么区别? 7、define和const的区别是什么? 8、C程序的…...
Spring Cloud Alibaba VS Spring Cloud
Spring Cloud Alibaba 与 Spring Cloud 组件对比 服务发现与注册中心 功能Spring CloudSpring Cloud Alibaba对比说明核心组件EurekaNacosNacos 支持动态配置管理、健康检查更灵活,且提供 DNS 服务发现能力。健康检查…...
containerd 配置代理
1.systemd unit file 为 containerd 服务创建一个 systemd 插入目录 mkdir /etc/systemd/system/containerd.service.d/创建名为 /etc/systemd/system/containerd.service.d/http-proxy.conf 的文件 添加 HTTP_PROXY 环境变量 [Service] Environment"HTTP_PROXYhttp:/…...
专家系统的基本概念解析——基于《人工智能原理与方法》的深度拓展
一、什么是专家系统 (一)基本思想与定义 1. 核心思想:知识与推理的分离 迄今为止,关于专家系统还没有一个公认的严格定义,一般认为: (1)它是一个智能程序系统; &…...
什么是公链?公链项目有哪些?公链项目开发
公链技术全景解析:定义、生态与开发指南(2025年深度版) 一、公链的本质与核心特征 1.1 公链的定义 公链(Public Blockchain)是一种完全开放、无需许可的区块链网络架构,其核心特征在于去中心化、透明…...
如何解析商品详情页面
解析商品详情页面是爬虫开发中的一个重要环节。由于商品详情页面通常包含丰富的信息,如商品名称、价格、描述、图片等,因此需要仔细分析页面结构并提取所需数据。以下是一个详细的步骤指南,展示如何使用 Java 和 Jsoup 解析商品详情页面。 一…...
Android 混合开发实战:统一 View 与 Compose 的浅色/深色主题方案
整个应用(包括 View 和 Compose 部分)的浅色/深色模式保持一致。以下是完整的解决方案: 全局配置方案 1. 基础主题设置 在 res/values/themes.xml 和 res/values-night/themes.xml 中定义统一的主题: <!-- values/themes.x…...
三国杀专业分析面板,立志成为桌游界的stockfish
三国杀专业分析面板 (SGSFish) GitHub仓库: 本项目是一个基于 Python 实现的三国杀专业分析面板,旨在模拟玩家决策过程,通过量化评估动作实体(卡牌/技能)的价值、考虑它们之间的相互影响(包括基于作用域的…...
解析 select 函数
解析 select 函数 select 函数是 Unix/Linux 系统中用于多路复用的系统调用,主要用于在多个文件描述符(file descriptors)上等待事件的发生。它允许程序同时监视多个 I/O 通道,并在任意一个通道准备好进行 I/O 操作时通知程序&am…...
对话模型和补全模型区别
对话模型和补全模型区别 什么是对话模型、补全模型 什么是 Completion 最基本地说,文本模型是一个经过训练的大型数学模型,旨在完成一项单一任务:预测下一个 token 或字符。这个过程被称为 completion,在您的旅程中您会经常遇到这个术语。 例如,当使用 completion 文本…...
计算机图形学实践:结合Qt和OpenGL实现绘制彩色三角形
以下是使用Qt和OpenGL实现绘制彩色三角形并添加颜色选择按钮的步骤: 一、创建OpenGL绘制组件 继承QOpenGLWidget实现自定义绘制类: // myopenglwidget.h #include <QOpenGLWidget> #include <QOpenGLFunctions_3_3_Core> #include <QO…...
十分钟应急响应——自定义工具链整合实战
核心思路 结合群联AI云防护的API和自定义脚本,实现攻击检测、节点切换、日志分析的端到端自动化。 技术实现步骤 1. 实时攻击检测脚本 使用Python监听群联系统日志,识别攻击特征: # monitor_attack.py import json import subprocess from…...
SpringCloud微服务架构设计与实践 - 面试实战
SpringCloud微服务架构设计与实践 - 面试实战 第一轮提问 面试官:马架构,请问在SpringCloud微服务架构中,如何实现服务注册与发现? 马架构:在SpringCloud中,Eureka是常用的服务注册与发现组件。服务提供…...
每日算法——快乐数、两数之和
202. 快乐数 class Solution { public:bool isHappy(int n) {unordered_set<int> result_set;while(true){int sum 0;while(n>0){sum (n%10)*(n%10);n/10;}if(sum1){return true;}else{if(result_set.find(sum) ! result_set.end()){return false;}result_set.inser…...
反射,枚举,lambda表达式
目录 反射枚举的使用Lambda表达式函数式接口语法Lambda表达式语法精简 变量捕获Lambda在集合List中的使用 反射 作用:在Java代码中,让一个对象认识到自己 比如一个类的名字,里面的方法,属性等 让程序运行的过程,某个对…...
matlab 绘图
1.三维绘图 % 原始数据(按行输入:x y z) data [1 2 3 ;5 56 234 ;32 34 67 1 2 5 ];% 提取坐标并生成网格(适用于surf函数的网格格式) x data(:,1); % X坐标(行数对应Y轴) y data…...
AI日报 - 2025年04月25日
🌟 今日概览(60秒速览) ▎🤖 AGI突破 | OpenAI o3模型展现行动能力,英国发布RepliBench评估AI自主复制风险,DeepMind CEO担忧AGI协调挑战。 模型能力向行动和自主性演进,安全与协调成为焦点。 ▎💼 商业动向…...
力扣面试150题--基本计算器
Day 31 题目描述 思路 (逆波兰表达式扩展) 初次思路:此题我遇到了几个难点 如何处理()如何处理-1和2-1中的负数还是减法问题 1-(-(12))如何处理多余的空格 我的做法如…...
各种各样的bug合集
一、连不上数据库db 1.可能是密码一大包东西不对; 2.可能是里面某个port和数据库不一样(针对于修改了数据库但是连不上的情况); 3.可能是git代码没拉对,再拉一下代码。❤ 二、没有这个包 可能是可以#注释掉。❤ …...
【25软考网工】第三章(3)虚拟局域网VLAN
一、虚拟局域网VLAN 1. VLAN基础 定义:根据管理功能、组织机构或应用类型对交换局域网进行分段而形成的逻辑网络。例如将大型网络划分为多个VLAN(如VLAN1-4)。 优势: 管理便利:便于对不同部门或功能进行分组管理安全隔…...
SFINAE(Substitution Failure Is Not An Error)
C 中的 SFINAE(替换失败并非错误) SFINAE(Substitution Failure Is Not An Error)是 C 模板元编程的核心机制之一,允许在编译时根据类型特性选择不同的模板实现。以下通过代码示例和底层原理,逐步解析 SFI…...
学习记录:DAY17
我的学习日志:前端开发练习 前言 只想畏缩在自己的床上,什么也不想干😰 我觉得有必要调整一下复习方针,不然容易白学。 我确实不太爱复习的人,尽量每天抽出时间来复习昨天的内容,周末总体复习一下一个星期…...
LibrePhotos本地部署打造个人云相册安全存储和分享家庭照片(1)
文章目录 前言1.关于LibrePhotos2.本地部署LibrePhotos3.LibrePhotos简单使用4. 安装内网穿透5.配置LibrePhotos公网地址6. 配置固定公网地址 前言 手机里塞满了珍贵回忆,却担心一不小心就被偷看?别怕,今天我就教你一个绝招——使用LibrePho…...
Android插拔U盘导致黑屏问题排查
问题现象: 车机大屏偶先插拔带音乐的U盘,导致车机系统短暂黑屏的情况。 日志中可以看到vold进程unmount了两次分区,一次是U盘分区,一次是/storage/emulated/0分区: I vold : Start killProcesses: /mnt/media_rw/…...
Android Build Variants(构建变体)详解
Android Build Variants(构建变体)是 Android 开发中用于生成不同版本应用程序的一种机制。它允许开发者根据不同的需求,如不同的应用市场、不同的功能模块、不同的环境配置等,从同一个代码库中生成多个不同的 APK。 组成部分 B…...
看一看 中间件Middleware
中间件(Middleware)是介于操作系统与应用程序之间的一层软件 它为分布式应用程序提供了统一的通信、数据交换、服务调用、消息传递等能力。 它的作用就像“胶水”,连接各个系统组件。 文章目录 消息队列缓存中间件数据库中间件服务注册与发现…...
ai人才需要掌握什么
在人工智能(AI)技术重塑全球产业格局的今天,AI人才的核心竞争力已超越单一技术维度,演变为“技术深度+人文广度+伦理自觉”的三维能力模型。本文将从技术能力体系、跨学科思维、伦理与治理三个层面,解析AI人才的核心能力框架,并针对技术局限性提出系统性应对策略。 一、…...
RISC-V低功耗MCU动态时钟门控技术详解
我来分享一下RISC-V核低功耗MCU的动态时钟门控技术实现: 这款MCU通过硬件级时钟门控电路实现了模块级的功耗管理。当外设(如UART、SPI)处于闲置状态时,系统会自动切断其时钟信号,减少无效翻转功耗。同时支持多电压域协…...
第十天 Shader编程:编写简单表面着色器 Addressable资源管理系统 DOTS(面向数据技术栈)入门
前言 作为Unity初学者,在实现复杂场景时经常会遇到性能瓶颈。本文将带你通过四个关键技术的实战学习,掌握现代Unity开发的核心优化方案: Shader编程 - 编写表面着色器控制物体渲染Addressable系统 - 实现高效资源管理DOTS技术栈 - 解锁百万…...
把dll模块注入到游戏进程的方法_插APC注入
一、概述 APC是异步过程调用,系统创建线程的时候会为线程创建一个APC队列,当线程调用SleepEx,WaitSingleObjectEx等函数时,并把线程状态被设置为可提醒状态时,线程并不会睡眠,而是检查APC队列是否为空,如果不为空,转去执行APC队列中的每一项,因此给目标进程中的线程插…...
【C++】内存管理:内存划分、动态内存管理(new、delete用法)
文章目录 一、C/C中的内存划分二、C语言中动态内存管理方式三、C中动态内存管理方式1、new、delete基本用法(1)、内置类型(2)、自定义类型 2、operator new与operator delete函数3、new和delete的实现原理(1)内置类型(2)自定义类型…...
【k8s】KubeProxy 的三种工作模式——Userspace、iptables 、 IPVS
在 Kubernetes 集群中,KubeProxy 是实现 Service 的网络代理和负载均衡功能的关键组件。它支持三种工作模式:Userspace 模式、iptables 模式和 IPVS 模式。每种模式都有其特点和适用场景,以下是详细介绍: Userspace 模式 工作原…...
密码学的hash函数,哈希碰撞, collision resistance, BTC用到的SHA-256简介
密码学中的哈希函数、哈希碰撞、抗碰撞性(collision resistance)以及比特币中使用的 SHA-256 的简明介绍: 🧩 一、哈希函数(Hash Function) 定义: 哈希函数是一种将任意长度的输入(…...
通过监督微调(SFT)提升AI Agent效果的完整指南
一、SFT技术深度剖析 1.1 核心概念 监督微调(Supervised Fine-Tuning)是在大规模预训练语言模型(如LLaMA、GPT系列)的基础上,使用特定任务标注数据进行二次训练的过程。其本质是通过有监督学习调整模型参数ÿ…...
TCP基础题:音乐播放列表管理系统
需求描述 服务器端 创建一个 TCP 服务器,监听本地的 9999 端口,支持多个客户端连接。维护一个音乐播放列表,每个音乐条目包含歌曲名称、歌手、时长等信息。能够处理客户端的以下请求: 添加音乐到播放列表:接收客户端发…...