spring boot
快速配置spring boot
- spring boot是由pivotal团队提供的全新框架,主要用来简化spring boot应用的初始化搭建及开发过程简化
- springboot 入门程序
- 开发控制类
//springboot启动类
@SpringBootApplication
public class Springboot01SsmpApplication {
public static void main(String[] args) {
SpringApplication.run(Springboot01SsmpApplication.class, args);
}
3. 启动自动生成的Application类
```java
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.6.5)
2022-04-02 23:02:39.231 INFO 20320 --- [ main] c.i.Springboot0101quickstartApplication : Starting Springboot0101quickstartApplication using Java 1.8.0_312 on LAPTOP-597M71Q7 with PID 20320 (D:\WeGame\spring\springboot_desc\springboot_01_01quickstart\target\classes started by in D:\WeGame\spring\springboot_desc)
2022-04-02 23:02:39.234 INFO 20320 --- [ main] c.i.Springboot0101quickstartApplication : No active profile set, falling back to 1 default profile: "default"
2022-04-02 23:02:40.054 INFO 20320 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2022-04-02 23:02:40.062 INFO 20320 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
- 最简单的spring boot工程所包含的基础文件
- 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.6.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.itheima</groupId>
<artifactId>springboot_01_02junit</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot_01_02junit</name>
<description>springboot_01_02junit</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
- Application类
@SpringBootApplication
public class Springboot01SsmpApplication {
public static void main(String[] args) {
SpringApplication.run(Springboot01SsmpApplication.class, args);
}
spring与spring boot对比
类/配置文件 | spring | Spring boot |
pom文件中的坐标 | 手动添加 | 勾选添加 |
web3.0配置类 | 手动制作 | 无 |
spring/springMVC配置类 | 手动制作 | 无 |
控制器 | 手动制作 | 手动制作 |
注意!!!
基于idea开发Spring boot程序需要联网确保能够加载到程序框架
spring boot的优缺点
- spring缺点
- 依赖设置繁琐
- 配置繁琐
- spring boot的优点
- 起步依赖(简化以来配置)
- 自动配置(简化常用工程的相关配置)
- 辅助功能(内置服务器)
parent
继承了spring boot的相关依赖配置
- 开发spring boot程序必须要继承spring-boot-starter-parent
- spring-boot-starter-parent中定义了若干的依赖管理
- 集成parent可以避免多个依赖使用相同技术时出现的以来冲突版本冲突
- 集成parent的形式也可以采用引入依赖的形式实现效果
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
starter
spring boot常见的项目名称
- 开发spring boot程序需要导入对应坐标时通常导入对应的starter
- 每一个starter根据功能的不同,通常包含多个坐标依赖
- 使用starter可以实现快速配置的效果,以达到简化配置的目的
引导类
- spring boot的引导类是boot工程的执行入口,运行main方法就可以启动项目
- spring boot工程运行后初始化spring容器,扫描引导类所在的包加载bean
@SpringBootApplication
public class Springboot01SsmpApplication {
public static void main(String[] args) {
SpringApplication.run(Springboot01SsmpApplication.class, args);
}
内嵌tomcat
starter内部包含有tomcat
- 内嵌tomcat服务器是spring boot辅助功能之一
- 内嵌tomcat工作原理是将tomcat服务器作为对象运行,并将该对象交给spring容器处理
- 变更服务器思想是除现有服务器,欠佳全新的服务器
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
基础配置
- 属性配置
- 配置文件分类
- yaml文件
- yaml数据的读取
属性配置
- 修改服务器端口
http://localhost8080/books
http://localhost/books
- Spring boot默认配置文件application.properties,通过键值对配置对应属性
#修改服务器端口号为80
server.port=80
- 关闭运行日志图标
spring.main.banner-mode=off
- 设置日志相关
logging.level.root=debug
Spring boot内置属性查询
- 内置属性查询
- 官方文档中参考第一项:Application Properties
配置文件格式
原配置文件格式不方便读写
server.port=80
server.servlet.context-path=/
spring.banner.image.width=120
spring boot支持多种配置
- application.properties
server.port=80
- application.yml 主流
server:
port: 81
- application.yaml
server:
port: 82
spring boot配置文件的加载顺序
- application.properties >application.yml >application.yaml >
yaml
- YAML: (YAML Ain’t Markup Language) 一种数据序列化格式
- 优点:
- 容易阅读
- 容易与脚本语言交互
- 以数据为核心,重数据轻格式
- YAML文件的扩展名
- .yml(主流)
- .yaml
yaml 语法规则
- 大小写敏感
- 属性层级关系使用多行描述,每行结尾使用冒号结束
- 使用缩进表示层级关系,同层级左对齐,只允许使用空格 不能使用tab键
- 属性前添加空格 属性名与属性值之间使用冒号+空格作为分隔
#表示注释 核心规则 数据前面要加空格与冒号隔开
字面值表示方式
boolean: TRUE #TRUE,true,True,FALSE,false,False均可
float: 3.14 #6.8523015e+5 #支持科学计数法
int: 123 #0b1010_0111_0100_1010_1110 #支持二进制、八进制、十六进制
null: ~ #使用~表示null
string: HelloWorld #字符串可以直接书写
string2: "Hello World" #可以使用双引号包裹特殊字符
date: 2018-02-17 #日期必须使用yyyy-MM-dd格式
datetime: 2018-02-17T15:02:31+08:00 #时间和日期之间使用T连接,最后使用+代表时区
yaml读取数据
country: china
name: zhangsan
music:
- qw
- we
- df
user:
age: 23
name: lisi
boot读取yaml数据
@Value("${country}")
private String country;
@Value("${music[2]}")
private String music;
@Value("${user.age}")
private String name;
// 将yaml中的所有数据封装
@Autowired
private Environment env;
@Autowired
private MyDatasource myDatasource;
@GetMapping
public String save(){
System.out.println("spring running");
System.out.println("country:"+country);
System.out.println("music:"+music);
System.out.println("name:"+name);
System.out.println("--------------");
System.out.println(env.getProperty("name"));
System.out.println(env.getProperty("user.name"));
System.out.println("=============");
System.out.println("madatasource"+myDatasource);
return "spring running";
}
封装指定的数据
datasource:
driver: com.mysql.cj.jdbc.Driver
url: jdbc.mysql://localhost/db_test
username: root
password: 123456
指定的封装类
@Component
//告诉spring要装载哪些属性
@ConfigurationProperties(prefix = "datasource")
public class MyDatasource {
private String driver;
private String url;
private String username;
private String password;
spring boot 整合第三方技术
- 整合Junit
- 整合MyBatis
- 整合MyBatis-plus
- 整合Druid
整合Junit
- spring boot整合JUnit
@SpringBootTest
class Springboot07JunitApplicationTests {
@Autowired
private BookService bookService;
@Test
public void testSave(){
bookService.save();
}
}
- 导入对应的starter
- 测试类使用@SpringbootTest修饰
- 使用自动装配的形式添加要测试的对象
整合MyBatis
- 设置数据源参数
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/ssm_db
username: root
password: root
注意 :
Spring boot版本低于2.4.3,MySQL版本大于8.0,需要在url链接串时配置时区
jdbc:mysql://localhost:3306/ssm_db?serverTimezone=UTC
或者在MySQL数据库端配置时区解决此问题提
- 定义数据层接口与映射配置
@Mapper
public interface UserDao {
@Select("select * from user")
public List<User> getAll();
}
- 测试类中注入dao层接口,测试功能
@SpringBootTest
class Springboot08MybatisApplicationTests {
@Autowired
private BookDao bookDao;
@Test
public void testGetById() {
Book book = bookDao.getById(1);
System.out.println(book);
}
}
- 勾选对应MyBatis技术,导入相应的starter
- 数据连接的相关信息转化配置
- 数据库SQL映射需要添加@Mapper被容器识别到
spring boot整合mtbatis-plus
手动添加spring boot整合MyBatis-plus的坐标,可以通过mvnrepository获取
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
因为spring boot中未收录MyBatis-plus的坐标版本,需要指定对应的Version
定义数据层结构映射配置,继承BaseMapper
@Mapper
public interface UserDao extends BaseMapper<User> {
}
- 手动添加MyBatis-plus对应的starter
- 数据持久层接口使用BaseMapper简化开发
- 需要使用第三方技术无法通过勾选确定时,需要手动添加坐标
spring boot整合Druid
导入对应的starter
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.6</version>
</dependency>
- 变更Druid的配置方式
spring:
datasource:
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/ssm_db?serverTimezone=UTC
username: root
password: root
基于spring boot的SSMP整合案例
- 分析
- 实体类开发-----使用Lombok快速开发实体类
- Dao开发 -----整合MyBatis-plus,制作数据层测试类
- Service开发 ---- 基于MyBatis-plus进行增量开发,制作业务层测试类
- Controller开发 — 基于Restful开发,使用Postman测试接口功能
- Controller开发 ---- 前后端协议开发制作
- 页面开发 ----- 基于VUE ElementUI制作,前后端联调,页面数据处理,页面消息处理
- 列表、新增、修改、删除、分页、查询
- 项目异常处理---- 基于spring MVC异常处理机制
- 按条件查询----- 页面功能调整,Controller改正功能,Service修改功能
创建模块
- 勾选spring MVC与MySQL坐标
- 修改配置文件为yml格式
- 修改端口
实体类的开发
- Lombok 一个Java的类库,提供一套注解,简化POJO类的开发
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
- 版本有spring boot提供无需指定版本
- 常用的注解 @Data
@Data
@NoArgsConstructor //提供无参构造
@AllArgsConstructor //提供全参构造
public class Book {
private Integer id;
private String type;
private String name;
private String description;
}
- 为当前实体类在编译期提供对应的get/set方法,toString方法,hashCode方法,equals方法
数据层的开发
- 技术方案
- MyBatis-Plus
- Druid
- 导入MyBatis-plus与Druid对应的starter
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.6</version>
</dependency>
- 配置数据源与MyBatisPlus对应的基础配置(id的生成策略使用数据库的自增策觉)
```yaml
server:
port: 8089
spring:
datasource:
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/db_ssm?serverTimezone=GMT&characterEncoding=utf8&useUnicode=true&useSSL=false
username: root
password: 123456
# 数据库的自增策觉,表前缀,日志
mybatis-plus:
global-config:
db-config:
table-prefix: tb_
id-type: auto
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
- 继承BaseMapper并指定泛型
@Mapper
public interface BookDao extends BaseMapper<Book> {
}
- 进行测试用例
@SpringBootTest
class Springboot01SsmpApplicationTests {
@Autowired
private BookDao bookDao;
/**
* 测试根据id查询
*/
@Test
void contextLoads() {
Book book = bookDao.selectById(1);
System.out.println(book);
}
/**
* 测试查询多条
*/
@Test
public void test1(){
List<Book> bookList = bookDao.selectList(null);
for (Book book : bookList) {
System.out.println(book);
}
}
/**
* 测试分页
*/
@Test
public void test2() {
IPage<Book> page = new Page<>(1,5);
IPage<Book> bookIPage = bookDao.selectPage(page, null);
System.out.println(bookIPage.getPages());
System.out.println(bookIPage.getRecords());
}
/**
* 按条件查询
*/
@Test
public void test4(){
String name = "spring";
// QueryWrapper<Book> bookQueryWrapper = new QueryWrapper<>();
//LambdaQueryWrapper 提供了lambda减少了拼写错误
LambdaQueryWrapper<Book> wrapper = new LambdaQueryWrapper<>();
//首先判断name是否为空 为空则不使用判断
wrapper.like(Strings.isNotEmpty(name),Book::getName,name);
List<Book> bookList = bookDao.selectList(wrapper);
}
}
- 手动导入starter坐标(2个)
- 配置数据源与MaBatis-Plus对应的配置
- 开发Dao接口(继承BaseMapper)
- 制作测试用例测试Dao层的接口
数据层开发分页功能
- 分页操作需要分页对象IPage
//测试分页查询 通过
@Test
public void test5(){
IPage<Book> bookPage = new Page<>(1,5);
IPage<Book> page = bookService.page(bookPage);
// IPage<Book> page = bookService.getPage(1, 5);
System.out.println(page.getRecords());
}
- 分页对象中封装的数据
- 查询的数据
- 当前页码值
- 每页数据的总量
- 最大页码值
- 数据总量
- 分页操作是在MyBatisPlus的常规操作基础上增强得到,内部是动态的拼写SQL语句,因此需要增强对应的功能,使用MyBatisPlus拦截器实现
/**
* 配置分页插件
* @return
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
//mp的拦截器
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//添加具体拦截器
interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return interceptor;
}
- 使用IPage对象封装分页数据
- 分页操作依赖于MyBatisPlus分页拦截器实现功能
- 借助MyBatisPlus日志查阅执行SQL语句
数据持久层开发 — 条件查询功能
- 使用QueryWrapper对象封装查询条件,推荐使用LambdaQueryWrapper对象,所有查询田间封装成方法调用
/**
* 按条件查询
*/
@Test
public void test4(){
String name = "spring";
// QueryWrapper<Book> bookQueryWrapper = new QueryWrapper<>();
//LambdaQueryWrapper 提供了lambda减少了拼写错误
LambdaQueryWrapper<Book> wrapper = new LambdaQueryWrapper<>();
//首先判断name是否为空 为空则不使用判断
wrapper.like(Strings.isNotEmpty(name),Book::getName,name);
List<Book> bookList = bookDao.selectList(wrapper);
}
- 使用Query Wrapper对象封装查询条件
- 推荐使用LambdaQueryWrapper对象
- 所有查询操作封装成方法调用
- 查询条件支持动态条件的拼装
业务层的开发
- ·Service层接口定义与树局层接口定义具有较大的区别
- selectByUserNameAndPassword(String username,String password);
- login(String username,String password);
- 接口定义
/**
* 添加
* @param book
* @return
*/
boolean save(Book book);
/**
* 更新
* @param book
* @return
*/
boolean update(Book book);
- 实现类定义
@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;
}
- 定义测试
@Autowired
private IBookService bookService;
//测试查询全部 通过
@Test
public void test(){
List<Book> books = bookService.list();
for (Book book : books) {
System.out.println(book);
}
}
//测试根据di查询 通过
@Test
public void test1(){
Book book = bookService.list().get(1);
System.out.println(book);
}
//测试插入一条数据 通过
@Test
public void test2(){
Book book = new Book();
book.setName("路宝数");
book.setType("文学");
book.setDescription("深入了解日语学习");
boolean save = bookService.save(book);
System.out.println(save);
}
- Service接口名称定义成业务名称,并与Dao接口名称进行区分
- 制作测试测试Service功能是否有效
业务层快速开发
- 开发方案
- 使用MyBatisPlus提供的业务层接口(Iservice)与业务层通用实现类(ServiceImpl<M,T>)
- 在通用类基础上做功能的重载或追加
- 注意重载时不要覆盖原始操作,避免原始提供的功能丢失
- 定义快速开发接口
public interface IBookService extends IService<Book> {
/**
* 分页查询增强版
* @param currentPage
* @param pageSize
* @return
*/
IPage<Book> getPage(int currentPage, int pageSize);
- 定义快速开发实现类
@Service
public class IBookServiceImpl extends ServiceImpl<BookDao, Book> implements IBookService {
@Autowired
private BookDao bookDao;
@Override
public IPage<Book> getPage(int currentPage, int pageSize) {
IPage<Book> page = new Page<>(currentPage,pageSize);
return bookDao.selectPage(page,null);
}
- 使用通用接口(IService)快速开发Service
- 使用实现类(ServiceImpl<M,T>)快速开发ServiceImpl
- 在通用接口的功能上做重载或追加
- 注意重载时不要覆盖原始操作,避免原始提供的功能丢失
表现层开发
- 基于REST风格开发
- 使用postMan测试表现层接口
- 功能测试
@GetMapping("/{currentPage}/{pageSize}")
public R getPage(@PathVariable Integer currentPage,@PathVariable Integer pageSize, Book book){
System.out.println("book参数"+book);
IPage<Book> page = bookService.getPage(currentPage, pageSize,book);
//如果查询到的总页码值小于当前的页码,就让当前页码值等于总页码值
if (currentPage > page.getTotal()){
//在执行一次查询 对page惊醒重新赋值
page = bookService.getPage((int)page.getTotal(),pageSize,book);
}
return new R(true,page);
}
- 对表现层的树局格式进行统一
- 设计表现层返回结果的模型类,用于后端与前端进行数据格式统一,也称为前后端数据协议
public class R {
private boolean flag;
private Object data;
private String msg;
public R() {
}
public R(boolean flag){
this.flag = flag;
}
public R(boolean flag, Object data) {
this.flag = flag;
this.data = data;
}
public R( String msg) {
this.flag = false;
this.msg = msg;
}
public R(boolean flag, String msg) {
this.flag = flag;
this.msg = msg;
}
}
- 设计统一返回值类型便于前端进行读取数据
- 返回值类型可以根据自己的需求进行自行设定,没有固定格式
- 返回值结果模型类用于前后端数据格式的统一,也称作前后端数据协议
命令行启动常见问题及解决方案
- windows端口被占用
# 查询端口
netstat -ano
#查询指定的端口号
netstat -ano | findstr "端口号"
#根据进程的PID查询进程名称
tasklist |findstr "进程PID号"
#根据PID杀死任务
taskkill /F /PID "进程PID号"
#根据进程名称杀死任务
taskkill -f -t -im "进程名称"