目录:
- 模块创建
- 实体类快速开发(lombok)
- 数据层标准开发(基础CRUD)
- 开启MP运行日志
- 分页
- 数据层标准开发(条件查询)
- 业务层标准开发(基础CRUD)
- 业务层标准开发(基于MyBatisPlus构建)
- 表现层标准开发
- 表现层数据一致性处理(R对象)
- 前后端调用(axios发送异步请求)
- 列表功能
- 添加功能
- 删除功能
- 修改功能
- 异常消息处理
- 分页
- 条件查询
- 基础篇完结
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));
}
}
运行结果:
小结:
- 手工导入starter坐标(2个)
- 配置数据源与MyBatisPlus对应的配置
- 开发Dao接口(继承BaseMapper)
- 制作测试类测试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拦截器实现
小结:
- 使用IPage封装分页数据
- 分页操作依赖MyBatisPlus分页拦截器实现功能
- 借助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);
}
}
运行结果:
小结:
- 使用Querywrapper对象封装查询条件
- 推荐使用LambdaQuerywrapper对象
- 所有查询操作封装成方法调用
- 查询条件支持动态条件拼装
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>)
- 在通用类基础上做功能重载或功能追加
- 注意重载时不要覆盖原始操作,避免原始提供的功能丢失
接口定义
实现类定义
实现类追加功能
小结:
- 使用通用接口(ISerivce<T>)快速开发service
- 使用通用实现类(ServiceImpl<M,T>)快速开发ServiceImpl
- 可以在通用接口基础上做功能重载或功能追加
- 注意重载时不要覆盖原始操作,避免原始提供的功能丢失
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
设计表现层返回结果的模型类, 用于后端与前端进行数据格式统一,也称为前后端数据协议
表现层接口统一返回值类型结果
小结:
- 设计统─的返回值结果类型便于前端开发读取数据
- 返回值结果类型可以根据需求自行设定,没有固定格式
- 返回值结果模型类用于后端与前端进行数据格式统一,也称为前后端数据协议
11.前后端调用(axios发送异步请求)
项目结构:(项目地址:JavaEE: 练习的代码 - Gitee.com)
运行结果:
前后端分离结构设计中页面归属前端服务器
单体工程中页面放置在resources目录下的static目录中(建议执行clean)
前端发送异步请求,调用后端接口
小结:
- 单体项目中页面放置在resources/static目录下
- created钩子函数用于初始化页面时发起调用
- 页面使用axios发送异步请求获取数据后确认前后端是否联通
12.列表功能
列表页
运行结果:
小结:
- 将查询数据返回到页面,利用前端数据双向绑定进行数据展示
13.添加功能
弹出添加窗口
清除数据
添加
取消添加
小结:
- 请求方式使用POST调用后台对应操作
- 添加操作结束后动态刷新页面加载数据
- 根据操作结果不同,显示对应的提示信息
- 弹出添加Div时清除表单数据
14.删除功能
删除
小结:
- 请求方式使用Delete调用后台对应操作
- 删除操作需要传递当前行数据对应的id值到后台
- 删除操作结束后动态刷新页面加载数据
- 根据操作结果不同,显示对应的提示信息
- 删除操作前弹出提示框避免误操作
15.修改功能
弹出修改窗口
删除消息维护
小结:
- 加载要修改数据通过传递当前行数据对应的id值到后台查询数据
- 利用前端数据双向绑定将查询到的数据进行回显
修改
取消添加和修改
小结:
- 请求方式使用PUT调用后台对应操作
- 修改操作结束后动态刷新页面加载数据(同新增)
- 根据操作结果不同,显示对应的提示信息(同新增)
16.异常消息处理
业务操作成功或失败返回数据格式
后台代码BUG导致数据格式不统一性
对异常进行统一处理,出现异常后,返回指定信息
修改表现层返回结果的模型类,封装出现异常后对应的信息
- flag: false
- Data: null
- 消息(msg): 要显示信息
页面消息处理,没有传递消息加载默认消息,传递消息后加载指定消息
可以在表现层Controller中进行消息统一处理
目的:国际化
页面消息处理
小结:
- 使用注解@RestcontrollerAdvice定义SpringMVC异常处理器用来处理异常的
- 异常处理器必须被扫描加载,否则无法生效
- 表现层返回结果的模型类中添加消息属性用来传递消息到页面
17.分页
页面使用el分页组件添加分页功能
定义分页组件需要使用的数据并将数据绑定到分页组件
替换查询全部功能为分页功能
分页查询
使用路径参数传递分页数据或封装对象传递数据
加载分页数据
分页页码值切换
小结:
- 使用el分页组件
- 定义分页组件绑定的数据模型
- 异步调用获取分页数据
- 分页数据页面回显
对查询结果进行校验,如果当前页码值大于最大页码值,使用最大页码值作为当前页码值重新查询
小结:
- 基于业务需求维护删除功能
18.条件查询
查询条件数据封装
- 单独封装
- 与分页操作混合封装
页面数据模型绑定
组织数据成为get请求发送的数据
条件参数组织可以通过条件判定书写的更简洁
Controller接收参数
业务层接口功能开发
Controller调用业务层分页条件查询接口
页面回显数据
小结:
- 定义查询条件数据模型(当前封装到分页数据模型中)
- 异步调用分页功能并通过请求参数传递数据到后台
19.基础篇完结:
基于SpringBoot的SSMP整合案例
- pom. xml 配置起步依赖
- application. yml 设置数据源、端口、框架技术相关配置等
- dao 继承BaseMapper、设置@Mapper
- dao测试类
- service 调用数据层接口或MyBatis-Plus提供的接口快速开发
- service测试类
- controller 基于Restful开发,使用Postman测试跑通功能
- 页面 放置在resources目录下的static目录中
项目地址:JavaEE: 练习的代码 - Gitee.com