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

2023-12-26 11:32:47

SpringBoot

  • Springboot项目

  • 相比于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;
}
```

文章来源:https://blog.csdn.net/CZY925323/article/details/135216844
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。