[黑马程序员SpringBoot2]——基础篇2

news2024/11/15 1:25:14

目录:

  1. 模块创建
  2. 实体类快速开发(lombok)
  3. 数据层标准开发(基础CRUD)
  4. 开启MP运行日志
  5. 分页
  6. 数据层标准开发(条件查询)
  7. 业务层标准开发(基础CRUD)
  8. 业务层标准开发(基于MyBatisPlus构建)
  9. 表现层标准开发
  10. 表现层数据一致性处理(R对象)
  11. 前后端调用(axios发送异步请求)
  12. 列表功能
  13. 添加功能
  14. 删除功能
  15. 修改功能
  16. 异常消息处理
  17. 分页
  18. 条件查询
  19. 基础篇完结

1.模块创建

pom.xml(把相应的依赖下载好)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.1.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>_20231024_ssmp</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>_20231024_ssmp</name>
    <description>_20231024_ssmp</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.2</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.9</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

2.实体类快速开发(lombok)

 

Book.class

package com.example.domain;

import lombok.Data;

@Data
public class Book {
    private Integer id;
    private String type;
    private String name;
    private String description;
}

 小结:

  • 实体类制作
  • 使用lombok简化开发
    • 导入lombok无需指定版本,由SpringBoot提供版本
    • Data注解

 3.数据层标准开发(基础CRUD)

技术实现方案

  • MyBatisPlus
  • Druid 

导入MyBatisPlus与Druid对应的starter

 继承BaseMapper并指定泛型

制作测试类测试结果


BookDao.interface

package com.example.dao;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.domain.Book;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface BookDao extends BaseMapper<Book> {
}

 Book.class

package com.example.domain;

import lombok.Data;

@Data
public class Book {
    private Integer id;
    private String type;
    private String name;
    private String description;
}

 application.yml

server:
  port: 80

spring:
  datasource:
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3308/test_db
      username: root
      password: 666666

mybatis-plus:
  global-config:
    db-config:
      table-prefix: tbl_
      id-type: auto

BookDaoTest

package com.example.dao;

import com.example.domain.Book;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;


@SpringBootTest
class BookDaoTest {
    @Autowired
    public BookDao bookDao;

    @Test
    void testGetById() {
        System.out.println(bookDao.selectById(1));
    }

    @Test
    void testSave() {
        Book book = new Book();
        book.setType("测试数据123");
        book.setName("测试数据123");
        book.setDescription("测试数据123");

        int ret = bookDao.insert(book);

        if (ret == 0) {
            System.out.println("新增失败!");
        } else {
            System.out.println("新增成功!");
        }
    }

    @Test
    void testUpdate() {
        Book book = new Book();
        book.setId(13);
        book.setType("aaaa");
        book.setName("aaaa");
        book.setDescription("aaaa");

        int ret = bookDao.updateById(book);

        if (ret == 0) {
            System.out.println("修改失败!");
        } else {
            System.out.println("修改成功!");
        }
    }

    @Test
    void testDelete() {
        int ret = bookDao.deleteById(13);

        if (ret == 0) {
            System.out.println("删除失败!");
        } else {
            System.out.println("删除成功!");
        }
    }

    @Test
    void testGetAll() {
        System.out.println(bookDao.selectList(null));
    }

}

运行结果:

小结: 

  1. 手工导入starter坐标(2个)
  2. 配置数据源与MyBatisPlus对应的配置
  3. 开发Dao接口(继承BaseMapper)
  4. 制作测试类测试Dao功能是否有效 

4.开启MP运行日志 

application.yml

server:
  port: 80

spring:
  datasource:
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3308/test_db
      username: root
      password: 666666

mybatis-plus:
  global-config:
    db-config:
      table-prefix: tbl_
      id-type: auto
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

 运行结果:

为方便调试可以开启MyBatisPlus的日志
 

小结:

  • 使用配置方式开启日志,设置日志输出方式为标准输出

5.分页 

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.18-SNAPSHOT</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>_20231024_ssmp1</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>_20231024_ssmp1</name>
    <description>_20231024_ssmp1</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.2</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.9</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <releases>
                <enabled>false</enabled>
            </releases>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
        <pluginRepository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <releases>
                <enabled>false</enabled>
            </releases>
        </pluginRepository>
    </pluginRepositories>

