spring boot


快速配置spring boot

  • spring boot是由pivotal团队提供的全新框架,主要用来简化spring boot应用的初始化搭建及开发过程简化
  1. springboot 入门程序
  2. 开发控制类
//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的优缺点

  1. spring缺点
  • 依赖设置繁琐
  • 配置繁琐
  1. spring boot的优点
  • 起步依赖(简化以来配置)
  • 自动配置(简化常用工程的相关配置)
  • 辅助功能(内置服务器)

parent

继承了spring boot的相关依赖配置

  1. 开发spring boot程序必须要继承spring-boot-starter-parent
  2. spring-boot-starter-parent中定义了若干的依赖管理
  3. 集成parent可以避免多个依赖使用相同技术时出现的以来冲突版本冲突
  4. 集成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();
	}
}
  1. 导入对应的starter
  2. 测试类使用@SpringbootTest修饰
  3. 使用自动装配的形式添加要测试的对象

整合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);
}
}

  1. 勾选对应MyBatis技术,导入相应的starter
  2. 数据连接的相关信息转化配置
  3. 数据库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修改功能

创建模块

  1. 勾选spring MVC与MySQL坐标
  2. 修改配置文件为yml格式
  3. 修改端口

实体类的开发

  • 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);
    }

}

  1. 手动导入starter坐标(2个)
  2. 配置数据源与MaBatis-Plus对应的配置
  3. 开发Dao接口(继承BaseMapper)
  4. 制作测试用例测试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;
    }

  1. 使用IPage对象封装分页数据
  2. 分页操作依赖于MyBatisPlus分页拦截器实现功能
  3. 借助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);
    }

  1. 使用Query Wrapper对象封装查询条件
  2. 推荐使用LambdaQueryWrapper对象
  3. 所有查询操作封装成方法调用
  4. 查询条件支持动态条件的拼装

业务层的开发

  • ·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);
    }

  1. Service接口名称定义成业务名称,并与Dao接口名称进行区分
  2. 制作测试测试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);
    }

  1. 使用通用接口(IService)快速开发Service
  2. 使用实现类(ServiceImpl<M,T>)快速开发ServiceImpl
  3. 在通用接口的功能上做重载或追加
  4. 注意重载时不要覆盖原始操作,避免原始提供的功能丢失

表现层开发

  • 基于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;
    }
}

  1. 设计统一返回值类型便于前端进行读取数据
  2. 返回值类型可以根据自己的需求进行自行设定,没有固定格式
  3. 返回值结果模型类用于前后端数据格式的统一,也称作前后端数据协议

命令行启动常见问题及解决方案

  • windows端口被占用
# 查询端口
netstat -ano
#查询指定的端口号
netstat -ano | findstr "端口号"
#根据进程的PID查询进程名称
tasklist |findstr "进程PID号"
#根据PID杀死任务
taskkill /F /PID "进程PID号"
#根据进程名称杀死任务
taskkill -f -t -im "进程名称"