学习笔记14——Springboot以及SSMP项目

news2025/3/17 14:02:45

SpringBoot

  • Springboot项目

    • IDEA2023只能创建jdk17和21的springboot项目解决 - 嘿嘿- - 博客园 (cnblogs.com)
    • 解决IntelliJ IDEA2022.03创建包时,包结构不自动分级显示的问题_idea建包不分级-CSDN博客
    • IDEA调出maven项目窗口_idea maven窗口-CSDN博客
  • 相比于spring的特点

    • parent:定义了几百个不冲突的版本信息和坐标,继承parent模块,直接使用就可以避免多个依赖版本冲突

      <dependencyManagement>
              <dependencies>
                  <dependency>
                      <groupId>org.springframework.boot</groupId>
                      <artifactId>spring-boot-dependencies</artifactId>
                      <version>${spring-boot.version}</version>
                      <type>pom</type>
                      <scope>import</scope>
                  </dependency>
              </dependencies>
          </dependencyManagement>
      
    • starter:将一些常用的组合依赖坐标打包,简化每次配置xml的难度

    • 引导类:之前的main就是加载配置类springconfig,现在的入口直接就是一个配置类@SpringBootApplication,启动后创建并初始化spring容器,并默认扫描当前配置类所在包以及子包

    • 内嵌Tomcat:将tomcat服务器以对象的形式在spring容器运行起来,然后程序(别的对象)要在tomcat中运行

      		<dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-web</artifactId>
              </dependency>
      
  • 配置、属性的修改【properities、yml、yaml】和不同读取【定义对象挨个value接收、用Environment对象整个接收,定义同样结构的对象@ConfigurationProperties 接收】

    • Common Application Properties (spring.io)

      # 对Application启动的容器中的tomcat属性进行修改
      server.port=80
      # 如果对应的包没有导入,那么这里的properities设置也会无效
      
    • 三种配置格式(properties > yml > ymal):共存叠加并相互覆盖,是所有配置的并集

      likes:
      	- game
      	- music
      	- sleep
       likes: [game,music,sleep]
      
    • 在这里插入图片描述

    • 在这里插入图片描述

  • 读取

    # 取变量值
    @Value("${country}")
    private String country;
    
    # 取对象的属性
    @Value("${User.name}")
    private String name;
    
    @Value("${likes[1]}")
    private String likes1;
    
    # 遇到数组用中括号
    @Value("${User[1].age}")
    private String age1;
    
  • 解决yaml的数据相互引用

    baseDir: c:\windows
    tempDir: ${baseDir}\temp
    
    # 转义\为制表位,加上双引号
    tempDir: "${baseDir}\temp"
    
  • 一次性加载到Environment对象中,不需要每次新建对象接收

    # 将属性数据封装成对象,通过Autowired自动装配
    
    @Autowired
    private Environment env;
    
  • 主流加载:对应的数据加载到对应的类中

    • 创建一个类,对应于ymal中的封装数据,给出set和get方法

    • 将该类定义为component

    • 指定加载yaml中的哪个数据

    • 该对象的属性得到对应的值

    • server就是这种类型

      @Component
      @ConfigurationProperties("datasource")
      

整合第三方配置

  1. junit【不需要勾选】

    • Test类需要加@SpringBootTest

    • 在Test类中直接装在对象进行测试

    • 两种情况

      • Test先在自己所属包范围下(上下两个层级都找)配置类,找到就装载
        • 如果test类和启动类不在同一个包下,那么就需要@SpringBootTest(classes = SpringbootJunitApplication.class)告诉配置类在哪里
  2. Mybatis【需要勾选mybatis framework 和 MySQL driver】

    • 导入包
    • 配置信息 【和tomcat一样,到这一步已经有了tomcat-spring/mybatis-spring对象了】
    • 用@Mapper来映射dao层
  3. Mybatis-plus

    • 导入包,可以手动去mvn网站去添加

    • 配置信息

    • Mapper映射(dao层可以简写,用BaseMapper映射到具体库中的表上)

      @Mapper
      public interface BookDao extends BaseMapper<Book> {
      }
      
      # 如果对象叫Book,但是表不叫这个名,就需要配置,就会默认在对象名字前加tbl找到表
      mybatis-plus:
        global-config:
          db-config:
            table-prefix: tbl_
      
  4. Druid【配合Mybatis使用】

    • 导入对应start包
    spring:
      datasource:
        druid:
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://localhost:3306/test
          username: root
          password: 123456
    