</project>

MPConfig.class

package com.example.config;

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MPConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return interceptor;
    }
}

 BookDao.interface

package com.example.dao;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.domain.Book;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface BookDao extends BaseMapper<Book> {
}

Book.class

package com.example.domain;

import lombok.Data;

@Data
public class Book {
    private Integer id;
    private String type;
    private String name;
    private String description;
}

applicaion.yml

server:
  port: 80

spring:
  datasource:
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3308/test_db
      username: root
      password: 666666

mybatis-plus:
  global-config:
    db-config:
      table-prefix: tbl_
      id-type: auto
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

BookDaoTest

package com.example.dao;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.domain.Book;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;


@SpringBootTest
class BookDaoTest {
    @Autowired
    public BookDao bookDao;

    @Test
    void testGetById() {
        System.out.println(bookDao.selectById(1));
    }

    @Test
    void testSave() {
        Book book = new Book();
        book.setType("测试数据123");
        book.setName("测试数据123");
        book.setDescription("测试数据123");

        int ret = bookDao.insert(book);

        if (ret == 0) {
            System.out.println("新增失败!");
        } else {
            System.out.println("新增成功!");
        }
    }

    @Test
    void testUpdate() {
        Book book = new Book();
        book.setId(13);
        book.setType("aaaa");
        book.setName("aaaa");
        book.setDescription("aaaa");

        int ret = bookDao.updateById(book);

        if (ret == 0) {
            System.out.println("修改失败!");
        } else {
            System.out.println("修改成功!");
        }
    }

    @Test
    void testDelete() {
        int ret = bookDao.deleteById(13);

        if (ret == 0) {
            System.out.println("删除失败!");
        } else {
            System.out.println("删除成功!");
        }
    }

    @Test
    void testGetAll() {
        System.out.println(bookDao.selectList(null));
    }

    @Test
    void testGetPage() {
        IPage page = new Page(2, 5);
        bookDao.selectPage(page, null);
        System.out.println(page.getCurrent());
        System.out.println(page.getSize());
        System.out.println(page.getTotal());
        System.out.println(page.getPages());
        System.out.println(page.getRecords());
    }
}

项目结构:

运行结果:

分页操作需要设定分页对象IPage


IPage对象中封装了分页操作中的所有数据

  • 数据
  • 当前页码值
  • 每页数据总量
  • 最大页码值
  • 数据总量

分页操作是在MyBatisPlus的常规操作基础上增强得到,内部是动态的拼写SQL语句,因此需要增强对应的功能,使用MyBatisPlus拦截器实现

小结: 

  1. 使用IPage封装分页数据
  2. 分页操作依赖MyBatisPlus分页拦截器实现功能
  3. 借助MyBatisPlus日志查阅执行sQL语句

6.数据层标准开发(条件查询) 

使用QueryWrapper对象封装查询条件,推荐使用LambdaQueryWrapper对象,所有查询操作封装成方法调用

支持动态拼写查询条件
 

代码示例:

BookDaoTest

package com.example.dao;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.domain.Book;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;


@SpringBootTest
class BookDaoTest {
    @Autowired
    public BookDao bookDao;

    @Test
    void testGetById() {
        System.out.println(bookDao.selectById(1));
    }

    @Test
    void testSave() {
        Book book = new Book();
        book.setType("测试数据123");
        book.setName("测试数据123");
        book.setDescription("测试数据123");

        int ret = bookDao.insert(book);

        if (ret == 0) {
            System.out.println("新增失败!");
        } else {
            System.out.println("新增成功!");
        }
    }

    @Test
    void testUpdate() {
        Book book = new Book();
        book.setId(13);
        book.setType("aaaa");
        book.setName("aaaa");
        book.setDescription("aaaa");

        int ret = bookDao.updateById(book);

        if (ret == 0) {
            System.out.println("修改失败!");
        } else {
            System.out.println("修改成功!");
        }
    }

