微服务-MybatisPlus下
微服务-MybatisPlus下
文章目录
- 微服务-MybatisPlus下
- 1 MybatisPlus扩展功能
- 1.1 代码生成
- 1.2 静态工具
- 1.3 逻辑删除
- 1.4 枚举处理器
- 1.5 JSON处理器
- **1.5.1.定义实体**
- **1.5.2.使用类型处理器**
- **1.6 配置加密(选学)**
- 1.6.1.生成秘钥
- **1.6.2.修改配置**
- **1.6.3.测试**
- 2 插件功能
- 2.1 分页插件
- 2.2 通用分页实体
- 2.2.1 简单分页查询
- 2.2.2 通用分页查询
1 MybatisPlus扩展功能
1.1 代码生成
自己从头开始,则步骤如下图所示



1.2 静态工具
有的时候Service之间也会相互调用,为了避免出现循环依赖问题,MybatisPlus提供一个静态工具类:Db,其中的一些静态方法与IService中方法 签名基本一致。主要差别就是由于是静态的,之前没有指定过实体对象,所以除save、update以外的函数几乎都要传入实体类,让底层调用反射机制,得到实体类。而save、update由于本身参数就需要传入一个实体类对象,此对象就可通过反射得到实体类,所以不需要再传入实体类。
实现CRUD功能:

