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

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 马程序员2024最新SpringCloud微服务开发与实战 个人学习心得、踩坑、与bug记录Day1最快 最全(1)

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

这是我的 github https://github.com/Qiuner ⭐️

gitee https://gitee.com/Qiuner 🌹

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

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

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静态工具练习 没有给出修改后的代码 但我这里写了

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

Day 1 MyBatis学习

原理

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

MyBatisPlus配置文件

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

  • 这个黄色是无效的意思

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.po
  global-config:
    db-config:
      id-type: assign_id

条件构造器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):降序排序,根据指定的列进行降序排序。

  • lambda使用获取函数的方式来实现避免硬编码,通过反射机制
@Test
    void testLambdaQueryWrapper() {
        // 1.构建条件 WHERE username LIKE "%o%" AND balance >= 1000
        QueryWrapper<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很快但占用了一部分业务层逻辑

理解

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

Service接口

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

  • 使用单元测试模仿Control层

@Autowired处爆红

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

重点
  • 这里代码写的很巧妙,代码的目的是将User Service交给Spring自动装配
@Autowired
    private  IUserService userService;
  • 但这种做法是spring所不推荐的

  • 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层使用

  • 使用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.

  • 这个报错是项目端口好已经被占用的报错
  • 打开cmd窗口 输入
netstat -ano | findstr :8080

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

  • 诶个突突了
  • 还不行就 这个是关闭所有niginx
taskkill /F /IM nginx.exe > nul

用到的请求参数

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

Lambda

control

server

@Override
    public 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着实强大

批量新增

@Test
    void 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倍
    @Test
    void 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变成这样

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

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=true
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: 123456
  • 最后加上&rewriteBatchedStatements=true
  • 这样就能实现批量插入


马程序员2024最新SpringCloud微服务开发与实战 个人学习心得、踩坑、与bug记录Day1最快 最全(2):https://developer.aliyun.com/article/1548597

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
8天前
|
JSON Java 测试技术
SpringCloud2023实战之接口服务测试工具SpringBootTest
SpringBootTest同时集成了JUnit Jupiter、AssertJ、Hamcrest测试辅助库,使得更容易编写但愿测试代码。
37 3
|
16天前
|
运维 NoSQL Java
后端架构演进:微服务架构的优缺点与实战案例分析
【10月更文挑战第28天】本文探讨了微服务架构与单体架构的优缺点,并通过实战案例分析了微服务架构在实际应用中的表现。微服务架构具有高内聚、低耦合、独立部署等优势,但也面临分布式系统的复杂性和较高的运维成本。通过某电商平台的实际案例,展示了微服务架构在提升系统性能和团队协作效率方面的显著效果,同时也指出了其带来的挑战。
55 4
|
1月前
|
Dubbo Java 应用服务中间件
Dubbo学习圣经:从入门到精通 Dubbo3.0 + SpringCloud Alibaba 微服务基础框架
尼恩团队的15大技术圣经,旨在帮助开发者系统化、体系化地掌握核心技术,提升技术实力,从而在面试和工作中脱颖而出。本文介绍了如何使用Dubbo3.0与Spring Cloud Gateway进行整合,解决传统Dubbo架构缺乏HTTP入口的问题,实现高性能的微服务网关。
|
2月前
|
Dubbo Java 应用服务中间件
微服务框架Dubbo环境部署实战
微服务框架Dubbo环境部署的实战指南,涵盖了Dubbo的概述、服务部署、以及Dubbo web管理页面的部署,旨在指导读者如何搭建和使用Dubbo框架。
223 17
微服务框架Dubbo环境部署实战
|
2月前
|
运维 持续交付 API
深入理解并实践微服务架构:从理论到实战
深入理解并实践微服务架构:从理论到实战
133 3
|
2月前
|
自然语言处理 Java 网络架构
解锁跨平台微服务新纪元:Micronaut与Kotlin联袂打造的多语言兼容服务——代码、教程、实战一次打包奉送!
【9月更文挑战第6天】Micronaut是一款轻量级、高性能的Java框架,适用于微服务开发。它支持Java、Groovy和Kotlin等多种语言,提供灵活的多语言开发环境。本文通过创建一个简单的多语言兼容服务,展示如何使用Micronaut及其注解驱动特性实现REST接口,并引入国际化支持。无论是个人项目还是企业应用,Micronaut都能提供高效、一致的开发体验,成为跨平台开发的利器。通过简单的配置和代码编写,即可实现多语言支持,展现其强大的跨平台优势。
52 3
|
2月前
|
运维 监控 持续交付
深入浅出:微服务架构的设计与实战
微服务,一个在软件开发领域如雷贯耳的名词,它代表着一种现代软件架构的风格。本文将通过浅显易懂的语言,带领读者从零开始了解微服务的概念、设计原则及其在实际项目中的运用。我们将一起探讨如何将一个庞大的单体应用拆分为灵活、独立、可扩展的微服务,并分享一些实践中的经验和技巧。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供新的视角和深入的理解。
80 3
|
2月前
|
安全 Java 开发者
强大!Spring Cloud Gateway新特性及高级开发技巧
在微服务架构日益盛行的今天,网关作为微服务架构中的关键组件,承担着路由、安全、监控、限流等多重职责。Spring Cloud Gateway作为新一代的微服务网关,凭借其基于Spring Framework 5、Project Reactor和Spring Boot 2.0的强大技术栈,正逐步成为业界的主流选择。本文将深入探讨Spring Cloud Gateway的新特性及高级开发技巧,助力开发者更好地掌握这一强大的网关工具。
222 6
|
3月前
|
消息中间件 缓存 Kafka
go-zero微服务实战系列(八、如何处理每秒上万次的下单请求)
go-zero微服务实战系列(八、如何处理每秒上万次的下单请求)
|
3月前
|
缓存 NoSQL Redis
go-zero微服务实战系列(七、请求量这么高该如何优化)
go-zero微服务实战系列(七、请求量这么高该如何优化)