    @Test
    void testDelete() {
        int ret = bookDao.deleteById(13);

        if (ret == 0) {
            System.out.println("删除失败!");
        } else {
            System.out.println("删除成功!");
        }
    }

    @Test
    void testGetAll() {
        System.out.println(bookDao.selectList(null));
    }

    @Test
    void testGetPage() {
        IPage page = new Page(2, 5);
        bookDao.selectPage(page, null);
        System.out.println(page.getCurrent());
        System.out.println(page.getSize());
        System.out.println(page.getTotal());
        System.out.println(page.getPages());
        System.out.println(page.getRecords());
    }

    @Test
    void testGetBy() {
        QueryWrapper<Book> qw = new QueryWrapper<>();
        qw.like("name", "Spring");
        bookDao.selectList(qw);
    }

    @Test
    void testGetBy2() {
        String name = "Spring";
        LambdaQueryWrapper<Book> lqw = new LambdaQueryWrapper<>();
        lqw.like(name != null, Book::getName, name);
        bookDao.selectList(lqw);
    }
}

运行结果:

小结:

  1. 使用Querywrapper对象封装查询条件
  2. 推荐使用LambdaQuerywrapper对象
  3. 所有查询操作封装成方法调用
  4. 查询条件支持动态条件拼装 

7.业务层标准开发(基础CRUD) 

 BookService.interface

package com.example.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.example.domain.Book;

import java.util.List;

public interface BookService {
    Boolean save(Book book);

    Boolean update(Book book);

    Boolean delete(Integer id);

    Book getById(Integer id);

    List<Book> getAll();

    IPage<Book> getPage(int currentPage, int pageSize);
}

BookServiceImpl.class

package com.example.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.dao.BookDao;
import com.example.domain.Book;
import com.example.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class BookServiceImpl implements BookService {
    @Autowired
    private BookDao bookDao;

    @Override
    public Boolean save(Book book) {
        return bookDao.insert(book) > 0;
    }

    @Override
    public Boolean update(Book book) {
        return bookDao.updateById(book) > 0;
    }

    @Override
    public Boolean delete(Integer id) {
        return bookDao.deleteById(id) > 0;
    }

    @Override
    public Book getById(Integer id) {
        return bookDao.selectById(id);
    }

    @Override
    public List<Book> getAll() {
        return bookDao.selectList(null);
    }

    @Override
    public IPage<Book> getPage(int currentPage, int pageSize) {
        IPage page = new Page(currentPage, pageSize);
        return bookDao.selectPage(page, null);
    }
}

BookServiceTest.class

package com.example.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.example.domain.Book;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class BookServiceTest {
    @Autowired
    private BookService bookService;

    @Test
    void save() {
        Book book = new Book();
        book.setType("测试数据123");
        book.setName("测试数据123");
        book.setDescription("测试数据123");

        Boolean ret = bookService.save(book);

        if (ret == false) {
            System.out.println("新增失败!");
        } else {
            System.out.println("新增成功!");
        }
    }

    @Test
    void update() {
        Book book = new Book();
        book.setId(13);
        book.setType("aaaa");
        book.setName("aaaa");
        book.setDescription("aaaa");

        Boolean ret = bookService.update(book);

        if (ret == false) {
            System.out.println("修改失败!");
        } else {
            System.out.println("修改成功!");
        }
    }

    @Test
    void delete() {
        Boolean ret = bookService.delete(16);

        if (ret == false) {
            System.out.println("删除失败!");
        } else {
            System.out.println("删除成功!");
        }
    }

    @Test
    void getById() {
        System.out.println(bookService.getById(4));
    }

    @Test
    void getAll() {
        System.out.println(bookService.getAll());
    }

    @Test
    void getPage() {
        IPage page = bookService.getPage(2, 5);
        System.out.println(page.getCurrent());
        System.out.println(page.getSize());
        System.out.println(page.getTotal());
        System.out.println(page.getPages());
        System.out.println(page.getRecords());
    }
}

项目结构:

Service层接口定义与数据层接口定义具有较大区别,不要混用

  • selectByUserNameAndPassword( String username, string password );
  • login(String username , string password ) ;

