• SpringBoot-基础篇复习(全)


    本文包含SpringBoot基础篇的所有知识点,大家一起来学习吧,开启一段新的旅程,加油吧。springboot是由Picotal团队提供的全新框架,用来简化spring的搭建和开发过程的配置,因为spring的配置比较繁琐,故引入了springboot。

    目录

    一、springboot入门案例

    1.1、入门案例之IDEA联网版

    1.2、入门案例解析-parent

     1.3、入门案例解析-starter

     1.4、引导类

    1.5、内嵌Tomcat

     二、REST风格补充

    2.1、REST风格简介

     2.2、Restful风格入门案例

    2.3、Restful快速开发

     三、配置修改

    3.1、属性配置方式

    3.2、文件配置格式及优先级

    3.3、yaml基本语法规则

     3.4、yaml读取单一属性数据

    3.5、读取yaml全部属性数据

    3.6、读取yaml引用类型数据

    四、SpringBoot整合第三方技术

    4.1、整合junit

    4.2、整合MyBatis

    4.3、整合MyBatis-Plus

    4.4、整合Druid

    五、基于SpringBoot的SSMP案例整合

    5.1、案例实现方案分析

     5.2、模块创建

    5.3、快速创建实体类

    5.4、数据层快速开发

    5.5、分页查询

    5.6、数据层的按条件查询

    5.7、业务层的开发(crud)

    5.8、业务层的开发(基于MyBatis-Plus构建)

    5.9、表现层标准开发

    5.10、前后端协议联调


    一、springboot入门案例

    1.1、入门案例之IDEA联网版

    直接创建一个控制器,响应浏览器的请求,并在控制台打印,如下:

    1. import org.springframework.web.bind.annotation.GetMapping;
    2. import org.springframework.web.bind.annotation.RequestMapping;
    3. import org.springframework.web.bind.annotation.RestController;
    4. @RestController
    5. @RequestMapping("/books")
    6. public class BookController {
    7. @GetMapping
    8. public String getById(){
    9. System.out.println("Springboot is running ...");
    10. return "springboot is running ..." ;
    11. }
    12. }

    启动Application:

    1. import org.springframework.boot.SpringApplication;
    2. import org.springframework.boot.autoconfigure.SpringBootApplication;
    3. @SpringBootApplication
    4. public class DemoApplication {
    5. public static void main(String[] args) {
    6. SpringApplication.run(DemoApplication.class, args);
    7. }
    8. }

    1.2、入门案例解析-parent

    使用parent可以更好地管理依赖,快速引入依赖,防止 依赖冲突等。

     1.3、入门案例解析-starter

    使用starter一般可以包含多个多个依赖坐标,可以简化配置。

     1.4、引导类

    springboot的引导类是boot工程的执行入口,运行main方法就可以启动程序。springboot运行后初始化spring容器,扫描类所在的包和加载bean。

    1.5、内嵌Tomcat

    内嵌Tomcat,将Tomcat容器以对象的形式在SpringBoot容器中运行,如果不想用这个服务器,可以用exclusion排除掉,再添加新的服务器即可。

     二、REST风格补充

    2.1、REST风格简介

    REST全称是表现形式状态转换,其实就是设置访问资源的描述形式。

     REST风格是隐藏资源的访问行为的,一般的使用如下动作行为区分对资源做了何种操作。

     2.2、Restful风格入门案例

    请求就是隐藏了访问路径的具体动作,使用method指定访问动作即可。

     对于又请求参数的,需要设置路劲参数,具体如下:

    三种接收参数传递的注解,@PathVariable一般用于接收单个路径参数,@RequetBody一般用于接收封装好的json数据,最后一种用于接收非json数据,用的较少。

    使用Restful进行增删改查的代码如下:

    1. import com.domain.User;
    2. import org.springframework.stereotype.Controller;
    3. import org.springframework.web.bind.annotation.*;
    4. @Controller
    5. public class UserController {
    6. //保存用户信息
    7. @RequestMapping(value = "/users",method = RequestMethod.POST)
    8. @ResponseBody
    9. public String save(){
    10. System.out.println("user save ...");
    11. return "{'module':'user save'}" ;
    12. }
    13. //删除指定id的用户信息
    14. @RequestMapping(value = "/users/{id}",method = RequestMethod.DELETE)
    15. @ResponseBody
    16. public String delete(@PathVariable Integer id){
    17. System.out.println("user delete ...");
    18. return "{'module':'user delete'}" ;
    19. }
    20. //添加用户数据
    21. @RequestMapping(value = "/users", method = RequestMethod.PUT)
    22. @ResponseBody
    23. public String update(@RequestBody User user){
    24. System.out.println("user update ...");
    25. return "{'module':'user update'}" ;
    26. }
    27. //查询指定id的用户
    28. @RequestMapping(value = "/users/{id}", method = RequestMethod.GET)
    29. @ResponseBody
    30. public String getById(@PathVariable Integer id){
    31. System.out.println("user getById ...");
    32. return "{'module':'user getById'}" ;
    33. }
    34. //查询所有用户的信息
    35. @RequestMapping(value = "/users", method = RequestMethod.GET)
    36. @ResponseBody
    37. public String getAll(){
    38. System.out.println("user getAll");
    39. return "{'module':'user getAll'}" ;
    40. }
    41. }

    2.3、Restful快速开发

    两个注解,如下,是两个注解的组合。

    两外是请求映射注解的四个,如下:

    简化后的增删改查如下:

    1. import com.domain.User;
    2. import org.springframework.web.bind.annotation.*;
    3. @RequestMapping("/users")
    4. @RestController //该注解是Controller和ResponseBody注解的组合
    5. public class UserController {
    6. //保存用户信息
    7. //@RequestMapping(method = RequestMethod.POST)
    8. @PostMapping
    9. public String save(){
    10. System.out.println("user save ...");
    11. return "{'module':'user save'}" ;
    12. }
    13. //删除指定id的用户信息
    14. //@RequestMapping(value = "/{id}",method = RequestMethod.DELETE)
    15. @DeleteMapping("/{id}")
    16. public String delete(@PathVariable Integer id){
    17. System.out.println("user delete ...");
    18. return "{'module':'user delete'}" ;
    19. }
    20. //添加用户数据
    21. //@RequestMapping( method = RequestMethod.PUT)
    22. @PutMapping
    23. public String update(@RequestBody User user){
    24. System.out.println("user update ...");
    25. return "{'module':'user update'}" ;
    26. }
    27. //查询指定id的用户
    28. //@RequestMapping(value = "/{id}", method = RequestMethod.GET)
    29. @GetMapping("/{id}")
    30. public String getById(@PathVariable Integer id){
    31. System.out.println("user getById ...");
    32. return "{'module':'user getById'}" ;
    33. }
    34. //查询所有用户的信息
    35. // @RequestMapping(method = RequestMethod.GET)
    36. @GetMapping
    37. public String getAll(){
    38. System.out.println("user getAll");
    39. return "{'module':'user getAll'}" ;
    40. }
    41. }

     三、配置修改

    3.1、属性配置方式

    直接在application.properties中修改就可以,比如修改服务器端口号,如下:

    1. #修改服务器端口号
    2. server.port=80

    3.2、文件配置格式及优先级

    springboot中有三种文件配置格式,三种都可以用,优先级properties>yml>yaml

    3.3、yaml基本语法规则

    就是简单的层级关系,注意冒号后面与数据之间需要一个空格即可。

    另外,在yaml中表示数组,可以使用减号作为开始,也可以直接用中括号,如下:

     3.4、yaml读取单一属性数据

    就是使用@Value进行读取单个数据,里面用$符号,遇到数组用中括号读取即可。

     演示代码如下:

    1. server:
    2. port: 8080
    3. lesson:
    4. springboot
    5. subject:
    6. s1: English
    7. s2: math
    8. hobby:
    9. - running
    10. - basketball
    11. - volleyball
    12. - reading
    13. movies: ['西红柿首富','你好李焕英']
    1. import org.springframework.beans.factory.annotation.Value;
    2. import org.springframework.web.bind.annotation.GetMapping;
    3. import org.springframework.web.bind.annotation.RequestMapping;
    4. import org.springframework.web.bind.annotation.RestController;
    5. @RestController
    6. @RequestMapping("/books")
    7. public class BookController {
    8. @Value("${lesson}")
    9. private String lessonName ;
    10. @Value("${hobby[2]}")
    11. private String hobby ;
    12. @Value("${subject.s2}")
    13. private String subject ;
    14. @Value("${movies[1]}")
    15. private String movies ;
    16. @GetMapping("/print")
    17. public String print(){
    18. System.out.println(lessonName);
    19. System.out.println(hobby);
    20. System.out.println(subject);
    21. System.out.println(movies);
    22. return "success !!!" ;
    23. }
    24. }

    3.5、读取yaml全部属性数据

    使用Enviroment对象封装全部配置信息,使用@Autowired注解自动装配数据到Enviroment对象中。

    1. import org.springframework.beans.factory.annotation.Autowired;
    2. import org.springframework.core.env.Environment;
    3. import org.springframework.web.bind.annotation.GetMapping;
    4. import org.springframework.web.bind.annotation.RequestMapping;
    5. import org.springframework.web.bind.annotation.RestController;
    6. @RestController
    7. @RequestMapping("/books")
    8. public class BookController {
    9. //封装全部数据到Enviroment对象中
    10. @Autowired
    11. private Environment environment ;
    12. @GetMapping("/print")
    13. public String print(){
    14. System.out.println(environment.getProperty("lesson"));
    15. System.out.println(environment.getProperty("hobby[1]"));
    16. return "success !!!" ;
    17. }
    18. }

    3.6、读取yaml引用类型数据

    使用注解绑定配置信息到封装类,另外需要将封装类定义为bean,然后将bean注入。

     yaml文件的配置如下:

    1. datasource:
    2. driver: com.mysql.jdbc.Driver
    3. username: root
    4. password: 123456

    将配置信息封装到类中,再将类变成bean,交给Spring管理。

    1. import org.springframework.boot.context.properties.ConfigurationProperties;
    2. import org.springframework.stereotype.Component;
    3. @Component //将该类变成bean,可以进行依赖注入
    4. @ConfigurationProperties(prefix = "datasource") //绑定yaml文件中的datasource配置到该类中
    5. public class MyDataSource {
    6. private String driver ;
    7. private String username ;
    8. private String password ;
    9. public String getDriver() {
    10. return driver;
    11. }
    12. public void setDriver(String driver) {
    13. this.driver = driver;
    14. }
    15. public String getUsername() {
    16. return username;
    17. }
    18. public void setUsername(String username) {
    19. this.username = username;
    20. }
    21. public String getPassword() {
    22. return password;
    23. }
    24. public void setPassword(String password) {
    25. this.password = password;
    26. }
    27. @Override
    28. public String toString() {
    29. return "MyDataSource{" +
    30. "driver='" + driver + '\'' +
    31. ", username='" + username + '\'' +
    32. ", password='" + password + '\'' +
    33. '}';
    34. }
    35. }

    四、SpringBoot整合第三方技术

    4.1、整合junit

    springboot整合junit主要包含下面三个步骤,具体如下,其实第一步都是自动生成的。

     创建接口和实现类,并进行测试。

    1. public interface BookDao {
    2. public void save() ;
    3. }
    1. import org.springframework.stereotype.Repository;
    2. @Repository
    3. public class BookImpl implements BookDao {
    4. @Override
    5. public void save() {
    6. System.out.println("save ...");
    7. }
    8. }

    注入测试对象,调用测方法。

    1. import com.dao.BookDao;
    2. import org.junit.jupiter.api.Test;
    3. import org.springframework.beans.factory.annotation.Autowired;
    4. import org.springframework.boot.test.context.SpringBootTest;
    5. @SpringBootTest
    6. class DemoApplicationTests {
    7. //注入要测试的对象
    8. @Autowired
    9. private BookDao bookDao ;
    10. @Test
    11. void contextLoads() {
    12. //执行测试对象相应的方法
    13. bookDao.save();
    14. }
    15. }

    注:若测试类如果存在于引导类的包或者子包中无需指定引导类。

    测试类不存在于引导类的包或者子包中需要使用classes属性执行引导类。

    4.2、整合MyBatis

    创建mybatis所需环境,在application.yml文件配置数据源,用于连接数据库。

    1. spring:
    2. datasource:
    3. driver-class-name: com.mysql.cj.jdbc.Driver
    4. url: jdbc:mysql://localhost:3306/test
    5. username: root
    6. password: 123456

    创建一个Goods实体类,如下:

    1. public class Goods {
    2. private Integer id ;
    3. private String name ;
    4. private Integer count ;
    5. private Double price ;
    6. public Integer getId() {
    7. return id;
    8. }
    9. public void setId(Integer id) {
    10. this.id = id;
    11. }
    12. public String getName() {
    13. return name;
    14. }
    15. public void setName(String name) {
    16. this.name = name;
    17. }
    18. public Integer getCount() {
    19. return count;
    20. }
    21. public void setCount(Integer count) {
    22. this.count = count;
    23. }
    24. public Double getPrice() {
    25. return price;
    26. }
    27. public void setPrice(Double price) {
    28. this.price = price;
    29. }
    30. @Override
    31. public String toString() {
    32. return "Goods{" +
    33. "id=" + id +
    34. ", name='" + name + '\'' +
    35. ", count=" + count +
    36. ", price=" + price +
    37. '}';
    38. }
    39. }

    写个接口,添加Mapper注解映射,并标记为Bean对象。

    1. import com.mybatis02.domain.Goods;
    2. import org.apache.ibatis.annotations.Mapper;
    3. import org.apache.ibatis.annotations.Select;
    4. import org.springframework.stereotype.Repository;
    5. import java.util.List;
    6. @Repository
    7. @Mapper
    8. public interface BookDao {
    9. @Select("select * from product")
    10. public List getAll() ;
    11. }

    在测试类中中注入bean,调用方法完成测试。

    1. import com.mybatis02.dao.BookDao;
    2. import com.mybatis02.dao.BookDaoImpl;
    3. import org.junit.jupiter.api.Test;
    4. import org.springframework.beans.factory.annotation.Autowired;
    5. import org.springframework.boot.test.context.SpringBootTest;
    6. @SpringBootTest
    7. class Mybatis02ApplicationTests {
    8. @Autowired
    9. private BookDao bookDao ;
    10. @Test
    11. void contextLoads() {
    12. System.out.println(bookDao.getAll());
    13. }
    14. }

    4.3、整合MyBatis-Plus

    创建mybatis-Plus所需环境,在application.yml文件中进行配置数据源。

    1. spring:
    2. datasource:
    3. driver-class-name: com.mysql.cj.jdbc.Driver
    4. url: jdbc:mysql://localhost:3306/test
    5. username: root
    6. password: 123456

    创建实体类,如下:

    1. public class Product {
    2. private Integer id ;
    3. private String name ;
    4. private Integer count ;
    5. private Double price ;
    6. public Integer getId() {
    7. return id;
    8. }
    9. public void setId(Integer id) {
    10. this.id = id;
    11. }
    12. public String getName() {
    13. return name;
    14. }
    15. public void setName(String name) {
    16. this.name = name;
    17. }
    18. public Integer getCount() {
    19. return count;
    20. }
    21. public void setCount(Integer count) {
    22. this.count = count;
    23. }
    24. public Double getPrice() {
    25. return price;
    26. }
    27. public void setPrice(Double price) {
    28. this.price = price;
    29. }
    30. @Override
    31. public String toString() {
    32. return "Goods{" +
    33. "id=" + id +
    34. ", name='" + name + '\'' +
    35. ", count=" + count +
    36. ", price=" + price +
    37. '}';
    38. }
    39. }

    定义数据层的接口和映射配置,直接继承BaseMapper类,就可以直接使用增删改查方法

    1. import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    2. import com.mybatisplus.domain.Product;
    3. import org.apache.ibatis.annotations.Mapper;
    4. import org.springframework.stereotype.Repository;
    5. @Mapper
    6. @Repository
    7. public interface BookDao extends BaseMapper {
    8. }

    将bean注入,完成测试。

    1. import com.mybatisplus.dao.BookDao;
    2. import org.junit.jupiter.api.Test;
    3. import org.springframework.beans.factory.annotation.Autowired;
    4. import org.springframework.boot.test.context.SpringBootTest;
    5. @SpringBootTest
    6. class MybatisplusApplicationTests {
    7. @Autowired
    8. private BookDao bookDao ;
    9. @Test
    10. void contextLoads() {
    11. System.out.println(bookDao.selectById(1));
    12. }
    13. }

    4.4、整合Druid

    导入Druid对应的starter坐标,配置数据源,写个接口完成增删改查,最后测试。

    先导入druid的坐标,直接从该网站复制过来,放到pom.xml文件中。

    1. "1.0" encoding="UTF-8"?>
    2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    4. <modelVersion>4.0.0modelVersion>
    5. <parent>
    6. <groupId>org.springframework.bootgroupId>
    7. <artifactId>spring-boot-starter-parentartifactId>
    8. <version>2.7.5version>
    9. <relativePath/>
    10. parent>
    11. <groupId>com.druidgroupId>
    12. <artifactId>demoartifactId>
    13. <version>0.0.1-SNAPSHOTversion>
    14. <name>druidname>
    15. <description>Demo project for Spring Bootdescription>
    16. <properties>
    17. <java.version>1.8java.version>
    18. properties>
    19. <dependencies>
    20. <dependency>
    21. <groupId>org.mybatis.spring.bootgroupId>
    22. <artifactId>mybatis-spring-boot-starterartifactId>
    23. <version>2.2.2version>
    24. dependency>
    25. <dependency>
    26. <groupId>com.alibabagroupId>
    27. <artifactId>druid-spring-boot-starterartifactId>
    28. <version>1.2.14version>
    29. dependency>
    30. <dependency>
    31. <groupId>com.mysqlgroupId>
    32. <artifactId>mysql-connector-jartifactId>
    33. <scope>runtimescope>
    34. dependency>
    35. <dependency>
    36. <groupId>org.springframework.bootgroupId>
    37. <artifactId>spring-boot-starter-testartifactId>
    38. <scope>testscope>
    39. dependency>
    40. dependencies>
    41. <build>
    42. <plugins>
    43. <plugin>
    44. <groupId>org.springframework.bootgroupId>
    45. <artifactId>spring-boot-maven-pluginartifactId>
    46. plugin>
    47. plugins>
    48. build>
    49. project>

    配置数据源,如下:

    1. spring:
    2. datasource:
    3. druid:
    4. driver-class-name: com.mysql.cj.jdbc.Driver
    5. url: jdbc:mysql://localhost:3306/test?serverTimezone=UTC
    6. username: root
    7. password: 123456

    写个接口完成查找功能,然后测试即可。

    1. import com.druid.domain.Goods;
    2. import org.apache.ibatis.annotations.Mapper;
    3. import org.apache.ibatis.annotations.Select;
    4. import org.springframework.stereotype.Repository;
    5. import java.util.List;
    6. @Repository
    7. @Mapper
    8. public interface BookDao {
    9. @Select("select * from product")
    10. public List getAll() ;
    11. }
    1. import com.druid.dao.BookDao;
    2. import org.junit.jupiter.api.Test;
    3. import org.springframework.beans.factory.annotation.Autowired;
    4. import org.springframework.boot.test.context.SpringBootTest;
    5. @SpringBootTest
    6. class DruidApplicationTests {
    7. @Autowired
    8. private BookDao bookDao ;
    9. @Test
    10. void contextLoads() {
    11. System.out.println(bookDao.getAll()) ;
    12. }
    13. }

    五、基于SpringBoot的SSMP案例整合

    5.1、案例实现方案分析

     5.2、模块创建

    主要包含以下三步,在第1步是在创建springboot项目的时候导入相应的坐标,然后修改配置文件,我们不使用.properties的配置文件,我们使用.yml配置文件,同时我们修改端口号为80.

    5.3、快速创建实体类

    使用lombok可以简化开发,在pom.xml中加入lombok依赖,使用@Data注解就可以了,里面自动封装了setter和getter方法等,但是没有构造方法,如果需要还要自己写。

    1. import lombok.Data;
    2. @Data
    3. public class Product {
    4. private Integer id ;
    5. private String name ;
    6. private Integer count ;
    7. private Double price ;
    8. public Product() {
    9. }
    10. public Product(Integer id, String name, Integer count, Double price) {
    11. this.id = id;
    12. this.name = name;
    13. this.count = count;
    14. this.price = price;
    15. }
    16. }

    5.4、数据层快速开发

    首先导入mybatis-plus和druid坐标依赖,配置数据源,开发dao接口(直接继承BaseMapper),最后在测试类进行测试增删改查的api。

    1)配置依赖坐标。

    1. "1.0" encoding="UTF-8"?>
    2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    4. <modelVersion>4.0.0modelVersion>
    5. <parent>
    6. <groupId>org.springframework.bootgroupId>
    7. <artifactId>spring-boot-starter-parentartifactId>
    8. <version>2.7.5version>
    9. <relativePath/>
    10. parent>
    11. <groupId>com.itemsgroupId>
    12. <artifactId>itemartifactId>
    13. <version>0.0.1-SNAPSHOTversion>
    14. <name>itemname>
    15. <description>Demo project for Spring Bootdescription>
    16. <properties>
    17. <java.version>1.8java.version>
    18. properties>
    19. <dependencies>
    20. <dependency>
    21. <groupId>org.springframework.bootgroupId>
    22. <artifactId>spring-boot-starter-webartifactId>
    23. dependency>
    24. <dependency>
    25. <groupId>com.baomidougroupId>
    26. <artifactId>mybatis-plus-boot-starterartifactId>
    27. <version>3.5.2version>
    28. dependency>
    29. <dependency>
    30. <groupId>com.alibabagroupId>
    31. <artifactId>druid-spring-boot-starterartifactId>
    32. <version>1.2.14version>
    33. dependency>
    34. <dependency>
    35. <groupId>org.projectlombokgroupId>
    36. <artifactId>lombokartifactId>
    37. dependency>
    38. <dependency>
    39. <groupId>com.mysqlgroupId>
    40. <artifactId>mysql-connector-jartifactId>
    41. <scope>runtimescope>
    42. dependency>
    43. <dependency>
    44. <groupId>org.springframework.bootgroupId>
    45. <artifactId>spring-boot-starter-testartifactId>
    46. <scope>testscope>
    47. dependency>
    48. dependencies>
    49. <build>
    50. <plugins>
    51. <plugin>
    52. <groupId>org.springframework.bootgroupId>
    53. <artifactId>spring-boot-maven-pluginartifactId>
    54. plugin>
    55. plugins>
    56. build>
    57. project>

    2)配置数据源。

    1. server:
    2. port: 80
    3. spring:
    4. datasource:
    5. druid:
    6. driver-class-name: com.mysql.cj.jdbc.Driver
    7. url: jdbc:mysql://localhost:3306/test?serverTimezone=UTC
    8. username: root
    9. password: 123456
    10. #设置id默认自动递增
    11. mybatis-plus:
    12. global-config:
    13. db-config:
    14. id-type: auto

    3)开发Dao接口

    1. import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    2. import com.items.domain.Product;
    3. import org.apache.ibatis.annotations.Mapper;
    4. import org.springframework.stereotype.Repository;
    5. @Mapper
    6. @Repository
    7. public interface ProductDao extends BaseMapper {
    8. }

    4)编写测试类,对Dao接口的增删改查方法进行测试。

    1. import com.items.domain.Product;
    2. import org.junit.jupiter.api.Test;
    3. import org.springframework.beans.factory.annotation.Autowired;
    4. import org.springframework.boot.test.context.SpringBootTest;
    5. @SpringBootTest
    6. class DaoApplicationTests {
    7. @Autowired
    8. private ProductDao productDao ;
    9. @Test
    10. void testGetById() { //按照id查询
    11. System.out.println(productDao.selectById(2)) ;
    12. }
    13. @Test
    14. void testGetAll() { //查询所有
    15. System.out.println(productDao.selectList(null)) ;
    16. }
    17. @Test
    18. void testSave(){ //添加
    19. //如果setter和getter方法不能用,需要在设置->插件中下载lombok的差件,重启IDE就可以劣
    20. Product product = new Product() ;
    21. product.setName("测试案例1");
    22. product.setCount(1234);
    23. product.setPrice(1234.0);
    24. productDao.insert(product) ;
    25. }
    26. @Test
    27. void testUpdate(){ //修改
    28. Product product = new Product() ;
    29. product.setId(1);
    30. product.setName("修改id=1的案例");
    31. product.setCount(10000);
    32. product.setPrice(12000.00);
    33. productDao.updateById(product) ;
    34. }
    35. @Test
    36. void testDelete(){ //删除指定数据行
    37. productDao.deleteById(11) ;
    38. }
    39. }

    5.5、分页查询

    使用Ipage封装分页数据,分页操作依赖MyBatis-Plus的拦截器实现。

    设置拦截器,内部是动态拼接SQL语句。

    1. import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
    2. import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
    3. import org.springframework.context.annotation.Bean;
    4. import org.springframework.context.annotation.Configuration;
    5. @Configuration
    6. public class MPConfig {
    7. @Bean //将拦截器交给Spring管理
    8. public MybatisPlusInterceptor mybatisPlusInterceptor(){
    9. MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor() ;
    10. mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
    11. return mybatisPlusInterceptor ;
    12. }
    13. }

    使用Ipage封装分页数据,并进行查询,如下:

    1. @Test
    2. void testGetPage(){ //分页查询
    3. IPage page = new Page(1,5) ;
    4. productDao.selectPage(page,null) ;
    5. }

    5.6、数据层的按条件查询

    可以使用Querywrapper和LambdaQuerywrapper完成条件查询,所有查询封装成方法调用。

    1. @Test
    2. void testGetBy1(){ //按条件查询方式1
    3. String name = "洗衣机" ;
    4. QueryWrapper queryWrapper = new QueryWrapper<>() ;
    5. queryWrapper.like(name!=null,"name","洗衣机") ;
    6. productDao.selectList(queryWrapper) ;
    7. }
    8. @Test
    9. void testGetBy2(){ //按条件查询方式2
    10. String name = "洗衣机" ;
    11. LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>() ;
    12. queryWrapper.like(name!=null,Product::getName,name) ;
    13. productDao.selectList(queryWrapper) ;
    14. }

    5.7、业务层的开发(crud)

    首先写业务层的接口,如下:

    1. import com.baomidou.mybatisplus.core.metadata.IPage;
    2. import com.items.domain.Product;
    3. import java.util.List;
    4. public interface ProductService {
    5. Boolean save(Product product) ;
    6. Boolean update(Product product) ;
    7. Boolean delete(Integer id) ;
    8. Product getById(Integer id) ;
    9. List getAll() ;
    10. IPage getPage(Integer currentPage, Integer pageSize) ;
    11. }

    将bean注入,根据接口,写具体的实现类,如下:

    1. import com.baomidou.mybatisplus.core.metadata.IPage;
    2. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
    3. import com.items.dao.ProductDao;
    4. import com.items.domain.Product;
    5. import com.items.service.ProductService;
    6. import org.springframework.beans.factory.annotation.Autowired;
    7. import org.springframework.stereotype.Service;
    8. import java.util.List;
    9. @Service
    10. public class ProductServiceImpl implements ProductService {
    11. @Autowired
    12. private ProductDao productDao ;
    13. @Override
    14. public Boolean save(Product product) {
    15. return productDao.insert(product) > 0 ;
    16. }
    17. @Override
    18. public Boolean update(Product product) {
    19. return productDao.updateById(product) > 0 ;
    20. }
    21. @Override
    22. public Boolean delete(Integer id) {
    23. return productDao.deleteById(id) > 0 ;
    24. }
    25. @Override
    26. public Product getById(Integer id) {
    27. return productDao.selectById(id) ;
    28. }
    29. @Override
    30. public List getAll() {
    31. return productDao.selectList(null) ;
    32. }
    33. @Override
    34. public IPage getPage(Integer currentPage, Integer pageSize) {
    35. IPage page = new Page(currentPage,pageSize) ;
    36. productDao.selectPage(page,null) ;
    37. return page;
    38. }
    39. }

    最后,编写测试类完成业务层的测试,如下:

    1. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
    2. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
    3. import com.baomidou.mybatisplus.core.metadata.IPage;
    4. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
    5. import com.items.dao.ProductDao;
    6. import com.items.domain.Product;
    7. import org.junit.jupiter.api.Test;
    8. import org.springframework.beans.factory.annotation.Autowired;
    9. import org.springframework.boot.test.context.SpringBootTest;
    10. @SpringBootTest
    11. class ServiceApplicationTests {
    12. @Autowired
    13. private ProductService productService ;
    14. @Test
    15. void testGetById() { //按照id查询
    16. System.out.println(productService.getById(1)) ;
    17. }
    18. @Test
    19. void testGetAll() { //查询所有
    20. System.out.println(productService.getAll()) ;
    21. }
    22. @Test
    23. void testSave(){ //添加
    24. //如果setter和getter方法不能用,需要在设置->插件中下载lombok的差件,重启IDE就可以劣
    25. Product product = new Product() ;
    26. product.setName("测试案例1");
    27. product.setCount(1234);
    28. product.setPrice(1234.0);
    29. productService.save(product) ;
    30. }
    31. @Test
    32. void testUpdate(){ //修改
    33. Product product = new Product() ;
    34. product.setId(1);
    35. product.setName("修改id=1的案例");
    36. product.setCount(10000);
    37. product.setPrice(12000.00);
    38. productService.update(product) ;
    39. }
    40. @Test
    41. void testDelete(){ //删除指定数据行
    42. productService.delete(10) ;
    43. }
    44. @Test
    45. void testGetPage(){ //分页查询
    46. productService.getPage(1,5) ;
    47. }
    48. }

    5.8、业务层的开发(基于MyBatis-Plus构建)

    使用MP进行业务层的开发有业务层通用接口Iservice和业务层通用实现类ServiceImpl,可以帮助完成业务层的快速开发,可以在其继续添加方法,注意不要覆盖方法即可。

    1)继承Iservice接口就可以实现增删改查,内部不需要再写具体接口方法

    1. import com.baomidou.mybatisplus.extension.service.IService;
    2. import com.items.domain.Product;
    3. public interface IProductService extends IService {
    4. //这是追加的方法,原始的方法直接继承了,不用再写
    5. Boolean insert(Product product) ;
    6. Boolean modify(Product product) ;
    7. Boolean delete(Integer id) ;
    8. Product get(Integer id) ;
    9. }

    2)接口实现类,为了不重写所有的方法,可以直接继承ServiceImpl即可

    1. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    2. import com.items.dao.ProductDao;
    3. import com.items.domain.Product;
    4. import com.items.service.IProductService;
    5. import org.springframework.beans.factory.annotation.Autowired;
    6. import org.springframework.stereotype.Service;
    7. @Service
    8. public class ProductServiceImpl extends ServiceImpl implements IProductService {
    9. //里面是追加方法的实现
    10. @Autowired
    11. private ProductDao productDao ;
    12. @Override
    13. public Boolean insert(Product product) {
    14. return productDao.insert(product) > 0 ;
    15. }
    16. @Override
    17. public Boolean modify(Product product) {
    18. return productDao.updateById(product) > 0 ;
    19. }
    20. @Override
    21. public Boolean delete(Integer id) {
    22. return productDao.deleteById(id) > 0 ;
    23. }
    24. @Override
    25. public Product get(Integer id) {
    26. return productDao.selectById(id) ;
    27. }
    28. }

    3)最后创建一个测试类进行测试,如下:

    1. import com.baomidou.mybatisplus.core.metadata.IPage;
    2. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
    3. import com.items.domain.Product;
    4. import org.junit.jupiter.api.Test;
    5. import org.springframework.beans.factory.annotation.Autowired;
    6. import org.springframework.boot.test.context.SpringBootTest;
    7. @SpringBootTest
    8. class Service1ApplicationTests {
    9. @Autowired
    10. private IProductService iProductService ;
    11. @Test
    12. void testGetById() { //按照id查询
    13. System.out.println(iProductService.getById(1)) ;
    14. }
    15. @Test
    16. void testGetAll() { //查询所有
    17. System.out.println(iProductService.list()) ;
    18. }
    19. @Test
    20. void testSave(){ //添加
    21. //如果setter和getter方法不能用,需要在设置->插件中下载lombok的差件,重启IDE就可以劣
    22. Product product = new Product() ;
    23. product.setName("测试案例1");
    24. product.setCount(1234);
    25. product.setPrice(1234.0);
    26. iProductService.save(product) ;
    27. }
    28. @Test
    29. void testUpdate(){ //修改
    30. Product product = new Product() ;
    31. product.setId(1);
    32. product.setName("修改id=1的案例");
    33. product.setCount(10000);
    34. product.setPrice(12000.00);
    35. iProductService.updateById(product) ;
    36. }
    37. @Test
    38. void testDelete(){ //删除指定数据行
    39. iProductService.removeById(15) ;
    40. }
    41. @Test
    42. void testGetPage(){ //分页查询
    43. IPage page = new Page<>(1,5) ;
    44. iProductService.page(page) ;
    45. System.out.println(page.getCurrent());
    46. System.out.println(page.getSize());
    47. System.out.println(page.getTotal());
    48. System.out.println(page.getPages());
    49. System.out.println(page.getRecords());
    50. }
    51. }

    5.9、表现层标准开发

    基于Restful风格的变现层开发,新增POST,删除DELETE,修改PUT,查询GET,接收实体参数使用@RequestBody注解,接收路径变量参数使用@PathVariable注解。

    1. import com.baomidou.mybatisplus.core.metadata.IPage;
    2. import com.items.domain.Product;
    3. import com.items.service.IProductService;
    4. import org.springframework.beans.factory.annotation.Autowired;
    5. import org.springframework.web.bind.annotation.*;
    6. import java.util.List;
    7. @RestController
    8. @RequestMapping("/products")
    9. public class ProductController {
    10. @Autowired
    11. private IProductService productService ;
    12. @GetMapping
    13. public List getAll() {
    14. return productService.list() ;
    15. }
    16. @PostMapping
    17. public Boolean save(@RequestBody Product product){
    18. return productService.save(product) ;
    19. }
    20. @PutMapping
    21. public Boolean update(@RequestBody Product product){
    22. return productService.updateById(product) ;
    23. }
    24. @DeleteMapping("/{id}")
    25. public Boolean delete(@PathVariable Integer id){
    26. return productService.removeById(id) ;
    27. }
    28. @GetMapping("/{id}")
    29. public Product getById(@PathVariable Integer id){
    30. return productService.getById(id) ;
    31. }
    32. //按条件查询页面数据
    33. @GetMapping("/{currentPage}/{pageSize}")
    34. public IPage getPage(@PathVariable Integer currentPage, @PathVariable Integer pageSize){
    35. return productService.getPage(currentPage, pageSize) ;
    36. }
    37. }

    下面对表现层进行数据一致化处理,把所有的格式统一为一样的。我们需要设计表现层返回结果的模型类,用于前后端数据格式统一,也叫做前后端数据协议。

    将数据都返回成flag标记是否操作成功,object标记操作结果。

    1. import lombok.Data;
    2. @Data //可以不用写setter和getter方法之类的
    3. public class R {
    4. private Boolean flag ;
    5. private Object data ;
    6. public R() {
    7. }
    8. public R(Boolean flag) {
    9. this.flag = flag;
    10. }
    11. public R(Boolean flag, Object data) {
    12. this.flag = flag;
    13. this.data = data ;
    14. }
    15. }
    1. import com.baomidou.mybatisplus.core.metadata.IPage;
    2. import com.items.domain.Product;
    3. import com.items.service.IProductService;
    4. import com.items.utils.R;
    5. import org.springframework.beans.factory.annotation.Autowired;
    6. import org.springframework.web.bind.annotation.*;
    7. import java.util.List;
    8. @RestController
    9. @RequestMapping("/products")
    10. public class ProductController {
    11. @Autowired
    12. private IProductService productService ;
    13. @GetMapping
    14. public R getAll() {
    15. return new R(true,productService.list()) ;
    16. }
    17. @PostMapping
    18. public R save(@RequestBody Product product){
    19. return new R(productService.save(product)) ;
    20. }
    21. @PutMapping
    22. public R update(@RequestBody Product product){
    23. return new R(productService.updateById(product)) ;
    24. }
    25. @DeleteMapping("/{id}")
    26. public R delete(@PathVariable Integer id){
    27. return new R(productService.removeById(id)) ;
    28. }
    29. @GetMapping("/{id}")
    30. public R getById(@PathVariable Integer id){
    31. return new R(true , productService.getById(id)) ;
    32. }
    33. //按条件查询页面数据
    34. @GetMapping("/{currentPage}/{pageSize}")
    35. public R getPage(@PathVariable Integer currentPage, @PathVariable Integer pageSize){
    36. return new R(true, productService.getPage(currentPage, pageSize)) ;
    37. }
    38. }

    5.10、前后端协议联调

    前端发送异步请求,调用后端接口。前端页面代码如下:

    1. html>
    2. <html>
    3. <head>
    4. <meta charset="utf-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <title>基于SpringBoot整合SSM案例title>
    7. <meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport">
    8. <link rel="stylesheet" href="../plugins/elementui/index.css">
    9. <link rel="stylesheet" href="../plugins/font-awesome/css/font-awesome.min.css">
    10. <link rel="stylesheet" href="../css/style.css">
    11. head>
    12. <body class="hold-transition">
    13. <div id="app">
    14. <div class="content-header">
    15. <h1>仓库管理系统h1>
    16. div>
    17. <div class="app-container">
    18. <div class="box">
    19. <div class="filter-container">
    20. <el-input v-model="pagination.count" placeholder="数量" style="width: 200px;" class="filter-item">el-input>
    21. <el-input v-model="pagination.name" placeholder="名称" style="width: 200px;" class="filter-item">el-input>
    22. <el-input v-model="pagination.price" placeholder="价格" style="width: 200px;" class="filter-item">el-input>
    23. <el-button @click="getAll()" class="dalfBut">查询el-button>
    24. <el-button type="primary" class="butT" @click="handleCreate()">新建el-button>
    25. div>
    26. <el-table size="small" current-row-key="id" :data="dataList" stripe highlight-current-row>
    27. <el-table-column type="index" align="center" label="序号">el-table-column>
    28. <el-table-column prop="count" label="数量" align="center">el-table-column>
    29. <el-table-column prop="name" label="名称" align="center">el-table-column>
    30. <el-table-column prop="price" label="价格" align="center">el-table-column>
    31. <el-table-column label="操作" align="center">
    32. <template slot-scope="scope">
    33. <el-button type="primary" size="mini" @click="handleUpdate(scope.row)">编辑el-button>
    34. <el-button type="danger" size="mini" @click="handleDelete(scope.row)">删除el-button>
    35. template>
    36. el-table-column>
    37. el-table>
    38. <div class="pagination-container">
    39. <el-pagination
    40. class="pagiantion"
    41. @current-change="handleCurrentChange"
    42. :current-page="pagination.currentPage"
    43. :page-size="pagination.pageSize"
    44. layout="total, prev, pager, next, jumper"
    45. :total="pagination.total">
    46. el-pagination>
    47. div>
    48. <div class="add-form">
    49. <el-dialog title="新增商品" :visible.sync="dialogFormVisible">
    50. <el-form ref="dataAddForm" :model="formData" :rules="rules" label-position="right" label-width="100px">
    51. <el-row>
    52. <el-col :span="12">
    53. <el-form-item label="数量" prop="count">
    54. <el-input v-model="formData.count"/>
    55. el-form-item>
    56. el-col>
    57. <el-col :span="12">
    58. <el-form-item label="名称" prop="name">
    59. <el-input v-model="formData.name"/>
    60. el-form-item>
    61. el-col>
    62. el-row>
    63. <el-row>
    64. <el-col :span="24">
    65. <el-form-item label="价格">
    66. <el-input v-model="formData.price" type="textarea">el-input>
    67. el-form-item>
    68. el-col>
    69. el-row>
    70. el-form>
    71. <div slot="footer" class="dialog-footer">
    72. <el-button @click="cancel()">取消el-button>
    73. <el-button type ="primary" @click="handleAdd()">确定el-button>
    74. div>
    75. el-dialog>
    76. div>
    77. <div class="add-form">
    78. <el-dialog title="编辑检查项" :visible.sync="dialogFormVisible4Edit">
    79. <el-form ref="dataEditForm" :model="formData" :rules="rules" label-position="right" label-width="100px">
    80. <el-row>
    81. <el-col :span="12">
    82. <el-form-item label="数量" prop="count">
    83. <el-input v-model="formData.count"/>
    84. el-form-item>
    85. el-col>
    86. <el-col :span="12">
    87. <el-form-item label="名称" prop="name">
    88. <el-input v-model="formData.name"/>
    89. el-form-item>
    90. el-col>
    91. el-row>
    92. <el-row>
    93. <el-col :span="24">
    94. <el-form-item label="价格">
    95. <el-input v-model="formData.price" type="textarea">el-input>
    96. el-form-item>
    97. el-col>
    98. el-row>
    99. el-form>
    100. <div slot="footer" class="dialog-footer">
    101. <el-button @click="cancel()">取消el-button>
    102. <el-button type="primary" @click="handleEdit()">确定el-button>
    103. div>
    104. el-dialog>
    105. div>
    106. div>
    107. div>
    108. div>
    109. body>
    110. <script src="../js/vue.js">script>
    111. <script src="../plugins/elementui/index.js">script>
    112. <script type ="text/javascript" src="../js/jquery.min.js">script>
    113. <script src="../js/axios-0.18.0.js">script>
    114. <script>
    115. var vue = new Vue({
    116. el: '#app',
    117. data:{
    118. dataList: [],//当前页要展示的列表数据
    119. dialogFormVisible: false,//添加表单是否可见
    120. dialogFormVisible4Edit:false,//编辑表单是否可见
    121. formData: {},//表单数据
    122. rules: {//校验规则
    123. count: [{ required: true, message: '必填项', trigger: 'blur' }],
    124. name: [{ required: true, message: '必填项', trigger: 'blur' }]
    125. },
    126. pagination: {//分页相关模型数据
    127. currentPage: 1,//当前页码
    128. pageSize:10,//每页显示的记录数
    129. total:0,//总记录数
    130. count: "",
    131. name: "",
    132. price: ""
    133. }
    134. },
    135. //钩子函数,VUE对象初始化完成后自动执行
    136. created() {
    137. this.getAll();
    138. },
    139. methods: {
    140. //分页查询
    141. getAll() {
    142. // 组织参数,拼接url请求地址
    143. var paramStr = "?name=" + this.pagination.name
    144. + "&count=" + this.pagination.count
    145. + "&price=" + this.pagination.price;
    146. console.log(paramStr);
    147. axios.get("/products/" + this.pagination.currentPage + "/" + this.pagination.pageSize + paramStr).then(res => {
    148. // console.log(res.data);
    149. this.pagination.currentPage = res.data.data.current;
    150. this.pagination.pageSize = res.data.data.size;
    151. this.pagination.total = res.data.data.total;
    152. this.dataList = res.data.data.records;
    153. });
    154. },
    155. //切换页码
    156. handleCurrentChange(currentPage) {
    157. // 修改页码值为当前选中的页码值
    158. this.pagination.currentPage = currentPage;
    159. // 执行查询
    160. this.getAll();
    161. },
    162. //弹出添加窗口
    163. handleCreate() {
    164. this.dialogFormVisible = true;
    165. this.resetForm();
    166. },
    167. //重置表单
    168. resetForm() {
    169. this.formData = {};
    170. },
    171. //添加
    172. handleAdd () {
    173. axios.post("/products", this.formData).then(res => {
    174. // 判断当前操作是否成功
    175. if(res.data.flag) {
    176. // 1.关闭弹层
    177. this.dialogFormVisible = false;
    178. this.$message.success(res.data.msg);
    179. } else {
    180. this.$message.error(res.data.msg);
    181. }
    182. }).finally(() => {
    183. // 2.重新加载数据
    184. this.getAll();
    185. });
    186. },
    187. //取消
    188. cancel(){
    189. this.dialogFormVisible = false;
    190. this.dialogFormVisible4Edit = false;
    191. this.$message.info("当前操作取消!");
    192. },
    193. // 删除
    194. handleDelete(row) {
    195. // console.log(row);
    196. this.$confirm("删除的数据将不可恢复,是否继续?", "提示", {type : "info"}).then(() => {
    197. axios.delete("/products/" + row.id).then(res => {
    198. if (res.data.flag) {
    199. this.$message.success(res.data.msg);
    200. } else {
    201. this.$message.error(res.data.msg);
    202. }
    203. }).finally(() => {
    204. this.getAll();
    205. });
    206. }).catch(() => {
    207. this.$message.info("取消操作");
    208. });
    209. },
    210. //弹出编辑窗口,以便于修改操作
    211. handleUpdate(row) {
    212. // 发送异步请求
    213. axios.get("/products/" + row.id).then(res => {
    214. // console.log(res.data);
    215. if (res.data.flag && res.data.data != null) {
    216. this.dialogFormVisible4Edit = true;
    217. this.formData = res.data.data;
    218. } else {
    219. this.$message.error(res.data.msg);
    220. }
    221. }).finally(() => { //不管弹出与否,自动刷新
    222. this.getAll();
    223. });
    224. },
    225. //修改
    226. handleEdit() {
    227. axios.put("/products", this.formData).then(res => {
    228. // 判断当前操作是否成功
    229. if(res.data.flag) {
    230. // 1.关闭弹层
    231. this.dialogFormVisible4Edit = false;
    232. this.$message.success(res.data.msg);
    233. } else {
    234. this.$message.error(res.data.msg);
    235. }
    236. }).finally(() => {
    237. // 2.重新加载数据
    238. this.getAll();
    239. });
    240. },
    241. //条件查询
    242. }
    243. })
    244. script>
    245. html>

    后端的代码做了修改,加了异常处理:

    1. import org.springframework.web.bind.annotation.ExceptionHandler;
    2. import org.springframework.web.bind.annotation.RestControllerAdvice;
    3. //作为SpringMVC的异常处理
    4. @RestControllerAdvice
    5. public class ExceptionAdvice {
    6. @ExceptionHandler //拦截异常信息
    7. public R doException(Exception e){
    8. e.printStackTrace();
    9. return new R(false, "服务器故障,请您稍后再试!") ;
    10. }
    11. }

    对于业务层的添加功能,增加了添加成功和添加失败的提示信息msg,直接在前端获取。

    1. @PostMapping
    2. public R save(@RequestBody Product product){
    3. Boolean flag = productService.save(product) ;
    4. return new R(flag, flag ? "添加成功" : "添加失败") ;
    5. }
    1. public R(Boolean flag, String msg){
    2. this.flag = flag ;
    3. this.msg = msg ;
    4. }

    对于按条件查询问题,在控制层引入了实体类product,并覆盖业务层的方法和实现类。

    1. //按条件查询页面数据
    2. @GetMapping("/{currentPage}/{pageSize}")
    3. public R getPage(@PathVariable Integer currentPage, @PathVariable Integer pageSize, Product product){
    4. return new R(true, productService.getPage(currentPage, pageSize,product)) ;
    5. }
     IPage getPage(Integer currentPage, Integer pageSize, Product product);
    1. @Override
    2. public IPage getPage(Integer currentPage, Integer pageSize, Product product) {
    3. IPage iPage = new Page (currentPage,pageSize) ;
    4. LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>() ;
    5. lambdaQueryWrapper.like(Strings.isNotEmpty(product.getName()),Product::getName,product.getName()) ;
    6. lambdaQueryWrapper.like(!(product.getCount() == null), Product::getCount, product.getCount()) ;
    7. lambdaQueryWrapper.eq(!(product.getPrice() == null), Product::getPrice, product.getPrice()) ;
    8. return productDao.selectPage(iPage, lambdaQueryWrapper) ;
    9. }

    查询全部的数据页面如下:

     按数量查询如下:

    按名称查询如下:

     

    按价格查询如下:

     

    修改功能如下:

     

    删除功能如下:

     

    添加功能如下:

      

    最后的总结如下:

  • 相关阅读:
    状态管理Pinia
    财报解读:抢滩“睡眠经济”,麒盛科技如何制胜市场?
    原型-设计模式
    【Linux03-基本工具之VIM】Linux下的强大编辑器(附软件生态与yum)
    Python 例题(10)
    雷军的开源情怀
    实现打包后暴露可修改接口地址文件
    Python+Selenium做自动化测试
    SpringBoot+Jwt+Redis
    springboot+jsp+ssm助农系统农产品宣传网站设计
  • 原文地址:https://blog.csdn.net/nuist_NJUPT/article/details/127726184