SSM结构流程

  • 深入剖析 MVC 模式与三层架构_jsp的mvc三层架构-CSDN博客

  • 配好需要的包:springweb,mybatisplus+druid+Lombok

  • 配置,一般这里需要配置的是jdbc/durid的datadriver,配置mybatis的prefix,配置服务器端口号

  • domain+Lombok:新建数据库对象,作为操作的基本返回

    • @Getter
    • @Setter
    • @Data:最常用
  • 写Dao层的语句(两种方法写操作,并将操作mapper到数据库,对于每个操作都需要在test测试)

    • mybatis-plus :@Mapper + extends BaseMapper

      // 操作对象是Book,表是prefix+Book
      @Mapper
      public interface BookDao extends BaseMapper<Book> {
      }
      
      // 如果是分页功能
      	@Test
          void testGetPage(){
              IPage page = new Page(1,5);
              bookDao.selectPage(page,null);
          }
          
      // 需要加配置器,动态拼接SQL语句
      @Configuration
      public class MPConfig {
          // 拦截器
          // 传入要拦截的对象,此处是分页功能
          @Bean
          public MybatisPlusInterceptor mybatisPlusInterceptor(){
              MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
              interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
              return interceptor;
          }
      }
      
      // 查询功能
      @Test
          void testGetBy(){
              QueryWrapper<Book> qw = new QueryWrapper<>();
              qw.like("name","Spring");
              bookDao.selectList(qw);
          }
      
      // 不需要记住列名,直接通过Book调用
      	@Test
          void testGetBy2(){
              LambdaQueryWrapper<Book> lqw = new LambdaQueryWrapper<>();
              lqw.like(Book::getName,"Spring");
              bookDao.selectList(lqw);
          }
          
      // 都有动态条件拼装,name为空就不拼接筛选条件
       	@Test
          void testGetBy2(){
              String name = null;
              LambdaQueryWrapper<Book> lqw = new LambdaQueryWrapper<>();
              lqw.like(name!=null,Book::getName,name);
              bookDao.selectList(lqw);
          }
      
    • mybatis:@Mapper + 自己写语句

      @Mapper
      public interface BookDao {
          @Select("select * from tbl_book where id = #{id}")
          Book getById(int id);
      }
      
  • 业务层Service

    • 业务层接口

    • 业务层实现类

    • // 分页:返回值bookDao.selectPage和IPage<Book>是一样的
      	@Override
          public IPage<Book> getPage(int currentPage, int pageSize) {
              IPage page = new Page(currentPage,pageSize);
              return bookDao.selectPage(page,null);
          }
      
    • public interface IBookService extends IService<Book> {
      	// 可以自己新增方法
      	// 不要覆盖原始操作
      }
      
      @Service
      public class BookServiceImpl extends ServiceImpl<BookDao, Book> implements IBookService {
      }
      
      // 以上写法,就可以直接开启下边的测试
      @Test
          void testGetPage(){
              IPage<Book> page = new Page<>(1,4);
              bookService.page(page);
              System.out.println(page.getRecords());
          }
      
  • 表现层

    • @RestController
      @RequestMapping("/books")
      public class BookController {
      
          @Autowired
          private IBookService bookService;
      
          @GetMapping
          public List<Book> getAll(){
              return bookService.list();
          }
      
          @PostMapping
          public Boolean save(@RequestBody Book book){
              return bookService.save(book);
          }
      
          @PutMapping
          public Boolean update(@RequestBody Book book){
              return bookService.updateById(book);
          }
      
          @DeleteMapping("{id}")
          public Boolean delete(@PathVariable int id){
              return bookService.removeById(id);
          }
      
          @GetMapping("{id}")
          public Book getById(@PathVariable int id){
              return bookService.getById(id);
          }
          
          @GetMapping("{currentPage}/{page}")
          public IPage<Book> getPage(@PathVariable int currentPage, @PathVariable int page){
              return bookService.getPage(currentPage,page);
          }
      }
      
  • 异常处理:利用AOC来拦截所有异常,统一进行处理,要添加@RestControllerAdvice,设置该类为切面类可以被扫描到

    • @ExceptionHandler(Exception.class)
          public R deException(Exception ex){
              // 控制台要写报错信息
              ex.printStackTrace();
              return new R("服务器故障");
          }
      
      // 没有遇到异常,正常执行时
      // 所有消息提示应该来自于同一层,不要前后端各自定义
      Boolean flag = bookService.save(book);
      return new R(flag,flag? "添加成功":"添加失败");
      
  • el分页组件

    • // 每次需要更新页面的信息,不然就一直会是初始值		axios.get("/books/"+this.pagination.currentPage+"/"+this.pagination.pageSize+param).then((res)=>{
                          this.pagination.pageSize = res.data.data.size;
                          this.pagination.currentPage = res.data.data.current;
                          this.pagination.total = res.data.data.total;
                          this.dataList = res.data.data.records;
                      });
      
      // 防止删页问题
      @GetMapping("{currentPage}/{pageSize}")
          public R getPage(@PathVariable int currentPage, @PathVariable int pageSize){
              IPage<Book> page = bookService.getPage(currentPage,pageSize);
              if (currentPage>page.getPages()){
                  page = bookService.getPage((int) page.getPages(),pageSize);
              }
              return new R(true,page);
          }
      
  • 查询功能

    • v-model:就是拿Vue的data中的数据进行填充或者给到这个值,建立==关系

    • 根据拿到的值,按照规定传参:路径+实体类直接传参

      @GetMapping("{currentPage}/{pageSize}")
          public R getPage(@PathVariable int currentPage, @PathVariable int pageSize,Book book)
      
    • 利用LambdaQueryWrapper进行查询

      @Override
          public IPage<Book> getPage(int currentPage, int size, Book book) {
              LambdaQueryWrapper<Book> lqw = new LambdaQueryWrapper<Book>();
              lqw.like(!book.getType().isEmpty(),Book::getType,book.getType());
              lqw.like(!book.getName().isEmpty(),Book::getName,book.getName());
              lqw.like(!book.getDescription().isEmpty(),Book::getDescription,book.getDescription());
              IPage<Book> page = new Page<>(currentPage,size);
              bookDao.selectPage(page,lqw);
              return page;
          }
      

