源码免费下载SpringBoot整合Spring+SpringMVC+MyBatisPlus案例:图书管理系统
Posted .29.
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了源码免费下载SpringBoot整合Spring+SpringMVC+MyBatisPlus案例:图书管理系统相关的知识,希望对你有一定的参考价值。
个人简介:Java领域新星创作者;阿里云技术博主、星级博主、专家博主;正在Java学习的路上摸爬滚打,记录学习的过程~
个人主页:.29.的博客
学习社区:进去逛一逛~
SpringBoot-SSMP整合案例
一、实现方案
案例实现方案分析:
-
实体类开发 —— 使用Lombok快速制作实体类
-
Dao开发 —— 整合MyBatisPlus,制作数据层测试类
-
Service开发 —— 整合MyBatisPlus进行增量开发,制作业务层测试类
-
Controller开发 —— 基于Restful开发,使用PostMan测试接口功能
-
Controller开发 —— 前后端开发协议制作
-
页面开发 —— 基于VUE+ElementUI制作,前后端联调,页面数据处理,页面消息处理
-
- 列表、新增、修改、删除、分页、查询
-
项目异常处理
-
按条件查询 —— 页面功能调整、Controller修正功能、Service修正功能
二、案例实现
1.快速搭建springboot工程
1.快速搭建
:
2.勾选需要的起步依赖
:
2. 实体类快速开发(Lombok)
Lombok
:一个Java类库,提供了一组注解,简化了POJO实体类开发
pom.xml导入lombok依赖
:
- lombok版本由SpringBoot提供,故无需额外指定
<!--lombok依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
快速利用lombok开发实体类
:
@Data注解
:自动创建实体类属性的Getter、Setter方法
import lombok.Data;
/**
* @author .29.
* @create 2023-03-27 20:58
*/
@Data
public class Book
private int id;
private String type;
private String name;
private String description;
3.数据层开发
手动导入springboot未提供勾选的起步依赖
:
<!--手动添加MyBatisPlus的起步依赖-->
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
<!--手动添加Druid数据库连接池的起步依赖-->
<!-- https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.8</version>
</dependency>
</dependencies>
springboot配置文件
:
将配置文件修改为yml
格式后,配置相关数据源信息
# 配置端口号
server:
port: 8080
# 配置dataSource(数据源)
spring:
datasource:
druid:
username: root
password: abc123
url: jdbc:mysql://localhost:3306/springboot?useSSL=false&useUnicode=true&CharacterEncoding=utf-8
driver-class-name: com.mysql.cj.jdbc.Driver
# 配置MyBatisPlus
# table-prefix:配置表格前缀,避免无法找到表格的问题
# id-type: 配置id类型,设置为auto以配合数据库表格的自增列,若不设置,在新增时不指定自增列会报错
mybatis-plus:
global-config:
db-config:
table-prefix: tbl_
id-type: auto
# 开启MyBatisPlus日志功能(注意:配置在mybatis-plus:的下一级)
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
Mapper接口
import com.haojin.springboot.springbootssmp.domain.Book;
import org.apache.ibatis.annotations.Mapper;
/**
* @author .29.
* @create 2023-03-27 21:11
*/
@Mapper
public interface BookMapper extends BaseMapper<Book>
//只需要让Mapper接口继承BaseMapper<>,以实体类类型作为泛型,就能直接使用MyBatisPlus提供好的CRUD方法
MyBatisPlus提供的相关方法参考:
MyBatisPlus——分页功能
:
-
分页操作需要设置分页对象
IPage
-
IPage
对象中封装了分页操作的所有数据: -
- 数据(Records)
- 当前页码值(Current)
- 每页数据总量(Size)
- 最大页码值(Pages)
- 数据总量(Total)
-
@Test
public void testSelectPage()
//实现分页功能的测试
IPage page = new Page(1, 5);
bookMapper.selectPage(page,null);
//测试 获取IPage对象中封装的数据:
System.out.println(page.getCurrent());//当前页码
System.out.println(page.getSize()); //每页数据总量
System.out.println(page.getPages()); //最大页码值
System.out.println(page.getTotal()); //数据总量
System.out.println(page.getRecords());//数据
只是上述调用MyBatisPlus中提供的分页功能相关的方法还无法真正实现分页功能,MyBatisPlu是通过拦截器来实现分页的,所以需要配置拦截器。
- 分页操作时在MyBatisPlus的常规操作基础上增强得到的,内部时动态地拼写SQL语句,因此需要增强对应地功能,使用MyBatisPlus拦截器实现:
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;
/**
* @author .29.
* @create 2023-03-27 22:36
*/
//拦截器配置类
@Configuration
public class MPConfig
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor()
//创建MP拦截器的容器
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
//往容器中添加需要的拦截器,这里是实现分页功能的拦截器
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mybatisPlusInterceptor;
配置了拦截器,上文测试的分页相关功能就能顺利实现啦~
MyBatisPlus——条件查询功能
:
- 可以使用
QueryWrapper
对象封装查询条件实现条件查询功能,这里推荐使用LambdaQueryWrapper
对象——所有查询操作封装成方法调用。
@Test
public void testGetByCondition()
//设置分页规则(第一页,每页五条)
IPage page = new Page(1, 5);
//将需要查询的类型作为泛型,LambdaQueryWrapper封装了所有查询操作,可直接调用相关方法
LambdaQueryWrapper<Book> lqw = new LambdaQueryWrapper<>();
//like方法封装条件进行查询
lqw.like(Book::getName,"Spring");
//查询结果分页
bookMapper.selectPage(page,lqw);
4.业务层开发
注意
:
- Service接口名称定义为业务名称,与数据层接口名称进行区分
- 制作测试类测试Service功能是否有效
- 可使用通用接口
IService<T>
快速开发Service - 可使用通用实现类
ServiceImpl<M,T>
快速开发ServiceImpl - 可以在通用接口也基础上做功能重载或功能追加
- 注意重载时不要覆盖原始操作,避免原始提供的功能丢失
①普通方式开发
业务层接口
:
import com.haojin.springboot.springbootssmp.domain.Book;
import java.util.List;
/**
* @author .29.
* @create 2023-03-28 19:41
*/
//业务层接口
public interface BookService
//增
Boolean save(Book book);
//改
Boolean update(Book book);
//删
Boolean delete(Integer id);
//查
Book getById(Integer id);
List<Book> getAll();
//分页
IPage getPage(int currPage,int pageSize);
接口实现类
:
import com.haojin.springboot.springbootssmp.domain.Book;
import com.haojin.springboot.springbootssmp.mapper.BookMapper;
import com.haojin.springboot.springbootssmp.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author .29.
* @create 2023-03-28 19:46
*/
//业务层接口实现类
@Service
public class BookServiceImpl implements BookService
@Autowired
private BookMapper bookMapper;
//业务层方法 与 数据层方法名 尽量不相同
//新增
@Override
public Boolean save(Book book)
return bookMapper.insert(book) > 0;
//修改
@Override
public Boolean update(Book book)
return bookMapper.updateById(book) > 0;
//删除
@Override
public Boolean delete(Integer id)
return bookMapper.deleteById(id) > 0;
//根据id查询
@Override
public Book getById(Integer id)
return bookMapper.selectById(id);
//查询所有
@Override
public List<Book> getAll()
return bookMapper.selectList(null);
//分页
@Override
public IPage getPage(int currPage, int pageSize)
IPage page = new Page(currPage, pageSize);
bookMapper.selectPage(page,null);
return page;
创建测试类,测试业务层功能是否能正常运行
:
import com.haojin.springboot.springbootssmp.domain.Book;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
/**
* @author .29.
* @create 2023-03-28 19:56
*/
@SpringBootTest
public class testServiceImpl
@Autowired
private BookService bookService;
@Test
public void testSave()
Book book = new Book();
book.setType("计算机理论");
book.setName("数据结构与算法");
book.setDescription("小白的算法入门推荐书籍");
System.out.println(bookService.save(book));
@Test
public void testUpdate()
Book book = new Book();
book.setId(8);
book.setType("测试更新 类型");
book.setName("测试更新 书名");
book.setDescription("测试更新 简介");
System.out.println(bookService.update(book));
@Test
public void testDelete()
System.out.println(bookService.delete(8));
@Test
public void testGetById()
System.out.println(bookService.getById(1));
@Test
public void testGetAll()
System.out.println(bookService.getAll());
@Test
public void testGetPage()
IPage page = bookService.getPage(1, 5);
System.out.println(page.getCurrent());//当前页码
System.out.println(page.getSize()); //每页数据总量
System.out.println(page.getPages()); //最大页码值
System.out.println(page.getTotal()); //数据总量
System.out.println(page.getRecords());//数据
②快速方式开发
基于MyBatisPlus快速构建业务层接口
:
- 这里一个接口,继承IService,操作类型作为泛型,就完成了上文繁琐的业务层实现操作
import com.baomidou.mybatisplus.extension.service.IService;
import com.haojin.springboot.springbootssmp.domain.Book;
/**
* @author .29.
* @create 2023-03-28 20:25
*/
//业务层快速开发(基于MyBatisPlus构建)
public interface IBookService extends IService<Book>
//已经提供了大量通用方法
//不通用的业务层方法继续在这里定义开发即可
//分页
IPage<Book> getPage(int currPage,int pageSize);
//条件查询分页
IPage<Book> getPage(int currPage,int pageSize,Book book);
MyBatisPlus提供的通用方法
:
基于MyBatisPlus快速构建接口实现类
:
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.haojin.springboot.springbootssmp.domain.Book;
import com.haojin.springboot.springbootssmp.mapper.BookMapper;
import com.haojin.springboot.springbootssmp.service.IBookService;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author .29.
* @create 2023-03-28 20:34
*/
@Service
//基于MyBatisPlus快速构建业务层接口实现类
public class MPBookServiceImpl extends ServiceImpl<BookMapper, Book> implements IBookService
@Autowired
BookMapper bookMapper;
//自己定义的
//分页
@Override
public IPage<Book> getPage(int currPage, int pageSize)
IPage page = new Page(currPage, pageSize);
bookMapper.selectPage(page,null);
return page;
//条件查询分页
@Override
public IPage<Book> getPage(int currPage, int pageSize,Book book)
LambdaQueryWrapper<Book> lqw = new LambdaQueryWrapper<>();
lqw.like(Strings.isNotEmpty(book.getType()),Book::getType,book.getType());
lqw.like(Strings.isNotEmpty(book.getName()),Book::getName,book.getName());
lqw.like(Strings.isNotEmpty(book.getDescription()),Book::getDescription,book.getDescription());
IPage page =
文章目录
-
1.引言
在 Spring Boot项目之中,我们引入 Spring Security依赖,什么也没做,启动项目 Spring Security 就会生效,访问请求就进行了拦截。
Spring Boot 对于 Spring Security 提供了自动化配置方案,可以使用更少的配置来使用 Spring Security。
那么这个过滤器链是怎么加载和实现拦截的呢?
2.Spring Security过滤器链加载
1.2.注册名为 springSecurityFilterChain的过滤器
当 Spring Boot 项目启动后,SecurityFilterAutoConfiguration
类会加载 DelegatingFilterProxyRegistrationBean
注册过滤器,名字为 springSecurityFilterChain
。
![](https://image.cha138.com/20230304/a43cba375f354ff59b44a53d70b7274e.jpg)
注意:springSecurityFilterChain名字是固定写死的。
DelegatingFilterProxyRegistrationBean
注册成功后,该过滤器就被加载了到了注册器中。然后调用getFilter()方法生成 DelegatingFilterProxy
代理对象并注册到 IOC
中 。
![](https://image.cha138.com/20230304/2ee77db09f8a4d478fc0b4d0b3611a72.jpg)
2、查看 DelegatingFilterProxy类
我们访问项目,就会进入 DelegatingFilterProxy
类的 doFilter
方法。
DelegatingFilterProxy类本质也是一个 Filter,其间接实现了 Filter接口,但是在 doFilter中其实调用的从 Spring 容器中获取到的代理 Filter的实现类。
![](https://image.cha138.com/20230304/b86fb025d6f0440698384058da992cbc.jpg)
返回的 FilterChainProxy
对象。
由此可知,DelegatingFilterProxy
类通过 springSecurityFilterChain
这个名称,得到了一个 FilterChainProxy
过滤器,最终执行的是这个过滤器的 doFilter
方法。
验证 springSecurityFilterChain名词不能修改
查看 initDelegate方法。
![](https://image.cha138.com/20230304/64100336d44646329c121ecda43bf78b.jpg)
3.查看 FilterChainProxy类
FilterChainProxy
类本质也是一个 Filter,所以查看 doFilter
方法。留意该类里面的属性。
public class FilterChainProxy extends GenericFilterBean
private static final Log logger = LogFactory.getLog(FilterChainProxy.class);
private static final String FILTER_APPLIED =
FilterChainProxy.class.getName().concat(".APPLIED");
// 过滤器链
private List<SecurityFilterChain> filterChains;
private FilterChainProxy.FilterChainValidator filterChainValidator;
private HttpFirewall firewall;
3.1 查看 doFilterInternal方法。
惊不惊喜?15个过滤器都在这里了!
![](https://image.cha138.com/20230304/0c9d60a69e8a47ba935116613e608cd0.jpg)
3.2 查看 getFilters方法。
原来这些过滤器都被封装进 SecurityFilterChain对象中。
![](https://image.cha138.com/20230304/c9f15af37d50426a9b68962f675ffdef.jpg)
4 查看 SecurityFilterChain接口
SecurityFilterChain
类是个接口,实现类也只有一个 DefaultSecurityFilterChain
类。
DefaultSecurityFilterChain
类的构造方法,初始化了 List filters,是通过传参放进去的。
![](https://image.cha138.com/20230304/830f062b3b884adfb57ef9a6d67a0e83.jpg)
过滤器链参数是什么时候传入的?
5 查看 SpringBootWebSecurityConfiguration类
创建 Spring Security
过滤器链是交给 Spring boot
自动配置,由 SpringBootWebSecurityConfiguration
类创建注入。
![](https://image.cha138.com/20230304/dcd3ad0233ff41e4a4a8e47ea8ecffe3.jpg)
查看 WebSecurityConfigurerAdapter
类。
![](https://image.cha138.com/20230304/51fdb920fbf944d894990b52e479a138.jpg)
然后会注入 HttpSecurity对象,HttpSecurity可以理解为 Spring Security 的 http核心配置,存放 Spring Security 中的过滤器链、请求匹配路径等相关认证授权的重要方法。
然后开始创建 Spring Security 过滤器链了,是交给 Spring Boot自动配置,一共有 15个过滤器。
使用 OrderedFilter进行代理,并设置了order属性。
添加完成后,将这些过滤器再封装为 DefaultSecurityFilterChain对象。
最后通过 WebSecurityConfiguration配置加载 springSecurityFilterChain,WebSecurityConfiguration中维护了securityFilterChains属性,会存放过滤器链中所有的过滤器。
总结:
Spring boot 通过 DelegatingFilterProxyRegistrationBean
注册过滤器,名字为 springSecurityFilterChain
,并生成 DelegatingFilterProxy
代理对象并注册到 IoC中。最终真正调用 FilterChainProxy
过滤器的 doFilter
获取到 Spring Security 过滤器链
。
Spring Security的过滤器链在底层是封装在 SecurityFilterChain接口中的。
以上是关于源码免费下载SpringBoot整合Spring+SpringMVC+MyBatisPlus案例:图书管理系统的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot整合ElasticSearch和Mysql 附案例源码