黑马程序员2024最新SpringCloud微服务开发与实战 个人学习心得、踩坑、与bug记录Day1

你好,我是Qiuner. 为记录自己编程学习过程和帮助别人少走弯路而写博客 这是我的 github gitee

如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的 😄 (^ ~ ^)

想看更多 那就点个关注吧 我会尽力带来有趣的内容

2024黑马程序员 SpringCloud微服务开发与实战,Java黑马商城项目微服务实战开发(涵盖MybatisPlus、Docker、MQ、ES、Redis高级等)的个人学习心得与代码记录!Day1

SpringCloud微服务课程导学_哔哩哔哩_bilibili

官方文档 ⁡‬⁣‍‍⁣⁣⁤‌⁢‌⁡⁢‍‍‍⁤⁡⁤‬⁣‌⁡⁣⁡⁤‌‌⁣⁣⁢‌‌‌⁣⁡⁣‍day01-MybatisPlus - 飞书云文档 (feishu.cn)

我这份文档是对官方文档的补充,比如官方文档没有记载P10的请求参数,这种东西没有什么营养,又容易漏写些东西,因此我记录了下来,您可以通过文字的目录快捷需要的东西

{
“balance”: 2000,
“info”: “{“age”:21}”,
“password”: “123”,
“phone”: “13899776876”,
“username”: “WangWu”
}

还记录了一些我自己开发中遇到的bug,如果您也遇到了可以直接地解决 不用去网上找了半天,也没能找到合适的解决方案

又比如说 P15 DB静态工具练习 没有给出修改后的代码 但我这里写了

还有一些我对技术点的理解

image-20240423154921490

image-20240423154949853

image-20240423155123462

Day 1 MyBatis学习

image-20240423160233752

image-20240423160243242

image-20240423161155352

原理

image-20240423161422522

  • 约定大于配置的原理 导致能使用它的代码
常见注解及使用场景

image-20240423161738703

image-20240423164013092

MyBatisPlus配置文件

  • 如果全局配置与局部配置冲突 会先使用局部配置

image-20240423164236156

image-20240423164430532

  • 这个黄色是无效的意思

java.lang.IllegalStateException: Failed to load ApplicationContext

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration’: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.boot.context.properties.ConfigurationPropertiesBindException: Error creating bean with name ‘mybatis-plus-com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties’: Could not bind properties to ‘MybatisPlusProperties’ : prefix=mybatis-plus, ignoreInvalidFields=false, ignoreUnknownFields=true; nested exception is org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under ‘mybatis-plus.global-config.db-config’ to com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig

  • 换成这行代码就可以了
mybatis-plus:type-aliases-package: com.itheima.mp.domain.poglobal-config:db-config:id-type: assign_id

image-20240423165823905

条件构造器wrapper

QueryWrapper 是 MyBatis Plus 中的一个查询条件封装器,用于构建 SQL 查询条件。它提供了一种更加便捷和灵活的方式来构建复杂的查询条件,而不需要直接编写 SQL 语句。

通过 QueryWrapper,你可以在 Java 代码中以面向对象的方式构建查询条件,而不必担心 SQL 注入等安全问题,同时也提高了代码的可读性和可维护性。

以下是 QueryWrapper 的一些常用方法和用法:

  1. eq(String column, Object val):等于查询,指定列的值等于给定的值。
  2. ne(String column, Object val):不等于查询,指定列的值不等于给定的值。
  3. gt(String column, Object val):大于查询,指定列的值大于给定的值。
  4. lt(String column, Object val):小于查询,指定列的值小于给定的值。
  5. ge(String column, Object val):大于等于查询,指定列的值大于等于给定的值。
  6. le(String column, Object val):小于等于查询,指定列的值小于等于给定的值。
  7. like(String column, String likeValue):模糊查询,指定列的值类似于给定的值。
  8. in(String column, Collection<?> coll):包含查询,指定列的值在给定的集合中。
  9. orderByAsc(String… columns):升序排序,根据指定的列进行升序排序。
  10. orderByDesc(String… columns):降序排序,根据指定的列进行降序排序。

image-20240423170049539