案例:静态工具查询
需求:
- 改造根据id查询用户的接口,查询用户的同时,查询出用户对应的所有地址
- 改造根据id批量查询用户的接口,查询用户的同时,查询出用户对应的所有地址
- 实现根据用户id查询收货地址功能,需要验证用户状态,冻结用户抛出异常(练习)
可以看到以上需求一般都需要在注入了userService之后,再注入addressService才能实现(当然你用多表联合或者注入mapper当我没说)。那这就涉及到了多个Service的相互调用,出现循环依赖问题,这种情况下就可以使用静态工具来解决。而且静态工具不需要注入,这样就避免了循环依赖
第一题:
- controller层
@GetMapping("{id}")@ApiOperation(value = "根据id查询用户接口")public UserVO queryUserById(@ApiParam("用户id") @PathVariable("id") Long id){
// User user = userService.getById(id);
// UserVO userVO = BeanUtil.copyProperties(user, UserVO.class);
// return userVO;return userService.queryUserAndAddressById(id);}
- service层
@Overridepublic UserVO queryUserAndAddressById(Long id) {//1. 查询用户User user = getById(id);if(user == null || user.getStatus() == 2){throw new RuntimeException("用户状态异常");}//2. 查询地址//这里本来可以直接用本service的lambdaQuery函数 单位了避免循环依赖,就使用静态工具List<Address> list = Db.lambdaQuery(Address.class).eq(Address::getUserId, user.getId()).list();//3. 封装vo//3.1 转User的PO为VoUserVO userVO = BeanUtil.copyProperties(user, UserVO.class);//3.2 转地址VOif(CollUtil.isNotEmpty(list)){userVO.setAddressList(BeanUtil.copyToList(list, AddressVO.class));}return userVO;}
第二题:
@Overridepublic List<UserVO> queryUserAndAddressByIds(List<Long> ids) {//1. 查询用户List<User> users = listByIds(ids);if(CollUtil.isEmpty(users)){return Collections.emptyList();}//2. 查询地址//2.1 获取用户id集合List<Long> userIds = users.stream().map(User::getId).collect(Collectors.toList());//2.2 根据用户id查询地址List<Address> addresses = Db.lambdaQuery(Address.class).in(Address::getUserId, userIds).list();//2.3 转换地址VOList<AddressVO> addressVOList = BeanUtil.copyToList(addresses, AddressVO.class);//2.4 用户地址集合分组处理、相同用户的放入一个集合(组)中Map<Long, List<AddressVO>> addressMap = new HashMap<>(0);if(CollUtil.isNotEmpty(addressVOList)) {addressMap = addressVOList.stream().collect(Collectors.groupingBy(AddressVO::getUserId));}//3. 转换为VO返回List<UserVO> list = new ArrayList<>(users.size());for(User user:users){//3.1 转换user的PO为VOUserVO userVO = BeanUtil.copyProperties(user, UserVO.class);list.add(userVO);//3.2 转换为VOuserVO.setAddressList(addressMap.get(user.getId()));}return list;}
也就是静态工具的使用和IService一样,只不过多了个实体类传入。当一个serivice中需要多个service时,就是用静态工具,用法类似,也有普通函数以及复杂条件查询函数,比如Db.lambdaQuery,Db.Db.lambdaUpdate。
1.3 逻辑删除
逻辑删除就是基于代码逻辑模拟删除效果,但并不会真正删除数据。思路如下:
- 在表中添加一个字段标记数据是否被删除
- 当删除数据时把标记置为1
- 查询时只查询标记为0的数据

MybatisPlus提供了逻辑删除技能,无需改变方法调用的方法,而是在底层帮我们自动修改CRUD的语句。我们要做的就是在applicaiton.yaml文件中配置逻辑删除的字段名称和值即可。

@Autowiredprotected AddressService addressService;@Testvoid testLogicDelete(){//1. 删除addressService.removeById(59L);//2. 查询Address address = addressService.getById(59L);System.out.println("address = " + address);}
虽然使用的remove方法,但是实际执行的是update方法。且在数据库中还存在,只不过deleted变成了true

1.4 枚举处理器
User类中有一个用户状态字段:

使用枚举表示状态,可以提高可读性。但是问题来了

数据库中status仍然是int类型,这就需要一个枚举类型到int类型的转化。

幸运的是Mybatis和mp帮我们解决了,如上图所示。只需要在枚举类中对应的字段上加上@EnumValue注释 mp就会自动把对应的字段值与数据库中列匹配

在applicaiton.yml中配置全局枚举类处理器

@JsonValue //用于枚举的返回值 数据库返回显示的值,比如此处是返回desc的值 也可以返回value的值 否则默认返回的是枚举的对象名 比如此处的NORMAL FROZEN
@Getter
public enum UserStatus {NORMAL(1,"正常"),FROZEN(2,"冻结"),;@EnumValueprivate final int value;@JsonValue //用于枚举的返回值 数据库返回显示的值private final String desc;UserStatus(int value,String desc){this.value = value;this.desc = desc;}}

1.5 JSON处理器
数据库的user表中有一个info字段,是JSON类型:

格式像这样:
{"age": 20, "intro": "佛系青年", "gender": "male"}
而目前User实体类中却是String类型:

这样一来,我们要读取info中的属性时就非常不方便。如果要方便获取,info的类型最好是一个Map或者实体类。
而一旦我们把info改为对象类型,就需要在写入数据库时手动转为String,再读取数据库时,手动转换为对象,这会非常麻烦。
意思就是对象的String字段可以被mp自动转换为数据库中的JSON,但是数据库中的JSON不能被mp自动帮我们转换为String或者相应的对象
因此MybatisPlus提供了很多特殊类型字段的类型处理器,解决特殊字段类型与数据库类型转换的问题。例如处理JSON就可以使用JacksonTypeHandler处理器。

1.5.1.定义实体
首先,我们定义一个单独实体类来与info字段的属性匹配:

代码如下:
package com.itheima.mp.domain.po;import lombok.Data;@Data
public class UserInfo {private Integer age;private String intro;private String gender;
}
1.5.2.使用类型处理器
接下来,将User类的info字段修改为UserInfo类型,并声明类型处理器:

测试可以发现,所有数据都正确封装到UserInfo当中了:

同时,为了让页面返回的结果也以对象格式返回,我们要修改UserVO中的info字段:

此时,在页面查询结果如下:

注意: 由于User类中嵌套了UserInfo类,出现了类的嵌套,那么就需要定义复杂的ResultMap,但是我们又不想定义,那么就直接在User类上加注释,autoResultMap = true 如下图所示

1.6 配置加密(选学)
目前我们配置文件中的很多参数都是明文,如果开发人员发生流动,很容易导致敏感信息的泄露。所以MybatisPlus支持配置文件的加密和解密功能。
我们以数据库的用户名和密码为例。
1.6.1.生成秘钥
首先,我们利用AES工具生成一个随机秘钥,然后对用户名、密码加密:
package com.itheima.mp;import com.baomidou.mybatisplus.core.toolkit.AES;
import org.junit.jupiter.api.Test;class MpDemoApplicationTests {@Testvoid contextLoads() {// 生成 16 位随机 AES 密钥String randomKey = AES.generateRandomKey();System.out.println("randomKey = " + randomKey);// 利用密钥对用户名加密String username = AES.encrypt("root", randomKey);System.out.println("username = " + username);// 利用密钥对用户名加密String password = AES.encrypt("MySQL123", randomKey);System.out.println("password = " + password);}
}
打印结果如下:
randomKey = 6234633a66fb399f
username = px2bAbnUfiY8K/IgsKvscg==
password = FGvCSEaOuga3ulDAsxw68Q==
1.6.2.修改配置
修改application.yaml文件,把jdbc的用户名、密码修改为刚刚加密生成的密文:
spring:datasource:url: jdbc:mysql://127.0.0.1:3306/mp?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=truedriver-class-name: com.mysql.cj.jdbc.Driverusername: mpw:QWWVnk1Oal3258x5rVhaeQ== # 密文要以 mpw:开头password: mpw:EUFmeH3cNAzdRGdOQcabWg== # 密文要以 mpw:开头
1.6.3.测试
在启动项目的时候,需要把刚才生成的秘钥添加到启动参数中,像这样:
–mpw.key=6234633a66fb399f
单元测试的时候不能添加启动参数,所以要在测试类的注解上配置:

然后随意运行一个单元测试,可以发现数据库查询正常。
2 插件功能
MyBatisPlus提供的内置拦截器有下面这些

2.1 分页插件
在未引入分页插件的情况下,MybatisPlus是不支持分页功能的,IService和BaseMapper中的分页方法都无法正常起效。 所以,我们必须配置分页插件。
- 首先,要在配置类中注册MyBatisPlus的核心插件,同时添加分页插件

- 接着,就可以使用分页的API了


void testPageQuery(){int pageNo = 1;int pageSize = 2;//1. 准备分页条件//1.1 分页条件Page<User> page = Page.of(pageNo, pageSize);//1.2 排序条件 可以指定多个 比如下面 余额相同则按id排序page.addOrder(new OrderItem("balance",true));page.addOrder(new OrderItem("id",true));//2. 分页查询Page<User> p = userService.page(page);//3. 解析long total = p.getTotal(); //总条数System.out.println("total = " + total);long pages = p.getPages(); //总页数System.out.println("pages = " + pages);List<User> records = p.getRecords(); //分页数据records.forEach(System.out::println);}
2.2 通用分页实体
2.2.1 简单分页查询
案例:简单分页查询案例
需求:遵循下面的接口规范,编写一个UserController接口,实现User的分页查询

- 实体类
public class PageQuery {@ApiModelProperty("页码")private Integer pageNo;@ApiModelProperty("页大小")private Integer pageSize;@ApiModelProperty("排序字段")private String sortBy;@ApiModelProperty("是否升序")private Boolean isAsc;
}@Data
@EqualsAndHashCode(callSuper = true)
@ApiModel(description = "用户查询条件实体")
public class UserQuery extends PageQuery{@ApiModelProperty("用户名关键字")private String name;@ApiModelProperty("用户状态:1-正常,2-冻结")private Integer status;@ApiModelProperty("余额最小值")private Integer minBalance;@ApiModelProperty("余额最大值")private Integer maxBalance;
}
- controller
@GetMapping("/page")@ApiOperation(value = "根据条件分页查询用户接口")public PageDTO<UserVO> queryUsersPage(UserQuery query){return userService.queryUsersPage(query);}
- impl层
@Overridepublic PageDTO<UserVO> queryUsersPage(UserQuery query) {String name = query.getName();Integer status = query.getStatus();//1. 构建查询条件Page<User> page = Page.of(query.getPageNo(), query.getPageSize());if(StrUtil.isNotBlank(query.getSortBy())){//不为空page.addOrder(new OrderItem(query.getSortBy(),query.getIsAsc()));}else {//为空 默认按照更新时间排序page.addOrder(new OrderItem("update_time",false));}//2. 分页查询Page<User> p = lambdaQuery().like(name != null, User::getUsername, name).eq(status != null, User::getStatus, status)
// .ge(minBalance != null, User::getBalance, minBalance)
// .le(maxBalance != null, User::getBalance, maxBalance).page(page);//3. 封装VO结果PageDTO<UserVO> userVOPageDTO = new PageDTO<>();userVOPageDTO.setTotal(p.getTotal());userVOPageDTO.setPages(p.getPages());List<User> records = p.getRecords();if(CollUtil.isEmpty(records)){userVOPageDTO.setList(Collections.emptyList());}else {List<UserVO> userVOS = BeanUtil.copyToList(records, UserVO.class);userVOPageDTO.setList(userVOS);}//4. 返回return userVOPageDTO;}
2.2.2 通用分页查询

- 改造PageQuery类
@Data
@ApiModel(description = "分页查询实体")
public class PageQuery {@ApiModelProperty("页码")private Integer pageNo = 1;@ApiModelProperty("页大小")private Integer pageSize = 5;@ApiModelProperty("排序字段")private String sortBy;@ApiModelProperty("是否升序")private Boolean isAsc = true;public <T> Page<T> toMpPage(OrderItem ... orders){// 1.分页条件Page<T> p = Page.of(pageNo, pageSize);// 2.排序条件// 2.1.先看前端有没有传排序字段if (sortBy != null) {p.addOrder(new OrderItem(sortBy, isAsc));return p;}// 2.2.再看有没有手动指定排序字段if(orders != null){p.addOrder(orders);}return p;}public <T> Page<T> toMpPage(String defaultSortBy, boolean isAsc){return this.toMpPage(new OrderItem(defaultSortBy, isAsc));}public <T> Page<T> toMpPageDefaultSortByCreateTimeDesc() {return toMpPage("create_time", false);}public <T> Page<T> toMpPageDefaultSortByUpdateTimeDesc() {return toMpPage("update_time", false);}
}
- 改造PageDTO类
@Data
@ApiModel(description = "分页结果")
@AllArgsConstructor
@NoArgsConstructor
public class PageDTO<T> {@ApiModelProperty("总条数")private Long total;@ApiModelProperty("总页数")private Long pages;@ApiModelProperty("总数据")private List<T> list;/*** 返回空分页结果* @param p MybatisPlus的分页结果* @param <V> 目标VO类型* @param <P> 原始PO类型* @return VO的分页对象*/public static <V, P> PageDTO<V> empty(Page<P> p){return new PageDTO<>(p.getTotal(), p.getPages(), Collections.emptyList());}/*** 将MybatisPlus分页结果转为 VO分页结果* @param p MybatisPlus的分页结果* @param voClass 目标VO类型的字节码* @param <V> 目标VO类型* @param <P> 原始PO类型* @return VO的分页对象*/public static <V, P> PageDTO<V> of(Page<P> p, Class<V> voClass) {// 1.非空校验List<P> records = p.getRecords();if (records == null || records.size() <= 0) {// 无数据,返回空结果return empty(p);}// 2.数据转换List<V> vos = BeanUtil.copyToList(records, voClass);// 3.封装返回return new PageDTO<>(p.getTotal(), p.getPages(), vos);}/*** 将MybatisPlus分页结果转为 VO分页结果,允许用户自定义PO到VO的转换方式* @param p MybatisPlus的分页结果* @param convertor PO到VO的转换函数* @param <V> 目标VO类型* @param <P> 原始PO类型* @return VO的分页对象*/public static <V, P> PageDTO<V> of(Page<P> p, Function<P, V> convertor) {// 1.非空校验List<P> records = p.getRecords();if (records == null || records.size() <= 0) {// 无数据,返回空结果return empty(p);}// 2.数据转换List<V> vos = records.stream().map(convertor).collect(Collectors.toList());// 3.封装返回return new PageDTO<>(p.getTotal(), p.getPages(), vos);}}
- impl层
@Overridepublic PageDTO<UserVO> queryUsersPage(UserQuery query) {String name = query.getName();Integer status = query.getStatus();//1. 构建查询条件Page<User> page = query.toMpPageDefaultSortByUpdateTimeDesc();Page<User> p = lambdaQuery().like(name != null, User::getUsername, name).eq(status != null, User::getStatus, status).page(page);return PageDTO.of(page, UserVO.class);}
相关文章:
微服务-MybatisPlus下
微服务-MybatisPlus下 文章目录 微服务-MybatisPlus下1 MybatisPlus扩展功能1.1 代码生成1.2 静态工具1.3 逻辑删除1.4 枚举处理器1.5 JSON处理器**1.5.1.定义实体****1.5.2.使用类型处理器** **1.6 配置加密(选学)**1.6.1.生成秘钥**1.6.2.修改配置****…...
【python_将一个列表中的几个字典改成二维列表,并删除不需要的列】
def 将一个列表中的几个字典改成二维列表(original_list,headersToRemove_list):# 初始化一个列表用于存储遇到的键,保持顺序ordered_keys []# 遍历data中的每个字典,添加其键到ordered_keys,如果该键还未被添加for d in original_list:for …...
IDEA的pom.xml显示ignored 的解决办法
问题: idea中创建Maven module时,pom.xml出现ignored。 原因: 相同名称的module在之前被创建删除过,IDEA会误以为新的同名文件是之前删除掉的,将这个新的module的pom.xml文件忽略掉显示ignored. 解决: 在…...
2. 卷积神经网络无法绕开的神——LeNet
卷积神经网络无法绕开的大神——LeNet 1. 基本架构2. LeNet 53. LeNet 5 代码 1. 基本架构 特征抽取模块可学习的分类器模块 2. LeNet 5 LeNet 5: 5 表示的是5个核心层,2个卷积层,3个全连接层.核心权重层:卷积层、全连接层、循环层ÿ…...
【区块链】JavaScript连接web3钱包,实现测试网络中的 Sepolia ETH余额查询、转账功能
审核看清楚了 ! 这是以太坊测试网络!用于学习的测试网络!!! 有关web3 和区块链的内容为什么要给我审核不通过? 别人凭什么可以发! 目标成果: 实现功能分析: 显示账户信…...
关于珞石机器人二次开发SDK的posture函数的算法RX RY RZ纠正 C#
在珞石SDK二次开发的函数钟,获取当前机器人位姿的函数posture函数在输出时会发现数据不正确,与示教器数据不一致。 其中第一个数据正确 第二三各数据为相反 第四五六各数据为弧度制 转换方法为(弧度/PI)*180度 然后发现第四个数据还要加上180度 第五…...
【Three.js基础学习】17.imported-models
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 前言 课程回顾: 如何在three.js 中引入不同的模型? 1. 格式 (不同的格式) https://en.wikipedia.org/wiki/List_of_file_form…...
Spring Bean - xml 配置文件创建对象
类型: 1、值类型 2、null (标签) 3、特殊符号 (< -> < ) 4、CDATA <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema/bea…...
uniapp map组件自定义markers标记点
需求是根据后端返回数据在地图上显示标记点,并且根据数据状态控制标记点颜色,标记点背景通过两张图片实现控制 <mapstyle"width: 100vw; height: 100vh;":markers"markers":longitude"locaInfo.longitude":latitude&…...
Windows:批处理脚本学习
目录 一、第一个批处理文件 1. &&和 | | 2. | 和 & 二、变量 1.传参变量%name 2.初始化变量set命令 3.变量的使用 4.局部变量与全局变量 5.使用环境变量 6.扩充变量语法 三、注释REM和 :: 四:函数 1.定义函数 2.…...
Dav_笔记10:Using SQL Plan Management之4
SQL管理库 SQL管理库(SMB)是驻留在SYSAUX表空间中的数据字典的一部分。它存储语句日志,计划历史记录,SQL计划基准和SQL配置文件。为了允许每周清除未使用的计划和日志,SMB使用自动空间管理。 您还可以手动将计划添加到SMB以获取一组SQL语句。从Oracle Database 11g之前的…...
通过json传递请求参数,如何处理动态参数和接口依赖
嗨,大家好,我是兰若姐姐,今天给大家讲一下如何通过json传递请求参数,如何处理动态参数和接口依赖 1. 使用配置文件和模板 在 test_data.json 中,你可以使用一些占位符或模板变量,然后在运行测试之前&…...
[240727] Qt Creator 14 发布 | AMD 推迟 Ryzen 9000芯片发布
目录 Qt Creator 14 发布Qt Creator 14 版本发布,带来一系列新功能和改进终端用户可通过命令行方式查看此新闻终端用户可通过命令行方式安装软件: AMD 推迟 Ryzen 9000芯片发布 Qt Creator 14 发布 Qt Creator 14 版本发布,带来一系列新功能…...
PLSQL Developer工具查询数据,报错(动态性能表不可访问)
解决的问题: 解决方案: 在配置-首选项-选项,取消勾选“自动统计”,保存之后即可查询数据...
基于 HTML+ECharts 实现智慧交通数据可视化大屏(含源码)
构建智慧交通数据可视化大屏:基于 HTML 和 ECharts 的实现 随着城市化进程的加快,智慧交通系统已成为提升城市管理效率和居民生活质量的关键。通过数据可视化,交通管理部门可以实时监控交通流量、事故发生率、道路状况等关键指标,…...
探索 IT 领域的新宠儿:量子计算
目录 引言:从经典到量子的飞跃 量子计算的基本概念 量子计算的独特优势 量子计算的深度剖析 量子计算的最新进展 量子计算的行业应用前景 面临的挑战与未来展望 结语:迎接量子计算的新时代 引言:从经典到量子的飞跃 在信息技术飞速发…...
TSPNet代码分析
论文《Realigning Confidence with Temporal Saliency Information for Point-Level Weakly-Supervised Temporal Action Localization》的official code分析 论文解读 代码分析 先看看训练过程,执行main if __name__ == __main__:exp = Exp()if exp.config.mode == eval:…...
Ubuntu上安装anaconda创建虚拟环境(各种踩坑版)
之前都是在Windows桌面版进行深度学习的环境部署及训练,今天尝试了一下在Ubuntu上进行环境部署,踩了不少坑,提供一些解决办法给大家避雷。 目录 一、下载和安装anaconda 1. 下载 2. 安装 二、创建虚拟环境 一、下载和安装anaconda 1. …...
DC-5靶机通关
今天我们来学习DC-5靶机!!! 1.实验环境 攻击机:kali2023.2 靶机:DC-5 2.1扫描网段 2.2扫描端口 这里后面这俩端口有点似曾相识啊,在dc3里面好像见过,那咱们给这两个端口来个更详细的扫描&…...
AI学习记录 -使用react开发一个网页,对接chatgpt接口,附带一些英语的学习prompt
实现了如下功能(使用react实现,原创) 实现功能: 1、对接gpt35模型问答,并实现了流式传输(在java端) 2、在实际使用中,我们的问答历史会经常分享给他人,所以下图的 copy …...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...
全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...
最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