接口定义


实现类定义

测试类定义
 

小结:

  • Service接口名称定义成业务名称,并与Dao接口名称进行区分
  • 制作测试类测试service功能是否有效

8.业务层标准开发(基于MyBatisPlus构建) 

IBookService.class

package com.example.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.example.domain.Book;

public interface IBookService extends IService<Book> {
    boolean insert(Book book);

    boolean modify(Book book);

    boolean delete(Integer id);

    Book get(Integer id);
}

BookServiceImpl1.class

package com.example.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.dao.BookDao;
import com.example.domain.Book;
import com.example.service.IBookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class BookServiceImpl1 extends ServiceImpl<BookDao, Book> implements IBookService {
    @Autowired
    private BookDao bookDao;

    @Override
    public boolean insert(Book book) {
        return bookDao.insert(book) > 0;
    }

    @Override
    public boolean modify(Book book) {
        return bookDao.updateById(book) > 0;
    }

    @Override
    public boolean delete(Integer id) {
        return bookDao.deleteById(id) > 0;
    }

    @Override
    public Book get(Integer id) {
        return bookDao.selectById(id);
    }
}

IBookServiceTest.class

package com.example.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.domain.Book;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class IBookServiceTest {
    @Autowired
    private IBookService bookService;


    @Test
    void save() {
        Book book = new Book();
        book.setType("测试数据123");
        book.setName("测试数据123");
        book.setDescription("测试数据123");

        Boolean ret = bookService.save(book);

        if (ret == false) {
            System.out.println("新增失败!");
        } else {
            System.out.println("新增成功!");
        }
    }

    @Test
    void update() {
        Book book = new Book();
        book.setId(18);
        book.setType("aaaa");
        book.setName("aaaa");
        book.setDescription("aaaa");

        Boolean ret = bookService.updateById(book);

        if (ret == false) {
            System.out.println("修改失败!");
        } else {
            System.out.println("修改成功!");
        }
    }

    @Test
    void delete1() {
        Boolean ret = bookService.removeById(17);

        if (ret == false) {
            System.out.println("删除失败!");
        } else {
            System.out.println("删除成功!");
        }
    }

    @Test
    void getById() {
        System.out.println(bookService.getById(4));
    }

    @Test
    void getAll() {
        System.out.println(bookService.list());
    }

    @Test
    void getPage() {
        IPage page = new Page<Book>(2, 5);
        bookService.page(page);
        System.out.println(page.getCurrent());
        System.out.println(page.getSize());
        System.out.println(page.getTotal());
        System.out.println(page.getPages());
        System.out.println(page.getRecords());
    }

    //    ------------------------追加的功能-----------------------------------
    @Test
    void insert() {
        Book book = new Book();
        book.setType("测试数据123");
        book.setName("测试数据123");
        book.setDescription("测试数据123");

        Boolean ret = bookService.insert(book);

        if (ret == false) {
            System.out.println("新增失败!");
        } else {
            System.out.println("新增成功!");
        }
    }

    @Test
    void modify() {
        Book book = new Book();
        book.setId(18);
        book.setType("aaaa");
        book.setName("aaaa");
        book.setDescription("aaaa");

        Boolean ret = bookService.modify(book);

        if (ret == false) {
            System.out.println("修改失败!");
        } else {
            System.out.println("修改成功!");
        }
    }

    @Test
    void delete() {
        Boolean ret = bookService.delete(17);

        if (ret == false) {
            System.out.println("删除失败!");
        } else {
            System.out.println("删除成功!");
        }
    }

    @Test
    void get() {
        System.out.println(bookService.get(4));
    }
}

 项目结构:

快速开发方案

  • 使用MyBatisPlus提供有业务层通用接口(ISerivce<T>)与业务层通用实现类(ServiceImpl<M,T>)
  • 在通用类基础上做功能重载或功能追加
  • 注意重载时不要覆盖原始操作,避免原始提供的功能丢失

接口定义


 

实现类定义


实现类追加功能


 

