SpringBoot学习笔记
文章目录
SpringBoot
以前学习SpringBoot时所做的笔记,发在这里是为了方便自己翻阅,不喜勿喷。
一、SpringBoot简介
1.1 SpringBoot的概述
-
什么是Spring Boot
- Spring Boot 是所有基于 Spring Framework 5.0 开发的项目。Spring Boot 的设计是为了让你尽可能快的跑起来 Spring 应用程序,并且尽可能减少你的配置文件。
- 设计目的:
- 用来简化 Spring 应用的初始搭建以及开发过程。
- 从最根本上来讲,Spring Boot 就是一些库的集合,它能够被任意项目所使用,它使用 “习惯优于配置” (项目中存在大量的配置,此外还内置一个习惯性的配置)的理念让你的项目快速运行起来。
- spring boot 其实不是什么新的框架,它默认配置了很多框架的使用方式,就像 maven 整合了所有的 jar 包,spring boot 整合了所有的框架,总结一下及几点:
- 为所有 Spring 开发提供一个更快更广泛的入门体验。
- 零配置,无冗余代码生成和XML 强制配置,遵循“约定大于配置” 。
- 集成了大量常用的第三方库的配置, Spring Boot 应用为这些第三方库提供了几乎可以零配置的开箱即用的能力。
- 提供一系列大型项目常用的非功能性特征,如嵌入服务器等。
-
SpringBoot的特点
- 为基于Spring的开发提供更快的入门体验
- 开箱即用,没有代码生成,也无需XML配置。同时也可以修改默认值来满足特定的需求
- 提供了一些大型项目中常见的非功能性特性,如嵌入式服务器、外部配置等
- SpringBoot不是对Spring功能上的增强,而是提供了一种快速使用Spring的方式
-
SpringBoot的核心功能
-
起步依赖
- 起步依赖本质上是一个Maven项目对象模型(Project Object Model,POM),定义了对其他库的传递依赖,这些东西加在一起即支持某项功能。
- 简单的说,起步依赖就是将具备某种功能的坐标打包到一起,并提供一些默认的功能。
-
自动配置
- Spring Boot的自动配置是一个运行时(更准确地说,是应用程序启动时)的过程,考虑了众多因素,才决定Spring配置应该用哪个,不该用哪个。该过程是Spring自动完成的。
-
二、SpringBoot快速入门
2.1 快速入门案例
-
创建Maven工程
-
使用idea工具创建一个maven工程
-
-
在该工程下的
pom.xml
文件中添加SpringBoot的起步依赖<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.ljf</groupId> <artifactId>springboot_demo01</artifactId> <version>1.0-SNAPSHOT</version> <!-- SpringBoot父工程,里面有很多现成的依赖,所以不需要再自己添加这些依赖了 --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.6.RELEASE</version> </parent> <dependencies> <!--web起步包,里面有很多 注意:虽然是web工程,但不需要打war包,直接打jar就行 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> </project>
-
编写SpringBoot引导类
-
SpringBoot引导类需要在所有组件类的上一层。
-
SpringBoot引导类需要使用
@SpringBootApplication
进行声明package com.ljf; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; // 声明该类是一个SpringBoot引导类 @SpringBootApplication public class Application { // main是java程序的入口 public static void main(String[] args) { // run()方法表示运行SpringBoot的引导类,run参数就是SpringBoot引导类的字节码对象 SpringApplication.run(Application.class, args); } }
-
-
编写Controller
-
必须在引导类
Application
同级包或者子级包中创建Controllerpackage com.ljf.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/hello") public class HelloController { @RequestMapping("/world") public String world(){ return "springboot 访问成功!"; } }
-
-
测试
-
执行SpringBoot起步类
Application
的主方法,控制台打印日志如下: -
通过日志发现,Tomcat started on port(s): 8080 (http) with context path ’’
- tomcat已经起步,端口监听8080,web应用的虚拟工程名称为空(默认“/”)
-
打开浏览器访问url地址为:http://localhost:8080/hello/world
-
2.2 SpringBoot工程热部署
-
我们在以往的开发中,每次修改类、页面等资源后,都是需要重新启动才生效,这样每次启动都很麻烦,浪费了大量的时间。
-
在使用SpringBoot后,只需在pom.xml文件中添加一个插件就可以实现不重启服务就能生效的功能,对于这样的功能,我们称之为热部署。
-
热部署依赖
<!-- 热部署依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency>
-
热部署插件
<build> <plugins> <!-- 热部署插件 --> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.1.6.RELEASE</version> </plugin> </plugins> </build>
-
-
开启 Intellij IEDA 自动编译,需要对IDEA进行自动编译的设置,如下:
-
正常情况下就可以进行热部署, 如果还是不行,在加入如下操作,如果已经可以热部署,就不需要看后面的操作
-
在Idea中,
Shift+Ctrl+Alt+/
, 选择Registry
-
找到以下选项,然后打勾:
-
-
2.3 使用idea快速创建SpringBoot项目
- 可以在Idea中快速创建一个SpringBoot项目
-
在选择创建项目时,选择
Spring Initializr
工程: -
进行一些基础配置
-
选择
Spring Web
-
选择工程路径
- 使用这种方式创建出的工程会自动生成 SpringBoot启动类 和 配置pom.xml文件,虽然很方便,但是由于这样创建的工程会有很多我们不需要的东西,且需要在有网的时候才有用,所以一般我们不这样创建SpringBoot项目,了解即可。
三、SpringBoot原理分析
3.1 起步依赖原理分析
-
通过查看父类
spring-boot-starter-parent
的pom.xml
文件,可以发现其右继承了另一个父工程spring-boot-starter-dependencies
,而查看这个工程的pom.xml
文件,发现这里有很多依赖。- 总结:
- 从上面的spring-boot-starter-dependencies的pom.xml中我们可以发现,一部分坐标的版本、依赖管理、插件管理已经定义好
- 所以我们的SpringBoot工程继承spring-boot-starter-parent后已经具备版本锁定等配置了(不会出现版本冲突的问题)。
- 所以起步依赖的作用就是进行依赖的传递。
- 总结:
-
通过查看web起步包
spring-boot-starter-web
工程的pom.xml
文件:- 我们可以发现,spring-boot-starter-web就是将web开发要使用的spring-web、spring-webmvc等坐标进行了“打包”
- 这样我们的工程只要引入spring-boot-starter-web起步依赖的坐标就可以进行web开发了,同样体现了依赖传递的作用
- 同时加载tomcat,只要启动main方法,就相当于起到tomcat进行开发
- 同时加载json,支持springmvc的数据请求和响应。
3.2 自动配置原理解析
3.2.1 原web.xml的中配置
-
问题提出:
- 在以往的web工程开发中,我们都需要配置一个
web.xml
文件,在其中配置过滤器、dispatcherServlet
等。 - 但在SpringBoot中却不需要配置
web.xml
文件,那么dispatcherServlet
等组件是如何配置的呢?
- 在以往的web工程开发中,我们都需要配置一个
-
问题解析:
-
其实web.xml文件中的一些配置其实都已经被SpringBoot自动配置好了
-
可以在SpringBoot的启动类中,通过
ApplicationContext.getBeanDefinitionNames()
方法查看web工程中所有的Bean对象package com.ljf; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; // 声明该类是一个SpringBoot引导类 @SpringBootApplication public class Application { // main是java程序的入口 public static void main(String[] args) { // run()方法表示运行SpringBoot的引导类,run参数就是SpringBoot引导类的字节码对象,run()方法的返回值是一个ApplicationContext对象 ApplicationContext act = SpringApplication.run(Application.class, args); // ApplicationContext.getBeanDefinitionNames()可以返回整个web工程的所有bean对象 for (String name : act.getBeanDefinitionNames()) { System.out.println(name); } } }
-
通过搜索其打印内容,可以发现里面有很多之前需要在web.xml中配置的bean对象:
-
dispatcherServlet:
-
characterEncodingFilter:
-
hiddenHttpMethodFilter:
-
-
-
3.2.2 @SpringBootApplication注解
-
SpringBoot的启动类需要使用
@SpringBootApplication
注解标识 -
通过查看
@SpringBootApplication
注解,我们可以发现这是一个复合注解:package org.springframework.boot.autoconfigure; // import... @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan( excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = {TypeExcludeFilter.class}), @Filter(type = FilterType.CUSTOM,classes = {AutoConfigurationExcludeFilter.class}) } ) public @interface SpringBootApplication { // ... }
-
在
@SpringBootApplication
注解中,最重要的复合注解是后三个:@SpringBootConfiguration // 表示当前类具有配置类的作用,用于代替配置文件 @EnableAutoConfiguration // 表示开启自动配置 @ComponentScan( // 表示自动扫描组件,等效于XML文件中的包扫描标签 excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = {TypeExcludeFilter.class}), @Filter(type = FilterType.CUSTOM,classes = {AutoConfigurationExcludeFilter.class}) } )
-
@ComponentScan
注解:-
作用:
- 表示自动扫描组件,等效于XML文件中的包扫描标签
-
注意:
-
该注解是把当前启动类所在的包作为扫描包的起点,例如启动类所在的包在
com.ljf
中,则该注解等效于:<context:component-scan base-package="com.ljf"></context:component-scan>
-
-
-
@SpringBootConfiguration
注解:- 作用:
- 表示当前类具有配置类的作用,用于代替配置文件
- 作用:
-
@EnableAutoConfiguration
注解:-
作用:
- 表示开启自动配置
-
点击查看
@EnableAutoConfiguration
注解:package org.springframework.boot.autoconfigure; // import... @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import({AutoConfigurationImportSelector.class}) public @interface EnableAutoConfiguration { String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; Class<?>[] exclude() default {}; String[] excludeName() default {}; }
-
发现
@EnableAutoConfiguration
注解引入了一个AutoConfigurationImportSelector
类,再查看该类(主要看一下三个方法):// selectImports()方法:选择性引入 public String[] selectImports(AnnotationMetadata annotationMetadata) { //... AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata); //.. } // getAutoConfigurationEntry()方法:获取自动配置项 protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata, AnnotationMetadata annotationMetadata) { // ... List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes); // ... } // getCandidateConfigurations()方法:有条件的获取配置项 protected List<String> getCandidateConfigurations()方法:有条件的获取配置项(AnnotationMetadata metadata, AnnotationAttributes attributes) { List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader()); // 在META-INF/spring.factories中找不到自动配置类。需要看看文件是否正确 Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct."); return configurations; }
- 其中,
SpringFactoriesLoader.loadFactoryNames()
方法的作用就是从META-INF/spring.factories
文件中读取指定类对应的类名称列表。
- 其中,
-
查看
spring-boot-autoconfigure-2.1.6.RELEASE.jar
包中的META-INF/spring.factories
文件:-
可以在
Auto Configure
下面全是以下Configure
类的全限定名 -
通过搜索发现,
META-INF/spring.factories
文件有标明dispatcherServlet
的配置类DispatcherServletAutoConfiguration
:org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\
-
查看
dispatcherServlet
的配置类DispatcherServletAutoConfiguration
:package org.springframework.boot.autoconfigure.web.servlet; // import @AutoConfigureOrder(-2147483648) @Configuration @ConditionalOnWebApplication( type = Type.SERVLET ) @ConditionalOnClass({DispatcherServlet.class}) @AutoConfigureAfter({ServletWebServerFactoryAutoConfiguration.class}) public class DispatcherServletAutoConfiguration { // dispatcherServlet bean对象的默认名称 public static final String DEFAULT_DISPATCHER_SERVLET_BEAN_NAME = "dispatcherServlet"; public static final String DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME = "dispatcherServletRegistration"; // ... }
-
-
3.2.3 举例自动配置
-
如何在SpringBoot中自动配置自己的类?
-
例:
-
新建包
com.atguigu.pojo
, 创建类User
package com.ljf.pojo; public class User { }
-
在
resources
文件夹下面 新建/META-INF/spring.factories
文件org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.ljf.pojo.User
-
重启项目,然后查看该项目打印的bean对象:
-
四、SpringBoot的配置文件
4.1 SpringBoot配置文件类型
-
SpringBoot是基于约定的,所以很多配置都有默认值,但如果想使用自己的配置替换默认配置的话,就可以使用application*.properties或者**application*.yml(application*.yaml)**进行配置。
-
SpringBoot默认会从Resources目录下加载application*.properties或application*.yml(application*.yaml)文件
-
这些设置可以在
pom.xml
文件中的父工程spring-boot-dependencies
中查看到:
-
-
properties配置文件:
-
properties文件是键值对类型的文件,键与值之间使用=号连接
-
例,在application.properties中对SpringBoot的tomcat的端口号进行修改:
server.port=80
-
-
具体可以修改SpringBoot的哪些配置文件,可以在 spring-boot-autoconfigure-2.1.6.RELEASE.jar 包中的 META-INF 目录下的
spring-configuration-metadata.json
文件中查找,-
以服务器端口号server.port为例:
-
4.2 application*.yml配置文件
-
yml配置文件简介
-
YML文件格式是YAML(YAML Aint Markup Language)编写的文件格式
-
YAML是一种直观的能够被电脑识别的的数据数据序列化格式,并且容易被人类阅读,容易和脚本语言交互的,可以被支持YAML库的不同的编程语言程序导入,比如: C/C++, Ruby, Python, Java, Perl, C#, PHP等。
-
YML文件是以数据为核心的,比传统的xml方式更加简洁。
-
YML文件的扩展名可以使用.yml或者.yaml。
-
-
yml配置文件的语法
-
配置普通数据
-
语法:
key: value
-
例:
name: jeff
-
注意:
- value之前有一个空格
-
-
配置对象数据
-
语法:
key: key1: value1 key2: value2 # 或者: key: {key1: value1,key2: value2}
-
例:
server: port: 18082 user: username: jeff password: 123
-
注意:
- yaml文件是按照key前面的空格区分级别的,相同缩进代表同一个级别,一般按一下tab键。
-
-
配置Map数据
-
语法:
map: key: value1 key: value2
-
-
配置数组(List、Set)数据
-
语法:
key: - value1 - value2 # 或者: key: [value1,value2]
-
例:
# 配置数据集合 city: - beijing - tianjin - shanghai - chongqing # 或者行内注入 city: [beijing,tianjin,shanghai,chongqing]
-
注意:
- -号与value之间存在一个空格
-
-
4.3 配置文件与配置类的属性映射方式
4.3.1 @ConfigurationProperties注解
-
@ConfigurationProperties
注解一般标注在组件类上,可以给组件属性赋值,所以其需要与@Component
注解(或其衍生注解)使用。 -
例:
-
对于组件类User:
package com.ljf.pojo; // import... @Component @ConfigurationProperties("user") public class User { private String username; private String password; private List<String> nicknames; private List<Mobile> mobiles; // get、set、toString方法 }
- 注意:
@ConfigurationProperties
注解需要传入yml配置文件中的key,这里是user
- 注意:
-
在application.yml文件中加入以下配置:
user: username: jeff password: 123 nicknames: - jj - ff mobiles: - num: 100 brand: 华为 - num: 101 brand: 小米
-
通过在SpringBoot的启动类中打印工程的所有bean对象:
-
再通过ApplicationContext的getBean()方法可以获取到user对象,发现属性的值与我们在配置文件中配置的值一样:
-
4.3.2 使用注解@Value映射
-
假如我们的组件类不需要使用一整个bean对象为其属性赋值,而只需要为其中的几个属性赋值,那么就可以通过
@Value
注解将配置文件中的值映射到一个Spring管理的Bean中的属性上 -
例如:
-
application.yml
配置如下:person: name: jeff addr: 南昌
-
组件类
HelloController
:package com.ljf.controller; // import... @RestController @RequestMapping("/hello") public class HelloController { @Value("${person.name}") private String name; @Value("${person.addr}") private String addr; @RequestMapping("/quick") public String quick() { return "name:"+name+",addr="+addr; } }
-
访问http://localhost/hello/quick结果:
-
-
@value注解语法:
@value("${key1.key2.....key3}") // 成员属性
五、SpringBoot与整合其他技术
5.1 SpringBoot整合Mybatis
-
pom.xml
中添加依赖(只需在原有的依赖上加入以下依赖即可):<!--mybatis起步依赖--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.1.1</version> </dependency> <!-- MySQL连接驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency>
-
application.yml配置文件:
server: # 重新指定服务器端口号 port: 80 mybatis: type-aliases-package: com.ljf.pojo # 指定mybatis别名包 mapper-locations: classpath:com/ljf/dao/*.xml # 指定xml映射文件路径 configuration: map-underscore-to-camel-case: true # 配置下划线命名到驼峰命名的自动转换 logging: level: com.ljf.dao: debug # 配置日志为debug级 spring: datasource: # 配置数据库数据源 username: root password: ljf123 url: jdbc:mysql://192.168.195.100:3306/meinian driver-class-name: com.mysql.cj.jdbc.Driver
-
注意:
- Bean类、Controller、Service、Dao.xml的写法与Spring的一致
- 只有 Dao 接口不同,需要在接口上加上
@Mapper
注解,标记该类是一个mybatis的mapper接口,可以被spring boot自动扫描到spring上下文
5.2 SpringBoot整合Junit
-
pom.xml
中添加依赖(只需在原有的依赖上加入以下依赖即可):<!--SpingBoot集成junit测试的起步依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
-
使用**@RunWit和@SpringBootTest注解**标识测试类就可以实现IOC自动注入:
package com.ljf.test; // import... @RunWith(SpringRunner.class) @SpringBootTest public class TestApplication { @Autowired private OrderService orderService; @Test public void testOrder() { List<Order> orders = orderService.findAll(); for (Order order : orders) { System.out.println(order); } } }
5.3 SpringBoot整合Spring Data JPA
5.3.1 Spring Data JPA 简介
- 什么是 JPA?
- JPA 英文名叫
Java Persistence API
,就是Java持久化API,是SUN公司推出的一套基于ORM
的规范。 - ORM:英文名为
Object-Relational Mapping
:对象关系映射- 简单来说为了不用JDBC那一套原始方法来操作数据库,ORM框架横空出世(等等)。
- 主流的ORM框架(mybatis、hibernate等)都实现了 JPA规范。
- JPA 英文名叫
- **Spring Data JPA **:
- 是 Spring Data 家族的一部分,可以轻松实现基于JPA的存储库。
- 此模块处理对基于JPA的数据访问层的增强支持, 它使构建使用数据访问技术的Spring驱动应用程序变得更加容易。
- Hibernate:
- JPA默认使用hibernat作为ORM实现,所以,一般使用Spring Data JPA即会使用Hibernate。
- Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装
- 它将POJO与数据库表建立映射关系,是一个全自动的orm框架
- hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。
- Mybatis:
- MyBatis是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射
- Spring Data JPA 和 Mybatis 的区别:
- 由于 Spring Data JPA 默认使用 Hibernate ,所以Spring Data JPA与MyBatis对比,起始也就是Hibernate与MyBatis对比。
- 从SQL语句的角度看:
- hibernate是一个自动化更强、更高级的框架
- MyBatis 在Sql语句编写方面则更灵活自由。
- 从抽象层次去看:
- 对于数据的操作,hibernate是面向对象的,而MyBatis是面向关系的
5.3.2 Spring Data JPA 的使用
-
在pom.xml导入依赖:(在原有的基础上加上这两个即可)
<!-- springBoot JPA的起步依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!-- MySQL连接驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency>
-
在application.yml中配置数据库和jpa的相关属性
server: # 重新指定服务器端口号 port: 80 logging: level: com.ljf.dao: debug # 配置日志为debug级 spring: datasource: # 配置数据库数据源 username: root password: ljf123 url: jdbc:mysql://192.168.195.100:3306/meinian driver-class-name: com.mysql.cj.jdbc.Driver jpa: # 配置 Spring Data JPA database: mysql show-sql: true generate-ddl: true hibernate: ddl-auto: update naming: # 表示使用 Hibernate 命名规则(即使用 @Table 和 @Column 注解定义的规则) physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
-
实体类Order
-
注意这里与以往的实体类不一样
package com.ljf.pojo; import javax.persistence.*; import java.util.Date; @Entity // 表示这是一个实体类 @Table(name = "t_order") // 为该实体类指定对应的数据库表的表名 public class Order { @Id // 用于指定实体类的主键 @GeneratedValue(strategy = GenerationType.IDENTITY) // 设置主键为自增长 @Column(name = "id") // 改属性对应数据库表中字段名 private Integer id; @Column(name = "member_id") private Integer memberId; @Column(name = "orderDate") private Date orderDate; @Column(name = "orderType") private String orderType; @Column(name = "orderStatus") private String orderStatus; @Column(name = "setmeal_id") private Integer setmealId; // get、set、toString方法 }
-
-
Dao接口
-
注意:需要继承 JpaRepository<T, TD> 接口,其中:
- 泛型T为对应实体类的类名
- 泛型TD为该实体类主键的类型
package com.ljf.dao; import com.ljf.pojo.Order; import org.springframework.data.jpa.repository.JpaRepository; // 需要继承 JpaRepository<T, TD> 接口,其中泛型T为对应实体类的类名,泛型TD为该实体类主键的类型 public interface OrderDao extends JpaRepository<Order, Integer> { }
-
这个接口中虽然没有方法,但是其父类接口(以及祖父接口)中定义了很多基本的方法
-
-
Service类:(与以往的没区别)
-
OrderService接口:
package com.ljf.service; import com.ljf.pojo.Order; import java.util.List; public interface OrderService { // 查询所有 List<Order> findListOrder(); // 根据id进行查询 Order findOrderById(Integer id); // 保存Order void saveOrder(Order order); // 跟新 void updateOrder(Order order); // 删除 void deleteOrderById(Integer id); }
-
OrderServiceImpl
package com.ljf.service.imp; // import @Service public class OrderServiceImpl implements OrderService { @Autowired private OrderDao orderDao; @Override public List<Order> findListOrder() { return orderDao.findAll(); } @Override public Order findOrderById(Integer id) { return orderDao.findById(id).get(); } @Override public void saveOrder(Order order) { orderDao.save(order); } @Override public void updateOrder(Order order) { orderDao.save(order); } @Override public void deleteOrderById(Integer id) { orderDao.deleteById(id); } }
-
-
SpringBoot启动类别忘了
-
测试类:
package com.ljf.test; // import... @RunWith(SpringRunner.class) @SpringBootTest public class TestService { @Autowired private OrderService orderService; @Test public void testFindListOrder() { List<Order> orders = orderService.findListOrder(); for (Order order : orders) { System.out.println(order); } } // 其他方法略... }
-
注意:
-
问题:
- 当数据库表中的字段名不是按下划线格式命名时,会出无法找到字段的问题
-
原因:
- 原因是 SpringBoot Data JPA 默认会把所有的名称转为小写,而不是使用Hibernate的 @Table 和 @Column 注解定义的规则,并且在大写字母前加上横线,比如 IsActive 翻译成 is_active。
-
解决:
-
我们应该使用 Hibernate 的命名规则,按照规则会使用 @Table 和 @Column 中的名字。
-
而使用 Hibernate 的命名规则需要在 springBoot 配置文件中加入如下规则:
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
-
-
5.4 SpringBoot整合Redis
-
找到上面的
springboot_mybatis
项目,在1pom.xml
文件中添加Redis起步依赖<!-- 配置使用redis启动器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
-
在
application.yml
文件中添加redis
的配置信息server: # 重新指定服务器端口号 port: 80 mybatis: type-aliases-package: com.ljf.pojo # 指定mybatis别名包 mapper-locations: classpath:com/ljf/dao/*.xml # 指定xml映射文件路径 logging: level: com.ljf.dao: debug # 配置日志为debug级 spring: datasource: # 配置数据库数据源 username: root password: ljf123 url: jdbc:mysql://192.168.195.100:3306/meinian driver-class-name: com.mysql.cj.jdbc.Driver redis: # 配置Redis host: 192.168.195.100 port: 6379
-
注入RedisTemplate测试redis操作
package com.ljf.service.impl; // import... @Service public class OrderServiceImpl implements OrderService { @Autowired private OrderDao orderDao; @Autowired private RedisTemplate redisTemplate; @Override public List<Order> findAll() { // redis的key String key = "alluser"; // 先查询redis中是否有数据,如果有直接返回redis的数据 List<Order> orders = (List<Order>) redisTemplate.boundValueOps(key).get(); if (orders!=null) { return orders; } // 如果没有,查询数据库 orders = orderDao.findAll(); // 将数据库数据存入到redis中 if (orders != null && orders.size()>0) { redisTemplate.boundValueOps(key).set(orders); } return orders; } }
5.5 SpringBoot整合定时任务
5.5.1 SpringBoot整合定时任务
-
创建工程
springboot_task
-
在
pom.xml
文件中添加Scheduled依赖(基本SpringBoot依赖省略)<!-- 添加 Scheduled 依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>5.0.5.RELEASE</version> </dependency>
-
创建SpringBoot启动类:
-
注意,使用定时任务需要使用 @EnableScheduling 注解标注启动类
package com.ljf; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @EnableScheduling // 定时任务需要加上这个注解 public class TaskApplication { public static void main(String[] args) { SpringApplication.run(TaskApplication.class, args); } }
-
-
创建定时任务类:
-
任务类需要被Spring扫描到,所以需要使用
@Component
等注解标注。 -
定时任务方法需要使用
@Scheduled
注解标注,在该注解中设定定时规则,可选的规则有三个:- cron:cron表达式
- fixedDelay:在上一次定时任务执行完毕后N毫秒再次执行,
- fixedRate:执行周期,执行频率,定时任务执行开始,在过N毫秒后执行,例:
* 执行A任务花了2秒,比如参数是3000,A任务执行完成之后,在过1秒后执行,
* 执行A任务花了15秒,比如参数是3000,A任务执行完成之后,立即执行。
package com.ljf.controller; // import... @Component public class TaskController { /** * @Scheduled注解: 设定定时规则,可选三种规则: * 1. cron:cron表达式 * * 2. fixedDelay:距离上一次定时任务执行完毕后N毫秒在执行, * * 3. fixedRate:执行周期,执行频率,定时任务执行开始,在过N毫秒后执行,例: * 执行A任务花了2秒,比如参数是3000,A任务执行完成之后,在过1秒后执行, * 执行A任务花了15秒,比如参数是3000,A任务执行完成之后,立即执行。 */ @Scheduled(fixedDelay = 3000) public void myTask() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println(simpleDateFormat.format(new Date())); } }
-
结果:
-
5.5.2 corn表达式
-
cron表达式:
- corn表达式分为七个域,依次分别是:
- 秒 分 时 日 月 周 年
- 每个域之间使用空格分隔
- 其中最后一个域(年)可以为空
- 每个域都有自己允许的值和一些特殊字符构成
- 使用这些特殊字符可以使我们定义的表达式更加灵活。
- corn表达式分为七个域,依次分别是:
-
下面是对这些特殊字符的介绍:
-
逗号(,):指定一个值列表
- 例如使用在月域上1,4,5,7表示1月、4月、5月和7月
-
横杠(-):指定一个范围
- 例如在时域上3-6表示3点到6点(即3点、4点、5点、6点)
-
星号(*):表示这个域上包含所有合法的值
- 例如,在月份域上使用星号意味着每个月都会触发
-
斜线(/):表示递增
- 例如使用在秒域上0/15表示每15秒
-
问号(?):只能用在日和周域上,但是不能在这两个域上同时使用,表示不指定
- 例如想在每月的20日触发调度,不管20日到底是星期几,则只能使用如下写法: 13 13 15 20 * ?, 其中最后一位只能用?,而不能使用 *,如果使用 * 表示不管星期几都会触发,实际上并不是这样。
-
井号(#):只能使用在周域上,用于指定月份中的第几周的哪一天
- 例如6#3,意思是某月的第三个周五 (6=星期五,3意味着月份中的第三周)
-
L:某域上允许的最后一个值,只能使用在日和周域上。
- 当用在日域上,表示的是在月域上指定的月份的最后一天。
- 用于周域上时,表示周的最后一天,就是星期六
-
W:W 字符代表着工作日 (星期一到星期五),只能用在日域上,它用来指定离指定日的最近的一个工作日
-
-
cron表达式在线生成器:http://cron.qqe2.com/
5.6 SpringBoot整合Thymeleaf
-
在
pom.xml
文件中加入thymeleaf起步依赖:<!-- thymeleaf 起步依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
-
在
application.yml
中设置thymeleaf
的缓存设置,设置为false。spring: thymeleaf: cache: false
-
其他与以往发开一样,唯一需要注意的是:
- 使用Ajax渲染页面时,Controller组件一般使用
@RestController
- 而使用Thymeleaf渲染页面时,Controller组件需要使用
Controller
- 使用Ajax渲染页面时,Controller组件一般使用