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

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用版 2核4GB 50GB
简介: 马程序员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
目录
相关文章
|
1天前
|
消息中间件 负载均衡 Java
最容易学会的springboot gralde spring cloud 多模块微服务项目
最容易学会的springboot gralde spring cloud 多模块微服务项目
|
1天前
|
设计模式 弹性计算 监控
后端开发中的微服务架构:优势、挑战与实施策略
在现代软件开发中,微服务架构已成为一种流行的设计模式,特别是在后端开发领域。该架构风格通过将应用程序分解为一组小型、松耦合的服务,旨在提升可维护性、可扩展性和敏捷性。本文深入探讨了微服务架构的关键优势,面临的主要挑战,以及成功实施微服务的策略。通过引用业界案例和最新研究,文章提供了对微服务架构综合理解的视角,并讨论了如何在不断变化的技术环境中保持其有效性。
|
1天前
|
设计模式 安全 持续交付
探索微服务架构下的后端开发实践
在现代软件开发领域,微服务架构已成为一种流行的设计模式,它通过将应用程序分解为一组小的服务来促进敏捷开发和可扩展性。本文深入探讨了微服务架构的核心概念、技术选型、数据一致性挑战以及安全性考虑,旨在为后端开发人员提供一份全面的微服务开发指南。文章结合最新的研究成果和业界最佳实践,分析了微服务架构的优势和面临的挑战,并提出了相应的解决方案。读者将了解到如何在实际项目中应用微服务原则,以及如何克服实施过程中的技术和组织障碍。
|
2天前
|
监控 Java 开发者
使用Java开发微服务架构的挑战与解决方案
使用Java开发微服务架构的挑战与解决方案
|
2天前
|
消息中间件 监控 API
后端开发中的微服务架构实践与挑战
在现代软件开发中,微服务架构因其灵活性和可扩展性而受到广泛推崇。本文将深入探讨微服务的核心概念、实施步骤以及面临的技术挑战,同时结合最新的研究数据和行业案例,分析微服务在实际应用中的表现和优化策略,为后端开发人员提供一份实用的指南。
6 0
|
2天前
|
存储 设计模式 监控
后端开发中的微服务架构实践与挑战
在数字化时代背景下,微服务架构作为现代软件工程的典范,被广泛应用于后端开发领域。本文将深入探讨微服务架构的核心概念、实施策略及其面临的主要挑战,同时提供一系列针对性的解决方案和最佳实践。通过引用最新的研究成果和行业案例,文章旨在为后端开发者提供一个全面的微服务架构指南,帮助他们在构建和维护复杂系统时做出明智的决策。
8 1
|
2天前
|
负载均衡 Java 开发者
Spring Cloud微服务架构中的配置管理与服务发现
Spring Cloud微服务架构中的配置管理与服务发现
|
10小时前
|
消息中间件 NoSQL Java
使用Java构建可扩展的微服务架构
使用Java构建可扩展的微服务架构
|
1天前
|
监控 Java 微服务
使用Spring Boot构建微服务架构
使用Spring Boot构建微服务架构
|
1天前
|
负载均衡 监控 Java
Java中的可扩展微服务架构
Java中的可扩展微服务架构