5、SpringBoot整合之SpringBoot整合MybatisPlus
SpringBoot整合MybatisPlus
目录(可点击直接跳转,但还是建议按照顺序观看,四部分具有一定的关联性):
首先给出四部分完整的项目结构
一、实现基础的增删改查功能
1.创建项目、选择依赖
选择Spring Web、JDBC API、MyBatis Framework、MySQL Driver
2.在pom文件中引入相关依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<!-- 修改jdbc版本 -->
<version>5.1.47</version>
<scope>runtime</scope>
</dependency>
<!-- 引入MybatisPlus的启动器 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.2</version>
</dependency>
<!-- 引入lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- 引入druid连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.6</version>
</dependency>
<!-- 引入log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
3.建库、建表、插入数据
CREATE DATABASE db_mybatisplus;
USE db_mybatisplus;
CREATE TABLE tab_teacher(
pk_teacher_id INT PRIMARY KEY AUTO_INCREMENT COMMENT '老师主键id,起始为1',
teacher_name VARCHAR(10) COMMENT '老师姓名',
teacher_sex CHAR(1) COMMENT '老师性别',
teacher_salary DOUBLE(6,1) COMMENT '老师工资'
);
-- 反复执行多次,随机插入多条数据
INSERT INTO tab_teacher VALUES(
NULL,
SUBSTR(MD5(RAND()), 1, 5),
IF(RAND()>0.5, '男', '女'),
RAND()*10000+1000
);
SELECT * FROM tab_teacher;
4.配置核心配置文件
# 配置连接数据库的四大参数
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://192.168.133.139/db_mybatisplus?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
spring.datasource.username=root
spring.datasource.password=root
# 指定连接池的类型
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
# 显示SQL语句
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
5.创建实体类
package cn.byuan.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
@NoArgsConstructor// 创建无参的构造方法
@AllArgsConstructor// 创建满参的构造方法
@Accessors(chain = true)// 使用链式方法
@Data// 重写toString方法等方法
@TableName("tab_teacher")// 对应表名
public class Teacher implements Serializable {
@TableId(value = "pk_teacher_id", type = IdType.AUTO)// 主键必须有TableId注解
private Integer teacherId;
@TableField("teacher_name")
private String teacherName;
@TableField("teacher_sex")
private String teacherSex;
@TableField("teacher_salary")
private Double teacherSalary;
}
6.创建Teacher类的dao接口,继承BaseMapper接口,使用BaseMapper接口的方法
这里我省去了mapper层,直接让dao层接口继承BaseMapper
这里要牢记一个原则:在启动类对继承BaseMapper的类进行扫描,谁继承BaseMapper类就对它进行扫描
package cn.byuan.dao;
import cn.byuan.entity.Teacher;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;
@Repository
public interface TeacherDao extends BaseMapper<Teacher> {
}
7.创建service接口及实现类
接口:
import cn.byuan.entity.Teacher;
import java.util.List;
public interface TeacherService {
// 添加一位老师
Integer addOneTeacher(Teacher teacher);
// 根据id删除一位老师
Integer deleteOneTeacherByTeacherId(Integer teacherId);
// 修改一位老师的信息
Integer updateOneTeacher(Teacher teacher);
// 根据id查询一位老师
Teacher getOneTeacherByTeacherId(Integer teacherId);
// 获取所有老师
List<Teacher> getAllTeacher();
}
实现类:
package cn.byuan.service;
import cn.byuan.dao.TeacherDao;
import cn.byuan.entity.Teacher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class TeacherServiceImp implements TeacherService{
@Autowired
private TeacherDao teacherDao;
// 添加一位老师
public Integer addOneTeacher(Teacher teacher){
return teacherDao.insert(teacher);
}
// 根据id删除一位老师
public Integer deleteOneTeacherByTeacherId(Integer teacherId){
return teacherDao.deleteById(teacherId);
}
// 修改一位老师的信息
public Integer updateOneTeacher(Teacher teacher){
return teacherDao.updateById(teacher);
}
// 根据id查询一位老师
public Teacher getOneTeacherByTeacherId(Integer teacherId){
return teacherDao.selectById(teacherId);
}
// 获取所有老师
public List<Teacher> getAllTeacher(){
return teacherDao.selectList(null);
}
}
8.在启动类对继承BaseMapper的类配置扫描
谁继承了BaseMapper就对谁进行扫描,因为之前我省去了mapper层,直接让dao层接口继承BaseMapper,因此这里扫描的是dao包
package cn.byuan;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("cn.byuan.dao")// 那一层继承了BaseMapper就对那一层进行扫描
public class Test005SpringbootMybatisplusApplication {
public static void main(String[] args) {
SpringApplication.run(Test005SpringbootMybatisplusApplication.class, args);
}
}
9.在测试类进行测试
package cn.byuan;
import cn.byuan.entity.Teacher;
import cn.byuan.service.TeacherService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class TeacherDaoOneTests {
@Autowired
private TeacherService teacherService;
@Test
void addOneTeacherTest(){
Teacher teacher = new Teacher()
.setTeacherName("test2")
.setTeacherSex("女")
.setTeacherSalary(9876.5);
teacherService.addOneTeacher(teacher);
}
@Test
void deleteOneTeacherByTeacherIdTest(){
teacherService.deleteOneTeacherByTeacherId(2);
}
@Test
void updateOneTeacher(){
Teacher teacher = new Teacher()
.setTeacherId(1)
.setTeacherName("qwe12")
.setTeacherSex("女")
.setTeacherSalary(1234.5);
teacherService.updateOneTeacher(teacher);
}
@Test
void getOneTeacherByTeacherId(){
teacherService.getOneTeacherByTeacherId(1);
}
@Test
void getAllTeacher(){
teacherService.getAllTeacher();
}
}
测试结果:
二、实现自动填充功能
自动填充功能一般可以用作记录操作发生时间,如某列的最后修改时间等,本部分代码基于第一部分:实现基础的增删改查、
1.修改数据库中的表结构
-- 修改数据库中表结构
ALTER TABLE tab_teacher ADD create_time TIMESTAMP COMMENT '记录插入时间';
ALTER TABLE tab_teacher ADD update_time TIMESTAMP COMMENT '记录修改时间';
-- 更新所有表中数据
UPDATE tab_teacher SET create_time=NOW();
UPDATE tab_teacher SET update_time=NOW();
SELECT * FROM tab_teacher;
2.修改实体类
这一步简单来说就是将增加的两列添加进Teacher类的属性中,其余与第一部分保持一致;
为实现自动填充还应在新加入的两个属性的TableField中增加"fill"属性
package cn.byuan.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
@NoArgsConstructor// 创建无参的构造方法
@AllArgsConstructor// 创建满参的构造方法
@Accessors(chain = true)// 使用链式方法
@Data// 重写toString方法等方法
@TableName("tab_teacher")// 对应表名
public class Teacher implements Serializable {
@TableId(value = "pk_teacher_id", type = IdType.AUTO)// 主键必须有TableId注解
private Integer teacherId;
@TableField("teacher_name")
private String teacherName;
@TableField("teacher_sex")
private String teacherSex;
@TableField("teacher_salary")
private Double teacherSalary;
// 增加的两列属性
@TableField(value = "create_time", fill = FieldFill.INSERT)// 插入时自动填充
private Date createTime;
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)// 插入和修改时自动填充
private Date updateTime;
}
3.创建handler层,实现MetaObjectHandler接口,重写insertFill与updateFill方法,指定填充的字段及属性值
package cn.byuan.handler;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class TeacherHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
this.strictInsertFill(metaObject, "createTime", Date.class, new Date());
this.strictInsertFill(metaObject, "updateTime", Date.class, new Date());
}
@Override
public void updateFill(MetaObject metaObject) {
this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date());
}
}
4.进行测试
这里我们只测试增加和修改两个方法
package cn.byuan;
import cn.byuan.entity.Teacher;
import cn.byuan.service.TeacherService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class TeacherDaoTwoTests {
@Autowired
private TeacherService teacherService;
@Test
void addOneTeacherTest(){
Teacher teacher = new Teacher()
.setTeacherName("test2")
.setTeacherSex("女")
.setTeacherSalary(9876.5);
teacherService.addOneTeacher(teacher);
}
@Test
void updateOneTeacher(){
Teacher teacher = new Teacher()
.setTeacherId(1)
.setTeacherName("wer23")
.setTeacherSex("女")
.setTeacherSalary(1234.5);
teacherService.updateOneTeacher(teacher);
}
}
从SQL语句可以看出,在执行update方法时,已自动为我们填充字段
数据库中新插入数据也没有问题
三、实现逻辑删除功能
数据是无价的,因此一般而言我们不会直接删除数据。对于"删除"我们一般的做法是定义一个字段来记录本行数据的可见性
1.修改数据库中的表结构
添加一个字段作为标记
-- 修改数据库中表结构, 添加一个字段作为标记
ALTER TABLE tab_teacher ADD visibility TINYINT COMMENT "0表示未删除,1表示删除";
-- 更新表中所有数据, 全部设置为未删除
UPDATE tab_teacher SET visibility=0;
2.在实体类中添加字段,并添加TableField和TableLogic两个注解
package cn.byuan.entity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
@NoArgsConstructor// 创建无参的构造方法
@AllArgsConstructor// 创建满参的构造方法
@Accessors(chain = true)// 使用链式方法
@Data// 重写toString方法等方法
@TableName("tab_teacher")// 对应表名
public class Teacher implements Serializable {
@TableId(value = "pk_teacher_id", type = IdType.AUTO)// 主键必须有TableId注解
private Integer teacherId;
@TableField("teacher_name")
private String teacherName;
@TableField("teacher_sex")
private String teacherSex;
@TableField("teacher_salary")
private Double teacherSalary;
@TableField(value = "create_time", fill = FieldFill.INSERT)// 插入时自动填充
private Date createTime;
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)// 插入和修改时自动填充
private Date updateTime;
// 新添加进来的字段
@TableField(value = "visibility", fill = FieldFill.INSERT)
@TableLogic(value = "0", delval = "1")// 指定次字段为逻辑删除字段, 默认0是未删除, 1是已删除
private Integer visibility;
}
3.在TeacherHandler中指定visibility字段的初始值
package cn.byuan.handler;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class TeacherHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
this.strictInsertFill(metaObject, "createTime", Date.class, new Date());
this.strictInsertFill(metaObject, "updateTime", Date.class, new Date());
// 新添加的字段
this.strictInsertFill(metaObject, "visibility", Integer.class, 0);
}
@Override
public void updateFill(MetaObject metaObject) {
this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date());
}
}
4.进行测试
这里只测试两个方法,一个是删除指定id值的老师,一个是根据被删除的老师id查询该老师是否可以被查询
package cn.byuan;
import cn.byuan.entity.Teacher;
import cn.byuan.service.TeacherService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class TeacherDaoThreeTests {
@Autowired
private TeacherService teacherService;
@Test
void deleteOneTeacherByTeacherIdTest(){
// 删除id为1的老师
teacherService.deleteOneTeacherByTeacherId(1);
}
@Test
void getOneTeacherByTeacherId(){
// 查询id为1的老师
teacherService.getOneTeacherByTeacherId(1);
}
}
可以看到,当我们执行delete方法时,实际上执行的是update方法
而查询语句并没有查询到该老师
数据库中id为1的老师信息依然存在
四、实现分页功能
1.创建一个配置类,通过方法返回一个PaginationInterceptor
package cn.byuan.conf;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@MapperScan("cn.byuan.dao")
public class PageConfig {
@Bean
public PaginationInterceptor PaginationInterceptor(){
return new PaginationInterceptor();
}
}
2.在service中根据selectPage方法进行分页
这里展示两种分页方式,对表中所有数据进行分页以及根据条件进行分页
接口:
package cn.byuan.service;
import cn.byuan.entity.Teacher;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import java.util.List;
public interface TeacherService {
// 添加一位老师
Integer addOneTeacher(Teacher teacher);
// 根据id删除一位老师
Integer deleteOneTeacherByTeacherId(Integer teacherId);
// 修改一位老师的信息
Integer updateOneTeacher(Teacher teacher);
// 根据id查询一位老师
Teacher getOneTeacherByTeacherId(Integer teacherId);
// 获取所有老师
List<Teacher> getAllTeacher();
// 该部分增加的方法
// 对表中所有信息进行分页, 传入参数为要查询的页数
Page<Teacher> getAllTeacherPage(Integer pageNumber);
// 按条件(性别)进行分页
Page<Teacher> getAllTeacherByTeacherSexPage(Integer pageNumber, String teacherSex);
}
实现类:
package cn.byuan.service;
import cn.byuan.dao.TeacherDao;
import cn.byuan.entity.Teacher;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class TeacherServiceImp implements TeacherService{
@Autowired
private TeacherDao teacherDao;
// 添加一位老师
public Integer addOneTeacher(Teacher teacher){
return teacherDao.insert(teacher);
}
// 根据id删除一位老师
public Integer deleteOneTeacherByTeacherId(Integer teacherId){
return teacherDao.deleteById(teacherId);
}
// 修改一位老师的信息
public Integer updateOneTeacher(Teacher teacher){
return teacherDao.updateById(teacher);
}
// 根据id查询一位老师
public Teacher getOneTeacherByTeacherId(Integer teacherId){
return teacherDao.selectById(teacherId);
}
// 获取所有老师
public List<Teacher> getAllTeacher(){
return teacherDao.selectList(null);
}
// 该部分增加的方法
// 对表中所有信息进行分页, 传入参数为要查询的页数
public Page<Teacher> getAllTeacherPage(Integer pageNumber){
QueryWrapper<Teacher> teacherQueryWrapper = new QueryWrapper<>();
Page<Teacher> teacherPage = new Page<>(pageNumber, 5);// 每页大小为5
teacherDao.selectPage(teacherPage, teacherQueryWrapper);
return teacherPage;
}
// 按条件(性别)进行分页
public Page<Teacher> getAllTeacherByTeacherSexPage(Integer pageNumber, String teacherSex){
QueryWrapper<Teacher> teacherQueryWrapper = new QueryWrapper<>();
teacherQueryWrapper.eq("teacher_sex", teacherSex);// 根据条件进行分页, 这里填写的是表中的列名
Page<Teacher> teacherPage = new Page<>(pageNumber, 5);
teacherDao.selectPage(teacherPage, teacherQueryWrapper);
return teacherPage;
}
}
3.进行测试
package cn.byuan;
import cn.byuan.entity.Teacher;
import cn.byuan.service.TeacherService;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class TeacherDaoFourTests {
@Autowired
private TeacherService teacherService;
@Test
void getAllTeacherPageTest(){
// 查看第三页
Page<Teacher> teacherPage = teacherService.getAllTeacherPage(3);
teacherPage.getRecords().forEach(System.out::println);
}
@Test
void getAllTeacherByTeacherSexPageTest(){
// 查询男生第1页的内容
Page<Teacher> teacherPage = teacherService.getAllTeacherByTeacherSexPage(1, "男");
teacherPage.getRecords().forEach(System.out::println);
}
}
测试结果
附:Page对象的一些常用方法
Page<Object> page = new Page<>(1, 6);// 指定当前页, 每页记录数
page.getCurrent();// 获取当前页
page.getTotal();// 获取总记录数
page.getSize();// 获取每页的记录数
page.getRecords();// 获取当前页数据的集合
page.getPages();// 获取总页数
page.hasNext();// 是否存在下一页
page.hasPrevious();// 是否存在上一页
源码地址:https://github.com/byuan98/springboot-integration/tree/master/test005_springboot_mybatisplus
5、SpringBoot整合之SpringBoot整合MybatisPlus的更多相关文章
- springboot+jpa+mysql+swagger整合
Springboot+jpa+MySQL+swagger整合 创建一个springboot web项目 <dependencies> <dependency> < ...
- java框架之SpringBoot(12)-消息及整合RabbitMQ
前言 概述 大多数应用中,可通过消息服务中间件来提升系统异步通信.扩展解耦的能力. 消息服务中两个重要概念:消息代理(message broker)和目的地(destination).当消息发送者发送 ...
- java框架之SpringBoot(13)-检索及整合Elasticsearch
ElasticSearch介绍 简介 我们的应用经常需要使用检索功能,开源的 Elasticsearch 是目前全文搜索引擎的首选.它可以快速的存储.搜索和分析海量数据.SpringBoot 通过整合 ...
- Springboot 2.0.4 整合Mybatis出现异常Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
在使用Springboot 2.0.4 整合Mybatis的时候出现异常Property 'sqlSessionFactory' or 'sqlSessionTemplate' are require ...
- SpringBoot Druid整合,SpringBoot 集成Druid
SpringBoot Druid整合,SpringBoot 集成Druid ================================ ©Copyright 蕃薯耀 2018年4月8日 http ...
- SpringBoot+SpringMVC+MyBatis快速整合搭建
作为开发人员,大家都知道,SpringBoot是基于Spring4.0设计的,不仅继承了Spring框架原有的优秀特性,而且还通过简化配置来进一步简化了Spring应用的整个搭建和开发过程.另外Spr ...
- SpringBoot:4.SpringBoot整合Mybatis实现数据库访问
在公司项目开发中,使用Mybatis居多.在 SpringBoot:3.SpringBoot使用Spring-data-jpa实现数据库访问 中,这种jpa风格的把sql语句和java代码放到一起,总 ...
- SpringBoot与PageHelper的整合示例详解
SpringBoot与PageHelper的整合示例详解 1.PageHelper简介 PageHelper官网地址: https://pagehelper.github.io/ 摘要: com.gi ...
- SpringBoot学习- 4、整合JWT
SpringBoot学习足迹 1.Json web token(JWT)是为了网络应用环境间传递声明而执行的一种基于JSON的开发标准(RFC 7519),该token被设计为紧凑且安全的,特别适用于 ...
- SpringBoot学习- 3、整合MyBatis
SpringBoot学习足迹 1.下载安装一个Mysql数据库及管理工具,同类工具很多,随便找一个都可以,我在windows下做测试项目习惯使用的是haosql 它内部集成了MySql-Front管理 ...
随机推荐
- 通用PE u盘装Ghost Win7系统教程
通用PE u盘装Ghost Win7系统教程 导读 通用pe工具箱是现在最老牌的的U盘装系统和维护电脑的专用工具之一,一键式制作.操作简单便捷,几乎100%支持所有U盘,不再为装机烦恼们,抓紧时间下载 ...
- SecureCRT配置自动记录日志
很多人用SecureCRT时,希望自动记录日志,一个是方便以后查阅,一个是对自己的操作有个记录.可以看看自己做了什么操作,有时甚至可以看看之前是不是犯了什么错,是个很不错的功能. 设置很简单,还可以根 ...
- NB-IOT技术与发展问答
http://blog.csdn.net/pan0755/article/details/70145936 该部分分享的是物联网各垂直应用领域里,NB-IoT技术的部署,看看适合NB-IoT技术的垂直 ...
- 《Java架构师的最佳实践》生产环境JVM调优之空间担保失败引起的FullGC
1 问题现象 应用prod-xxx-k8s,在内存足够的情况下,仍然会产生偶发FullGC的问题. JVM配置如下: -Xmx8192m -Dhsf.server.max.poolsize=2500 ...
- Python中字符串转换列表
前言:在使用Python完成工作中一些任务的时候,常常要对数据类型进行转换,比如字符串转列表,列表转字符串,字符串转元组等等,下面分享一下常用的字符串转列表 字符串转列表 第一种字符串转列表: t_s ...
- python 匹配中文字符
参考: http://hi.baidu.com/nivrrex/blog/item/e6ccaf511d0926888d543071.html http://topic.csdn. ...
- RabbitMQ(1)学习目标
一:安装,专业术语,简单队列,工作队列,发布/订阅队列,路由队列,主题队列,RPC队列,事务,确认模式,SpringAMQP 二:什么是MQ? MQ就是消息队列,是一种进程间通信或同一进程的不同线程间 ...
- Navicat Premium 15 linux 安装与激活 ArchLinux 2021
查看了很多教程花了半小时才弄好可真不容易 参考https://github.com/orginly/navicat-keygen 下载地址 http://www.navicat.com.cn/down ...
- spring模板
applicationContext <?xml version="1.0" encoding="UTF-8"?> <beans xmlns= ...
- 初遇SpringBoot踩坑与加载静态文件遇到的坑
SpringBoot开发 创建SpringBoot项目 大家都知道SpringBoot开发非常快,创建SpringBoot项目时,勾上SpringW ...