小结:

  1. 使用通用接口(ISerivce<T>)快速开发service
  2. 使用通用实现类(ServiceImpl<M,T>)快速开发ServiceImpl
  3. 可以在通用接口基础上做功能重载或功能追加
  4. 注意重载时不要覆盖原始操作,避免原始提供的功能丢失 

9.表现层标准开发 

getAll

getById

delete

save

update

getPage

BookController.class

package com.example.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.example.domain.Book;
import com.example.service.IBookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@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.modify(book);
    }

    @DeleteMapping("{id}")
    public Boolean delete(@PathVariable Integer id) {
        return bookService.delete(id);
    }

    @GetMapping("{id}")
    public Book getById(@PathVariable Integer id) {
        return bookService.getById(id);
    }

    @GetMapping("{currentPage}/{pageSize}")
    public IPage<Book> getPage(@PathVariable int currentPage, @PathVariable int pageSize) {
        return bookService.getPage(currentPage, pageSize);
    }
}

IBookService.interface

package com.example.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.domain.Book;

public interface IBookService extends IService<Book> {
    boolean insert(Book book);

    boolean modify(Book book);

    boolean delete(Integer id);

    Book get(Integer id);

    IPage<Book> getPage(int currentPage, int pageSize);
}

 BookServiceImpl1

package com.example.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.dao.BookDao;
import com.example.domain.Book;
import com.example.service.IBookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class BookServiceImpl1 extends ServiceImpl<BookDao, Book> implements IBookService {
    @Autowired
    private BookDao bookDao;

    @Override
    public boolean insert(Book book) {
        return bookDao.insert(book) > 0;
    }

    @Override
    public boolean modify(Book book) {
        return bookDao.updateById(book) > 0;
    }

    @Override
    public boolean delete(Integer id) {
        return bookDao.deleteById(id) > 0;
    }

    @Override
    public Book get(Integer id) {
        return bookDao.selectById(id);
    }

    @Override
    public IPage<Book> getPage(int currentPage, int pageSize) {
        IPage page = new Page(currentPage, pageSize);
        bookDao.selectPage(page, null);
        return page;
    }
}

项目结构:

小结:

  • 基于Restfu1制作表现层接口
    • 新增:POST
    • 删除:DELETE
    • 修改:PUT
    • 查询:GET
  • 接收参数
    • 实体数据:@RequestBody
    • 路径变量:@PathVariable 

10. 表现层数据一致性处理(R对象)

 R.class

package com.example.utils;

import lombok.Data;

@Data
public class R {
    private Boolean flag;
    private Object data;

    public R() {
    }

    public R(Boolean flag) {
        this.flag = flag;
    }

    public R(Boolean flag, Object data) {
        this.flag = flag;
        this.data = data;
    }
}

 BookController1.class

package com.example.controller;

import com.example.domain.Book;
import com.example.service.IBookService;
import com.example.utils.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;


@RestController
@RequestMapping("/books")
public class BookController1 {
    @Autowired
    private IBookService bookService;

    @GetMapping
    public R getAll() {
        return new R(true, bookService.list());
    }

    @PostMapping
    public R save(@RequestBody Book book) {
        return new R(bookService.save(book));
    }

    @PutMapping
    public R update(@RequestBody Book book) {
        return new R(bookService.modify(book));
    }

    @DeleteMapping("{id}")
    public R delete(@PathVariable Integer id) {
        return new R(bookService.delete(id));
    }

    @GetMapping("{id}")
    public R getById(@PathVariable Integer id) {
        return new R(true, bookService.getById(id));
    }

    @GetMapping("{currentPage}/{pageSize}")
    public R getPage(@PathVariable int currentPage, @PathVariable int pageSize) {
        return new R(true, bookService.getPage(currentPage, pageSize));
    }
}

项目结构:

postman测试结果:

getAll

getById 

 delete

update

        

save

getPage

 设计表现层返回结果的模型类, 用于后端与前端进行数据格式统一,也称为前后端数据协议

表现层接口统一返回值类型结果


小结:

  1. 设计统─的返回值结果类型便于前端开发读取数据
  2. 返回值结果类型可以根据需求自行设定,没有固定格式
  3. 返回值结果模型类用于后端与前端进行数据格式统一,也称为前后端数据协议