like(!book.getType().isEmpty(),Book::getType,book.getType());
lqw.like(!book.getName().isEmpty(),Book::getName,book.getName());
lqw.like(!book.getDescription().isEmpty(),Book::getDescription,book.getDescription());
IPage page = new Page<>(currentPage,size);
bookDao.selectPage(page,lqw);
return page;
}
```

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

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

相关文章

【2023下算法课设】Gray码的分治构造算法

Gray码是一个长度为2ⁿ的序列&#xff0c;序列中无相同元素&#xff0c;且每个元素都是长度为n位的二进制位串&#xff0c;相邻元素恰好只有1位不同。例如长度为2的格雷码为&#xff08;000,001,011,010,110,111,101,100&#xff09;&#xff0c;设计分治算法对任意的n值构造相…

如何使用设计模式来解决类与类之间调用过深的问题。

我们将使用责任链模式和装饰者模式的组合。 考虑一个简化的餐厅订单处理系统&#xff0c;其中包括服务员&#xff08;Waiter&#xff09;、厨师&#xff08;Chef&#xff09;和收银员&#xff08;Cashier&#xff09;。订单从服务员开始&#xff0c;然后传递给厨师&#xff0c…

python区块链简单模拟【05】

新增内容&#xff1a;构建去中心化网络 import socket #套接字&#xff0c;利用三元组【ip地址&#xff0c;协议&#xff0c;端口】可以进行网络间通信 import threading #线程 import pickle# 定义一个全局列表保存所有节点 NODE_LIST []class Node(threading.Thread…

目标检测-Two Stage-RCNN

文章目录 前言一、R-CNN的网络结构及步骤二、RCNN的创新点候选区域法特征提取-CNN网络 总结 前言 在前文&#xff1a;目标检测之序章-类别、必读论文和算法对比&#xff08;实时更新&#xff09;已经提到传统的目标检测算法的基本流程&#xff1a; 图像预处理 > 寻找候选区…

手术麻醉临床信息系统源码,客户端可以接入监护仪、麻醉机、呼吸机

一、手术麻醉临床信息管理系统介绍 1、手术麻醉临床信息管理系统是数字化手段应用于手术过程中的重要组成部分&#xff0c;用数字形式获取并存储手术相关信息&#xff0c;既便捷又高效。既然是管理系统&#xff0c;那就是一整套流程&#xff0c;管理患者手术、麻醉的申请、审批…

NVIDIA Jetson Nano 2GB 系列文章(9):调节 CSI 图像质量

NVIDIA英伟达中国 ​在本系列上一篇文章中&#xff0c;我们为大家展示了如何执行常见机器视觉应用。在本篇文章中&#xff0c;我们将带领大家调节 CSI 图像质量。 前面两篇文章在 Jetson Nano 2GB 上使用 CSI 摄像头做了几个实验&#xff0c;效果很不错&#xff0c;并且很容易…

分布式系统架构设计之分布式通信机制

二、分布式通信机制&#xff1a;保障系统正常运行基石 在分布式系统中&#xff0c;各个组件之间的通信是保障系统正常运行的基石&#xff0c;直接影响到系统的性能、可扩展性以及整体的可维护性。接下来我们就一起看看通信在分布式系统中的重要性&#xff0c;以及一些常用的技…

java八股 redis

Redis篇-01-redis开篇_哔哩哔哩_bilibili 1.缓存穿透 2.缓存击穿 逻辑过期里的互斥锁是为了保证只有一个线程去缓存重建 3.缓存雪崩 4.双写一致性 4.1要求一致性&#xff08;延迟双删/互斥锁&#xff09; 延迟双删无法保证强一致性 那么前两步删缓和更新数据库哪个先呢&#xf…

kubernetes(k8s) Yaml 文件详解

YAML格式&#xff1a;用于配置和管理&#xff0c;YAML是一种简洁的非标记性语言&#xff0c;内容格式人性化&#xff0c;较易读。 1、查看API 资源版本标签 kubectl api-versions 2、编写资源配置清单 kubectl create -f nginx-test.yaml --validatefalse 2.3 查看创建的po…

【Python可视化系列】一文教会你绘制美观的热力图(理论+源码)

一、问题 前文相关回顾&#xff1a; 【Python可视化系列】一文彻底教会你绘制美观的折线图&#xff08;理论源码&#xff09; 【Python可视化系列】一文教会你绘制美观的柱状图&#xff08;理论源码&#xff09; 【Python可视化系列】一文教会你绘制美观的直方图&#xff08;理…

docker部署kafka zookeeper模式集群

单机模式链接&#xff1a;https://blog.csdn.net/wsdhla/article/details/133032238 kraft集群模式链接&#xff1a;部署Kafka_kafka 部署-CSDN博客 zookeeper选举机制举例&#xff1a; 目前有5台服务器&#xff0c;每台服务器均没有数据&#xff0c;它们的编号分别是1,2,3,4,5…

鸿蒙开发(二)- 鸿蒙DevEco开发环境搭建

上篇说到&#xff0c;鸿蒙开发目前势头旺盛&#xff0c;头部大厂正在如火如荼地进行着&#xff0c;华为也对外宣称已经跟多个厂商达成合作。目前看来&#xff0c;对于前端或客户端开发人员来说&#xff0c;掌握下鸿蒙开发还是有些必要性的。如果你之前是从事Android开发的&…

【计算机网络】—— 奈氏准则和香农定理

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 &#x1f4ab;个人格言:"没有罗马,那就自己创造罗马~" 目录 失真 - 信号的变化 ​编辑影像失真的因素&#xff1a; ​编辑信道带宽&#xff1a; 码间串扰…

通过 Bytebase API 做数据库 Schema 变更

Bytebase 是一款数据库 DevOps 和 CI/CD 工具&#xff0c;适用于开发人员、DBA 和平台工程团队。 它提供了一个直观的图形用户界面来管理数据库 Schema 变更。另一方面&#xff0c;一些团队可能希望将 Bytebase 集成到现有的内部 DevOps 研发平台中。这需要调用 Bytebase API。…

内存管理--bss data txt数据段与stm32的ZI-data RW-data RO-data Code数据段的关系

目录 前沿 1 数据在内存中的位置 1.1 堆栈在内存中的位置 1.2 全局变量和局部变量在内存中的位置 1.2.1 全局变量在内存中的位置 1.2.2 局部变量在内存中的位置 1.3 static变量在内存中的位置 1.4 malloc赋值的变量存放在内存中的位置 1.5 代码在内存中的位置 2 ZI-d…

udp广播的例子

以下是一个使用C语言描述广播发送和接收的简单示例&#xff1a; 发送端&#xff08;广播发送&#xff09;&#xff1a; #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> #inclu…

如何使用Docker将.Net6项目部署到Linux服务器(二)

目录 二 安装Redis 2.1 基本安装 2.1.1 下载Redis 2.1.2 解压并安装Redis 2.1.3 编译Redis 2.1.3 配置config文件 2.1.4 配置redis服务 2.1.5 关闭redis服务 2.2 Docker安装 2.2.1 拉取镜像 2.2.2 查看镜像 2.2.2 创建挂载目录 2.2.3 创建配置文件 2.2.4 创建容器…

几种串口扩展电路

一、IIC串口扩展电路 LCT200 是一款可以通过 I2C 接口通讯&#xff0c;拓展 2 路独立串口的通讯芯片&#xff0c;同时也支持通过 2 路串口读写 I2C 接口的数据。LCT200 的封装为 TSSOP-20。 主要功能&#xff1a;⚫ 通过对 I2C 接口读写实现拓展 2 路独立串口功能 ⚫ 通过读写…

Linux学习教程(第十八章 SELinux管理)

第十八章 SELinux管理 root 用户实在是一个超人&#xff0c;它在 Linux 系统当中就是无所不能的&#xff0c;而且读、写和执行权限对 root 用户完全没有作用。root 用户的存在极大地方便了 Linux 的管理&#xff0c;但是也造成了一定的安全隐患。 大家想象一下&#xff0c;如果…

LabVIEW与PID在温度测控系统中的应用

LabVIEW与PID在温度测控系统中的应用 本案例介绍LabVIEW在温度控制系统中的应用&#xff0c;特别是结合PID算法。项目使用abVIEW作为主要开发工具&#xff0c;配合NI PCI-7831R数据采集和控制设备&#xff0c;实现了高效的温度调节。 系统的核心在于LabVIEW的FPGA模块&#x…