image-20240423170259137

  • lambda使用获取函数的方式来实现避免硬编码,通过反射机制
    @Testvoid testLambdaQueryWrapper() {// 1.构建条件 WHERE username LIKE "%o%" AND balance >= 1000QueryWrapper<User> wrapper = new QueryWrapper<>();wrapper.lambda().select(User::getId, User::getUsername, User::getInfo, User::getBalance).like(User::getUsername, "o").ge(User::getBalance, 1000);// 2.查询List<User> users = userMapper.selectList(wrapper);users.forEach(System.out::println);}
  • 条件构造器 的缺点就是将持久层和业务层混杂在一起了

自定义SQL

  • 为了解决MP编写SQL很快但占用了一部分业务层逻辑

image-20240423172804717

image-20240423173035222

理解

  • 自定义SQL是语法糖,很好的将业务层和持久层分开来

Service接口

image-20240423193238509

  • 这里的Service层,原本要写下图这样的业务,但是有了MP就可以写,直接调用

image-20240423201544735

image-20240423201649104

  • 使用单元测试模仿Control层

@Autowired处爆红

image-20240423195112370

image-20240423195805813

image-20240423195816284

案例 基于Restful风格实现下列接口(有重点)

image-20240423205029193

重点
  • 这里代码写的很巧妙,代码的目的是将User Service交给Spring自动装配

  •     @Autowiredprivate  IUserService userService;
    
    • 但这种做法是spring所不推荐的

image-20240424095755311

  • springboot推荐使用构造函数注入
   public UserController(IUserService userService) {this.userService = userService;}

但太繁琐了 于是采用

@Api(tags = "用户管理接口")
@RequiredArgsConstructor
@RestController
@RequestMapping("users")
public class UserController {private final IUserService userService;
  • 使用了@RequiredArgsConstructor注解,这是Lombok库提供的功能之一。它会为带有final关键字的成员变量生成构造函数参数,并在构造函数中进行初始化。因此,在这种情况下,不需要使用@Autowired注解来进行依赖注入,因为Lombok会自动为userService生成一个构造函数参数,并且在初始化UserController对象时将其注入。

  • 这种方式的好处是代码更简洁,不需要显式地声明@Autowired,而且对于final成员变量的使用更加规范,因为它们只能在构造函数中被初始化一次。

  • 使用了mp之后 简单service层代码能直接在控制层使用,简单的mapper层代码能直接在service层使用

image-20240424141722453

  • 使用alt加8弹出服务窗口
端口被占用报错Web server failed to start. Port 8080 was already in use.Identify and stop the process that’s listening on port 8080 or configure this application to listen on another port.

image-20240424141854135

  • 这个报错是项目端口好已经被占用的报错

  • 打开cmd窗口 输入

netstat -ano | findstr :8080

image-20240424142419687

  • 这个意思是还有进程和8080通信
taskkill /PID 6176 /F
taskkill /PID 5776 /F
  • 如果关掉后在运行关掉8080命令,那是有东西在一直重启通信,应该是你的苍穹外卖、黑马点评什么的没有关闭

  • 打开任务管理器

    image-20240424144101146

  • 诶个突突了

  • 还不行就 这个是关闭所有niginx

    taskkill /F /IM nginx.exe > nul
    

用到的请求参数

{"balance": 2000,"info": "{\"age\":21}","password": "123","phone": "13899776876","username": "WangWu"
}

Lambda

image-20240424165812569

control

image-20240424163928230

server

  @Overridepublic List<User> queryUsers(String name, Integer status, Integer minBalance, Integer maxBalance) {return   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).list();}
  • mp着实强大

批量新增

image-20240424165841869

  @Testvoid testSaveOneByOne() {long b = System.currentTimeMillis();for (int i = 1; i <= 100000; i++) {userService.save(buildUser(i));}long e = System.currentTimeMillis();System.out.println("耗时:" + (e - b));}// 下面这种数据能够提升10倍@Testvoid testSaveBatch() {// 准备10万条数据List<User> list = new ArrayList<>(1000);long b = System.currentTimeMillis();for (int i = 1; i <= 100000; i++) {list.add(buildUser(i));// 每1000条批量插入一次if (i % 1000 == 0) {userService.saveBatch(list);list.clear();}}long e = System.currentTimeMillis();System.out.println("耗时:" + (e - b));}private User buildUser(int i) {User user = new User();user.setUsername("user_" + i);user.setPassword("123");user.setPhone("" + (18688190000L + i));user.setBalance(2000);user.setInfo("{\"age\": 24, \"intro\": \"英文老师\", \"gender\": \"female\"}");user.setCreateTime(LocalDateTime.now());user.setUpdateTime(user.getCreateTime());return user;}

在这两种处理方案中,第一个 testSaveOneByOne 方法是逐个保存每个用户的数据,而第二个 testSaveBatch 方法是批量保存用户数据。

下面是为什么批量保存会更快的一些原因:

  1. 减少数据库交互次数: 在逐个保存用户数据的方法中,每次保存都需要与数据库进行一次交互,包括建立连接、发送请求、执行操作、关闭连接等,这些操作会产生较大的开销。而批量保存可以将多条数据打包成一次请求发送到数据库,减少了大量的数据库交互次数,从而节省了时间。
  2. 减少事务开销: 在数据库中,每次保存操作通常都会包含一个事务。在逐个保存的方法中,每次保存都会启动一个新的事务,这会增加事务管理的开销,包括事务的开始、提交和回滚等操作。而批量保存可以将多个保存操作合并到一个事务中,减少了事务管理的开销。
  3. 优化数据库写入性能: 数据库在处理批量数据插入时通常会有一些优化措施,例如批量插入语句的执行计划优化、预分配内存空间、减少日志记录等,这些优化可以提高数据库写入性能,从而加快批量保存的速度。

批量保存数据可以减少数据库交互次数、减少事务开销,并且可以享受数据库的写入性能优化,因此通常会比逐个保存数据的方式更快。

想要实现真正最快最好的批量插入 的将插入的SQL变成这样

image-20240424170528146

  • 这样虽然写了很多数据但对数据库来说只是一个插入操作

MySQL的客户端连接参数中有这样的一个参数:rewriteBatchedStatements。顾名思义,就是重写批处理的statement语句。参考文档:

https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-connp-props-performance-extensions.html#cj-conn-prop_rewriteBatchedStatements

这个参数的默认值是false,我们需要修改连接参数,将其配置为true

修改项目中的application.yml文件,在jdbc的url后面添加参数&rewriteBatchedStatements=true:

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: rootpassword: 123456
  • 最后加上&rewriteBatchedStatements=true

  • 这样就能实现批量插入

image-20240424171008784

代码生成工具 MybatisPlus

image-20240424204445431

讲师推荐的插件安装后 导航栏没有出现Other

image-20240424205700601

image-20240424205711867

  • 这是因为你的idea版本比较新

image-20240424205800326

  • 新版集成到这里了

image-20240424210959292

  • 这里存在的问题,我也不知道怎么办 给项目加了JDBC的依赖也不行
  • 我的解决方法是换成下面这个小蓝鸟

image-20240424213336323

小蓝鸟怎么用 看我的另一篇文章

image-20240424214053132

image-20240424214137429

  • 选择路径和其他配置项

静态工具

image-20240424214938267

image-20240424215621280

image-20240426165236277

静态工具使用报错 The server time zone value ‘�й���׼ʱ��’ is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.

问题描述

image-20240426163014685

  • 数据库连接没有问题,JDBC依赖也导入了
     <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.28</version> <!-- JDBC依赖 --></dependency>
  • 但显示

解决办法
  • 这是你没有设置时区 下面设置的是中国的时区 这里时区要设置成自己国家的 不然生成不出来
jdbc:mysql://localhost:3306/mp?serverTimezone=Asia/Shanghai

静态Db

image-20240426170437182

image-20240426171439640

依赖注入的核心思想是将类的依赖关系从类本身解耦,使得类更加灵活、可测试和可维护。

两个类相互注入可能会导致循环依赖的问题。循环依赖指的是两个或多个类之间存在直接或间接的依赖关系,使得它们无法被实例化。例如,类 A 依赖于类 B,而类 B 又依赖于类 A,这样的情况就会导致循环依赖。

循环依赖可能会导致以下问题:

  1. 编译错误或运行时异常:在解析类之间的依赖关系时,编译器或运行时容器可能会无法确定类的实例化顺序,导致编译错误或运行时异常。
  2. 性能问题:循环依赖可能导致对象的创建和初始化过程变得复杂,影响程序的性能。
  3. 可维护性问题:循环依赖会增加代码的复杂性,降低代码的可读性和可维护性。

为了避免循环依赖,可以考虑以下几种方法:

  • 重构类设计:尽量避免直接相互依赖,可以考虑通过接口、抽象类或事件总线等方式来解耦类之间的关系。
  • 使用延迟初始化:在需要时才初始化对象,避免在类的构造函数中直接注入其他类的实例。
  • 使用依赖注入容器:一些依赖注入容器(如Spring)提供了解决循环依赖的机制,可以通过配置或注解来处理循环依赖的情况。

为什么要在DTO中加上VO

  1. 数据传输的灵活性:通过将地址信息作为 AddressVO 类独立出来,使得在用户表单实体 UserFormDTO 中可以通过引用 AddressVO 类来包含多个收货地址。这样设计使得用户表单实体可以轻松地与收货地址相关联,同时避免了将地址信息直接嵌入到用户表单实体中的复杂性。
  2. 代码复用性:通过将收货地址信息抽象为 AddressVO 类,可以在系统的其他地方复用这个类,例如在订单模块中也可能需要使用收货地址信息。这样可以避免代码重复,并提高了系统的可维护性。
  3. 可扩展性:由于地址信息被抽象成了单独的类,如果将来需要添加更多与收货地址相关的字段或功能,可以直接在 AddressVO 类中进行扩展,而不需要修改用户表单实体 UserFormDTO。这样可以减少对现有代码的影响,降低了系统的耦合度。
  4. 清晰的数据结构:将用户表单实体和收货地址实体分开设计,使得数据结构更加清晰明了,易于理解和维护。同时,使用

根据用户查询id处爆红

image-20240427090309522

image-20240427090324305

  • 加上上面这个即可
    public void setAddresses(List<AddressVO> addressVOList) {// 在这里将收货地址列表设置到用户VO中// 例如,可以直接将地址列表赋值给用户VO中的地址属性this.addressVOList = addressVOList;}
  • 这样就避免了相互依赖

  • 互相依赖有不少点可以说的 等过些时候我开篇文详细说说

批量查询

@Override
public List<UserVO> queryUserAndAddressByIds(List<Long> ids) {return List.of();
}
    @Overridepublic List<UserVO> queryUserAndAddressByIds(List<Long> ids) {// 1 查询用户List<User> users = listByIds(ids);if (CollUtil.isEmpty(users)) {return Collections.emptyList();}// 2 查询地址 获取用户集合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();// 3 处理voList<UserVO> userVOS = BeanUtil.copyToList(users, UserVO.class);userVOS.forEach(userVO -> {List<AddressVO> addressVOS = BeanUtil.copyToList(addresses.stream().filter(address -> address.getUserId().equals(userVO.getId())).collect(Collectors.toList()),AddressVO.class);userVO.setAddresses(addressVOS);});return userVOS;}
  • 这是我写的 和老师有所出入 uu们可以自己看看

逻辑删除

image-20240427092812062

image-20240427100556459

枚举处理器

image-20240427100633754

  • mybatis实现了类型的int枚举类型转换

image-20240427100736878

  • MP的扩展

报错ava.lang.IllegalArgumentException: Could not find @EnumValue in Class: com.itheima.mp.enums.UserStatus. at com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler.lambda$new$0(MybatisEnumTypeHandler.java:65) ~[mybatis-plus-core-3.5.3.1.jar:3.5.3.1]

image-20240427101846196

image-20240427101813595

  • 这里官方文档给的代码有错
package com.itheima.mp.enums;import com.baomidou.mybatisplus.annotation.EnumValue;
import lombok.Getter;@Getter
public enum UserStatus {NORMAL(1, "正常"),FREEZE(2, "冻结");@EnumValueprivate final int value;private final String desc;UserStatus(int value, String desc) {this.value = value;this.desc = desc;}
}

image-20240427102047151

@EnumValue@JsonValue 是两个注解,通常用于在 Java 枚举类中定义枚举值的序列化和反序列化方式。

  1. @EnumValue:

    • 用于标识枚举类中表示数据库存储值的字段。
    • 在 MyBatis Plus 中,当将枚举值持久化到数据库时,会使用被 @EnumValue 注解标记的字段的值。这个值应该是枚举类中定义的一个整数字段,通常用来表示数据库中的实际存储值。
  2. @JsonValue:

    • 用于标识枚举类中表示枚举值描述的字段。

    • 在序列化枚举值时,会使用被 @JsonValue 注解标记的字段的值作为 JSON 字符串的值。

JSON处理器

  • 这里在官方文档中记载的很详细
  • 因为数据库中的数据是json格式的数据而在实体类中确实String类型 为了解决这件事,所以使用JSON处理器

image-20240427102459783

  • 使用TableField

image-20240427102553227

MybatisPlus 内部拦截器

image-20240427111938462

实现分页查询

image-20240427112056802

image-20240427112612245

image-20240427112653238

通用分页实体

image-20240428074959342

image-20240428075650992

image-20240428075658938

  • 这里因为分页查询是通用的 因此封装起来

通用分页实体和MP转换

PageQueryMybatisPlusPage之间转换的过程比较麻烦的

image-20240428082658591

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

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

相关文章

FPGA高端项目:FPGA帧差算法多目标图像识别+目标跟踪,提供11套工程源码和技术支持

目录 1、前言免责声明 2、相关方案推荐FPGA帧差算法单个目标图像识别目标跟踪 3、详细设计方案设计原理框图运动目标检测原理OV5640摄像头配置与采集OV7725摄像头配置与采集RGB视频流转AXI4-StreamVDMA图像缓存多目标帧差算法图像识别目标跟踪模块视频输出Xilinx系列FPGA工程源…

【c++】cpp类的继承

目录 &#xff08;1&#xff09;继承概念与语法 &#xff08;2&#xff09;派生类的访问控制 &#xff08;3&#xff09;继承中的构造和析构 1.类型兼容性原则 2.继承中的构造析构调用原则 3.继承与组合混搭下构造和析构调用原则 &#xff08;4&#xff09;同名成员(函数…

slice

最重要的一张图 endlessSummer :summer[:5]//这是这张图真正厉害的地方为什么向函数传递slice允许在函数内部修改底层数组的元素&#xff1f; 因为slice值包含指向第一个sllice元素的指针&#xff0c;传入的slice允许在函数内部修改底层数组的元素。 复制的slice只是对底层的…

LabVIEW与Modbus协议的多点温度监控系统

LabVIEW与Modbus协议的多点温度监控系统 随着工业自动化和智能化水平的不断提升&#xff0c;对于现场监控技术的需求日益增长。开发了一种基于LabVIEW与Modbus协议的多点温度监控系统&#xff0c;实现高效、准确的温度数据采集、处理和显示&#xff0c;以及数据存储功能&#…

TCP/IP协议族中的TCP(一):解析其关键特性与机制

⭐小白苦学IT的博客主页⭐ ⭐初学者必看&#xff1a;Linux操作系统入门⭐ ⭐代码仓库&#xff1a;Linux代码仓库⭐ ❤关注我一起讨论和学习Linux系统 前言 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是一种面向连接的、可靠的、基于字…

牛客社区帖子分页显示实现

下图是前端分页的组件&#xff1a; 下面是对应的静态html页面&#xff0c;每一个方块&#xff0c;都是一个a标签&#xff0c;可以点击&#xff0c;执行的链接是/community/index&#xff0c;GET请求&#xff0c;拼接的参数是current&#xff0c;也就是pageNum&#xff0c;只需…

力扣HOT100 208. 实现Trie(前缀树)

解题思路&#xff1a; class Trie {private Trie[] children; // 存储子节点的数组private boolean isEnd; // 记录是否为单词结尾public Trie() {children new Trie[26]; // 数组大小为26&#xff0c;代表26个小写字母isEnd false;}public void insert(String word) {Trie …

智能小程序 Ray 开发实践——基础内容组件 Text 和 Icon 介绍

Text 文本内容。 导入 import { Text } from ray-js/ray; Props 属性类型默认值说明支持平台classNamestring样式名涂鸦、微信selectablebooleanfalse文本是否可选涂鸦、微信onClick(e: { type: click }) > voidfalse点击事件涂鸦、微信 示例代码 基本使用 import Re…

【yolov8算法道路-墙面裂缝检测-汽车车身凹陷-抓痕-损伤检测】

yolo算法道路-墙面裂缝检测-汽车车身凹陷-抓痕-损伤检测 1. yolo算法裂缝检测-汽车车身凹陷-抓痕检测-汽车车身损伤检测2. yolo房屋墙面路面裂缝-发霉-油漆脱落-渗水-墙皮脱落检测3. 水泥墙面裂缝检测 YOLOv8算法是一种先进的目标检测技术&#xff0c;它基于YOLO系列算法的改进…

探索矿业数字化平台:实现智能化采矿与管理

随着信息技术的迅猛发展&#xff0c;矿业领域也在逐步实现数字化转型。数字化平台的出现为矿业企业带来了更高效、更智能的采矿与管理方式。本文将探讨矿业数字化平台的意义、特点以及未来发展方向。 ### 1. 数字化平台的意义 传统的矿业生产和管理方式存在诸多问题&#xff…

Python赋值运算符

目录 赋值运算符 将值赋给变量&#xff1a; 做加法运算之后完成赋值&#xff1a; 做减法运算之后完成赋值&#xff1a;- 做乘法运算之后完成赋值&#xff1a;* 做除法运算之后完成赋值&#xff1a;/ 做整除运算之后完成赋值&#xff1a;// 做幂次运算之后完成赋值&#xff1a;*…

Pytorch 计算深度模型的大小

计算模型大小的方法 卷积 时间复杂度 与 空间复杂度 的计算方式&#xff1a; C 通道的个数&#xff0c;K卷积核大小&#xff0c;M特征图大小&#xff0c;C_l-1是输入通道的个数&#xff0c;C_l是输出通道的个数 1 模型大小 MB 计算模型的大小的原理就是计算保存模型所需要…

在MySQL中isnull()函数不能作为替代null值!

在MySQL中isnull()函数不能作为替代null值&#xff01; 如下&#xff1a; 首先有个名字为business的表&#xff1a; SELECT ISNULL(business_name,no business_name) AS bus_isnull FROM business WHERE id2 直接运行就会报错&#xff1a; 错误代码&#xff1a; 1582 Incor…

cuDNN-Graph API

Graph API 为了适应越来越重要的算子融合需求&#xff0c;cuDNN8.0版本引入了Graph API&#xff0c;以提供更灵活的API接口。Graph API提供一个声明式的编程模型&#xff0c;此模型将计算操作描述为计算图。 用户首先需要构建操作图。从高层面来说&#xff0c;用户其实是在描…

Swift - Playground

文章目录 Swift - Playground1. 新建Playground2. View3. 图片4. ViewController5. Playground - 多Page6. 注释6.1 Playground的注释支持markup语法&#xff08;与markdown相似&#xff09;6.1.1 语法 Swift - Playground Playground可以快速预览代码效果&#xff0c;是学习语…

设计模式(九):组合模式

设计模式&#xff08;九&#xff09;&#xff1a;组合模式 1. 组合模式的介绍2. 组合模式的类图3. 组合模式的实现 1. 组合模式的介绍 组合模式&#xff08;Composite Pattern&#xff09;属于结构型模式&#xff0c;是用于把一组相似的对象当作一个单一的对象。 组合模式依据…

基于SpringBoot+Vue校园二手交易系统的设计与实现

系统介绍 自从新冠疫情爆发以来&#xff0c;各个线下实体越来越难做&#xff0c;线下购物的人也越来越少&#xff0c;随之带来的是一些不必要的浪费&#xff0c;尤其是即将毕业的大学生&#xff0c;各种用品不方便携带走导致被遗弃&#xff0c;造成大量的浪费。本系统目的就是让…

基于Spring Boot的旅游管理系统设计与实现

基于Spring Boot的旅游管理系统设计与实现 开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/idea 系统部分展示 前台浏览管理界面图&#xff0c;通过内容列表可以获取网…

PotatoPie 4.0 实验教程(41) —— FPGA实现RISC-V 扩展 GPIO UART Timer功能

TD工程介绍 我们提供的TD工程里的RISC-V核默认就开启了GPIO UART扩展&#xff0c;可以看到还有SPI和I2C扩展。因此后面的实验中TD的工程我们基本不怎么修改TD的内容&#xff0c;只需要修改TD工具中Soc_Top.v文件中的TCM0_INITFILE为FD生成的固件名称即可&#xff0c;主要修我以…

【mysql】mysql命令使用大全,你想要的都在这里

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…