11.前后端调用(axios发送异步请求)

项目结构:(项目地址:JavaEE: 练习的代码 - Gitee.com)

运行结果:

前后端分离结构设计中页面归属前端服务器
单体工程中页面放置在resources目录下的static目录中(建议执行clean)

前端发送异步请求,调用后端接口


小结:

  • 单体项目中页面放置在resources/static目录下
  • created钩子函数用于初始化页面时发起调用
  • 页面使用axios发送异步请求获取数据后确认前后端是否联通 

12.列表功能 

 列表页

 运行结果:

小结:

  • 将查询数据返回到页面,利用前端数据双向绑定进行数据展示

13.添加功能

弹出添加窗口


 

清除数据


 

添加


 

取消添加


  

小结:

  1. 请求方式使用POST调用后台对应操作
  2. 添加操作结束后动态刷新页面加载数据
  3. 根据操作结果不同,显示对应的提示信息
  4. 弹出添加Div时清除表单数据  

14.删除功能 

删除

 

小结:

  1. 请求方式使用Delete调用后台对应操作
  2. 删除操作需要传递当前行数据对应的id值到后台
  3. 删除操作结束后动态刷新页面加载数据
  4. 根据操作结果不同,显示对应的提示信息
  5. 删除操作前弹出提示框避免误操作

15.修改功能

弹出修改窗口

删除消息维护


 

小结:

  • 加载要修改数据通过传递当前行数据对应的id值到后台查询数据
  • 利用前端数据双向绑定将查询到的数据进行回显

修改


 

取消添加和修改


 

小结:

  • 请求方式使用PUT调用后台对应操作
  • 修改操作结束后动态刷新页面加载数据(同新增)
  • 根据操作结果不同,显示对应的提示信息(同新增) 

16.异常消息处理

业务操作成功或失败返回数据格式

后台代码BUG导致数据格式不统一性

对异常进行统一处理,出现异常后,返回指定信息


 

修改表现层返回结果的模型类,封装出现异常后对应的信息

  • flag: false
  • Data: null
  • 消息(msg): 要显示信息

 

页面消息处理,没有传递消息加载默认消息,传递消息后加载指定消息


 

可以在表现层Controller中进行消息统一处理


 

目的:国际化
 

页面消息处理

 

小结:

  • 使用注解@RestcontrollerAdvice定义SpringMVC异常处理器用来处理异常的
  • 异常处理器必须被扫描加载,否则无法生效
  • 表现层返回结果的模型类中添加消息属性用来传递消息到页面 

17.分页 

页面使用el分页组件添加分页功能

定义分页组件需要使用的数据并将数据绑定到分页组件


 

替换查询全部功能为分页功能


 

分页查询


 

使用路径参数传递分页数据或封装对象传递数据
 

加载分页数据


 

分页页码值切换


 

小结:

  • 使用el分页组件
  • 定义分页组件绑定的数据模型
  • 异步调用获取分页数据
  • 分页数据页面回显 

对查询结果进行校验,如果当前页码值大于最大页码值,使用最大页码值作为当前页码值重新查询

 

小结:

  • 基于业务需求维护删除功能

18.条件查询 

查询条件数据封装

  • 单独封装
  • 与分页操作混合封装

 

页面数据模型绑定

组织数据成为get请求发送的数据


 

条件参数组织可以通过条件判定书写的更简洁

Controller接收参数

业务层接口功能开发


 

Controller调用业务层分页条件查询接口


 

页面回显数据


 

小结:

  • 定义查询条件数据模型(当前封装到分页数据模型中)
  • 异步调用分页功能并通过请求参数传递数据到后台 

19.基础篇完结:

 基于SpringBoot的SSMP整合案例

  1. pom. xml                        配置起步依赖
  2. application. yml             设置数据源、端口、框架技术相关配置等
  3. dao                                继承BaseMapper、设置@Mapper
  4. dao测试类
  5. service                           调用数据层接口或MyBatis-Plus提供的接口快速开发
  6. service测试类
  7. controller                         基于Restful开发,使用Postman测试跑通功能
  8. 页面                                放置在resources目录下的static目录中

项目地址:JavaEE: 练习的代码 - Gitee.com

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

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

相关文章

阿里云企业邮箱基于Spring Boot快速实现发送邮件功能

邮件在项目中经常会被用到&#xff0c;比如用邮件发送通知。比如&#xff0c;通过邮件注册、认证、找回密码、系统报警通知、报表信息等。本篇文章带大家通过SpringBoot快速实现一个发送邮件的功能。 邮件协议 下面先简单了解一下常见的邮件协议。常用的电子邮件协议有SMTP、…

xxl-job项目集成实战,全自动项目集成,可以直接使用到项目中

如果你看官方文档&#xff0c;在研究透&#xff0c;至少也得几天时间&#xff0c;如果你直接看我的文档&#xff0c;快速用到项目中&#xff0c;也就10分钟就搞好了。 xxl-job功能确实很强大&#xff0c;而且使用的人比较多&#xff0c;既然在使用xxl-job&#xff0c;那肯定是…

成为CSS选择器大师,让你的网页瞬间提升品味!

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 ⭐ 专栏简介 &#x1f4d8; 文章引言 一、选…

【SpringCoud】

1,启动各个服务: 2,访问以下地址: http://localhost:5001/product/purchase/1/1/1000 浏览器输出: 控制台输出: 这里随机调用的端口号使用了轮询的方式 从服务治理中心拉去一份服务实例清单,然后通过某种负载均衡的算法选择具体的实例 Product核心逻辑代码: @RestController…

新生儿黄疸:原因、科普和注意事项

引言&#xff1a; 新生儿黄疸是许多新生儿面临的常见情况。虽然它通常是一种暂时的现象&#xff0c;但对于许多父母来说&#xff0c;这可能引发担忧。本文将科普新生儿黄疸的原因&#xff0c;提供相关信息&#xff0c;并为父母和监护人提供注意事项&#xff0c;以帮助他们更好…

如何在 SwiftUI 中创建悬浮操作按钮

文章目录 前言创建悬浮操作按钮悬浮按钮出现在屏幕的最前方悬浮按钮位于屏幕的右下角使悬浮按钮呈现圆形添加阴影总结 前言 悬浮操作按钮&#xff08;Floating Action Button, FAB&#xff09;是一种在 Android 和 Material Design 中使用的 UI 元素。它用于触发特定屏幕的主要…

百度迁徒数据爬虫方法

百度迁徙数据是由百度公司提供的免费开放数据集&#xff0c;主要包含了全国范围内各大城市的每日人口流入流出情况。这些数据来源于百度地图上的用户位置信息&#xff0c;通过计算得到每个小时的流入流出人数&#xff0c;并且可以按照省级、市级等多种维度进行分析。 百度迁徙 …

Modbus转MQTT以太网网关MQT-802主要特点和典型应用

随着社会的快速发展&#xff0c;物联网已经潜移默化地深入工控行业的各个领域&#xff0c;其高效的资源整合和强大的数据采集能力&#xff0c;深受客户的喜爱。上海泗博为实现客户在云端平台接收处理世界万物的信息以及实现远程控制&#xff0c;精心打造一款全新物联网产品&…

制作翻页电子画册,手机观看更快捷

随着科技的发展&#xff0c;便携式翻页电子手册越来越受到人们的青睐。这种电子手册不仅方便携带&#xff0c;而且可以在手机上轻松观看&#xff0c;非常适合那些忙碌的上班族或者学生党。与传统纸质书籍相比&#xff0c;电子手册不仅节省了空间&#xff0c;而且还可以随时随地…

C51--单片机中断

51单片机是单线程模式&#xff0c;需要用到硬件中断。 一、中断系统 中断系统是为使CPU具有对外界紧急事件的实时处理能力而设置的。 当中央处理器CPU正在处理某件事的时候&#xff0c;外界发生了紧急事件请求&#xff0c;要求CPU暂停当前工作&#xff0c;转而去处理这个紧急…

LeetCode刷题---最长回文子串

方法一&#xff1a;暴力破解 class Solution {public String longestPalindrome(String s) {if(s.length()<2){return s;}//最长长度int maxLen0;//保留索引坐标String ans "";for(int i0;i<s.length()-1;i){for(int ji1;j<s.length();j){String strs.subs…

ubuntu 下的 使用anaconda 环境运行python 项目

pycharm部署django项目到云服务器的详细流程_编程网 anaconda 安装环境 ubuntu下Anaconda安装与使用教程_ubuntu 运行anaconda_fakerth的博客-CSDN博客 激活环境 conda activate web_hook_python3.9进入到项目目录 cd /home/web-hook-main查看端口是否被占用 sudo ss …

Spring Boot集成Swagger接口分类与各元素排序问题

在上一篇中我们完成使用JSR-303校验&#xff0c;以及利用Swagger2得到相关接口文档&#xff0c;这节&#xff0c;我们在原先的基础之上&#xff0c;完成Swagger中关于对各个元素之间控制前后顺序的具体配置方法。 Swagger的接口的分组 首先我们需要对Swagger中的接口也就是以…

浅谈wheel滚轮事件

<divonWheel{(ee) > {// new WheelEvent(自定义,e) 获取 e[wheelDelta],e[deltaY] 判断滚轮方向var e new WheelEvent(syntheticWheel,ee)console.log(滚动触发事件, e,ee);console.log(滚动触发事件e.wheelDelta, e[wheelDelta],e[deltaY]);console.log(滚动触发事件e.…

Spirit:继承 gh-ost 灵魂的 MySQL 在线大表变更方案

昨天看到社区发布了一个新的 MySQL 大表变更工具 Spirit。是海外支付巨头 Block 旗下的 Cash App (地位类似于支付宝) 开源的&#xff0c;作者之前也在 PingCAP 工作过。 目前市面上做大表变更的方案有两个&#xff1a; Percona 开源的 pt-online-schema-change&#xff0c;基…

WMS仓储管理系统如何保障仓库的安全性

仓库安全一直以来都是企业运营中的重要一环&#xff0c;而WMS仓储管理系统则可以为仓库安全提供有力的保障。本文将探讨WMS仓储管理系统如何在实际应用中确保仓库的安全性。 WMS管理系统是一种专门用于管理仓库和库存的软件&#xff0c;它可以帮助企业对库存进行跟踪、管理以及…

鼎鑫鸿鄴引入“能源互联网+”理念 打造共赢

近年来&#xff0c;随着全球能源消耗的不断增长和环境问题的日益突出&#xff0c;清洁能源转型成为全球共同关注的话题。中国作为全球最大的能源消费国&#xff0c;也在积极推动能源结构的优化和清洁能源的发展。鼎鑫鸿鄴新能源科技有限公司在推动清洁能源转型方面制定了一系列…

探索 10 个有价值的在线免费设计模板网站

对于许多设计师来说&#xff0c;现成的模板无疑可以大大提高工作效率和质量&#xff0c;特别是在赶上项目过程时。然而&#xff0c;找到合适和免费的模板是另一个问题。在这里&#xff0c;我整理了10个推荐的设计模板网站&#xff0c;希望能对您有所帮助。 1.即时设计 即时设计…

转化率的催化剂:网站客服机器人如何推动企业销售?

随着5G的推广&#xff0c;人工智能技术的普及程度越来越高&#xff0c;人机交互已经成为这个时代的常态&#xff0c;无论是在我们的日常生活中还是在企业服务中都非常常见。如今&#xff0c;无论是营销型企业还是客服型企业&#xff0c;都纷纷采用网站客服机器人服务&#xff0…

研究目标检测的同学看过来:超越YOLOv8!华为提出Gold-YOLO:高效实时

超越YOLOv8&#xff01;华为提出Gold-YOLO&#xff1a;高效实时目标检测器 超越YOLO系列&#xff08;v5、v6、v7、v8&#xff09;&#xff01;Gold-YOLO&#xff1a;一种全新的实时目标检测器&#xff0c;提出一种GD新机制&#xff0c;通过卷积和自注意力操作来实现&#xff0…