参考视频: https://www.bilibili.com/video/BV1Et411Y7tQ?p=1
官网: https://spring.io/projects/spring-boot
Spring Boot入门
简介
入门程序
- maven
```xml
org.springframework.boot 2.3.1.RELEASE spring-boot-starter-parent
- 编写主程序
![image.png](https://cdn.nlark.com/yuque/0/2020/png/1561124/1603507567382-2fb00219-9757-44f3-b9ff-f1dafd76e2f4.png#height=384&id=npbBI&margin=%5Bobject%20Object%5D&name=image.png&originHeight=768&originWidth=1767&originalType=binary&ratio=1&size=1025480&status=done&style=none&width=883.5)
```java
//标注为SpringBoot应用
@SpringBootApplication
public class Application {
public static void main(String[] args) {
//启动 Spring 应用
SpringApplication.run(Application.class,args);
}
}
- 编写控制器
- 启动应用
- 打包为jar
引入插件
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Spring Boot应用程序启动器
使用 Spring Initializer 快速创建 Spring Boot 项目
- 项目结构
Spring Boot配置
yaml
application.yml
server:
port: 8090
yaml语法
以空格的缩进来控利层级关系;只要是左对齐的一列数据,都是同一个层级的
- key和value之间必须有空格
**key: value**
- 属性和值是大小写敏感
值的写法
themeleaf + mybatis-plus + druid
spring:
devtools:
restart:
enabled: true
#热部署路径
additional-paths: src/main/java
resources:
#静态资源路径
static-locations: classpath:/static/
mvc:
#静态资源请求url
static-path-pattern: /static/**
#隐藏表单type
hiddenmethod:
filter:
enabled: true
datasource:
username: admin
password: cyl032512
url: jdbc:mysql://111.229.166.200:3306/auto_course?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
#关闭thymeleaf缓存
thymeleaf:
cache: false
mybatis-plus:
configuration:
#mp日志文件打印到控制台
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
#开启驼峰命名
map-underscore-to-camel-case: true
#xml路径
mapper-locations: classpath:/mapper/*.xml
global-config:
db-config:
logic-delete-field: deleted # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
#类别名
type-aliases-package: cn.landsall.entity
server:
servlet:
#项目根目录
context-path: /demo
port: 8080
#debug: true
从配置文件读取数据
maven
有注释处理器才有提示
<!-- 注释处理器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
元数据类
//必须先是容器的组件
@Component
//从配置文件的 person 中获取值
@ConfigurationProperties(prefix = "person")
//需要有无参构造函数
public class Person {
private String lastName = "lastName";
private Integer age = 0;
private Boolean boss = false;
private Date birth;
private Map<String, Object> maps;
private List<Object> lists;
}
application.yml
person:
last-name: cyl
age: 10
boss: true
birth: 2020/10/10
maps: {key1: value1,key2: value2}
lists:
- ppp1
- ppp2
- ppp3
通过@Autowired获得对象 ```java /*
- SpringBoot 单元测试
*/ @RunWith(SpringRunner.class) @SpringBootTest class SpringBootInitializrApplicationTests { @Autowired private Person person;
@Test void contextLoads() {
System.out.println(person);
@ConfigurationProperties和@Value的区别
- @Value常用在获取零散的简单数据
- @ConfigurationProperties常用在映射JavaBean类
@PropertySource
- @ConfigurationProperties默认从全局配置文件中获取值
加上 @PropertySource 可以指定一个配置文件
spring-config.xml ```java <?xml version=”1.0” encoding=”UTF-8”?>
<a name="8HVTj"></a>
##### @ImportResource
导入 Spring 的配置文件,让配置文件里面的内容生效
- 使用在**配置类**上
```java
@SpringBootApplication
@ImportResource(locations = {"classpath:spring-config.xml"})
通过配置类和@Bean
AppConfig
@Configuration
public class AppConfig {
//给容器添加Bean,id默认为方法名
@Bean
public ConfigServer configServer(){
return new ConfigServer();
}
}
Test
@RunWith(SpringRunner.class)
@SpringBootTest
class SpringBootInitializrApplicationTests {
@Autowired
private ApplicationContext ioc;
@Test
void contextLoads() {
System.out.println(ioc.containsBean("configServer"));
}
}
配置文件占位符
随机数
- 默认值
${person.lastName:defaultName}
不同配置环境
多个配置文件
激活指定Profile
- 在主配置文件中添加属性
spring.profiles.active=dev
dev为自定义的profile名称
spring: profiles:
active: dev
server: port: 8081
spring:
profiles: dev
server: port: 8082
spring: profiles: prod
<a name="A6luY"></a>
### 命令行参数
![image.png](https://cdn.nlark.com/yuque/0/2020/png/1561124/1603587970581-2c235bcc-4ea2-4c67-acae-4ee0048e3919.png#height=682&id=KJwFO&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1364&originWidth=2148&originalType=binary&ratio=1&size=205010&status=done&style=none&width=1074)
<a name="JHE8D"></a>
### 虚拟机参数
![image.png](https://cdn.nlark.com/yuque/0/2020/png/1561124/1603588146418-0eac42f2-6685-4ad2-ab3e-cc0bafb16194.png#height=682&id=ehnON&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1364&originWidth=2148&originalType=binary&ratio=1&size=205569&status=done&style=none&width=1074)
<a name="WZgTM"></a>
## 配置文件加载位置
![image.png](https://cdn.nlark.com/yuque/0/2020/png/1561124/1603589048913-a3fffea8-f59d-4b0d-a73c-6742e13ffebc.png#height=384&id=m8FK0&margin=%5Bobject%20Object%5D&name=image.png&originHeight=768&originWidth=1717&originalType=binary&ratio=1&size=628044&status=done&style=none&width=858.5)<br />spring.config.location 优先级最高<br />各文件形成**互补**关系
<a name="4SCx5"></a>
## 自动配置原理
[配置文件属性参照](https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html#web-properties)<br />视频: [https://www.bilibili.com/video/BV1Et411Y7tQ?p=18](https://www.bilibili.com/video/BV1Et411Y7tQ?p=18)
- @SpringBootApplication
```java
@SpringBootConfiguration
@EnableAutoConfiguration
public @interface SpringBootApplication {
@SpringBootConfiguration
@Configuration
public @interface SpringBootConfiguration {
@EnableAutoConfiguration
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration
@AutoConfigurationPackage
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {
@AutoConfigurationImportSelector
Spring Boot与日志
SpringBoot默认使用SLF4j和logback
SpringBoot自动导入了所有日志的桥接器并且底层使用slf4j和logback的日志记录方式,如果要引入其他框架(带有默认的日志实现),只需排除这个框架的日志依赖
使用默认日志框架
https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-logging
在全局配置文件配置
application.yml
logging:
level:
cn:
landsall: debug #指定包的日志级别
file:
path: logs/application #日志文件的位置(相对于当前的磁盘),默认文件名为spring.log
name: logs/application.log #日志文件名,路径可以是项目相对路径也可以是绝对路径
pattern:
console: "[%-5level] %d{yyyy-mm-dd HH:mm:ss.SSS} %c %M %L [%thread] %m%n" #控制台日志的格式
导入日志配置文件
SpringBoot会查找以下配置文件,否则使用默认的配置
SpringBoot默认配置
- 建议使用带spring后缀的文件名,让文件被SpringBoot识别而不是被日志框架识别(可以使用springProfile功能)
- spring.profiles.active=dev
切换日志实现
log4j2
- 排除spring-boot-starter-logging
- 引入spring-boot-starter-log4j2
```xml
org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-logging
<a name="sUVLD"></a>
# Spring Boot与Web开发
[文档](https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-developing-web-applications)
<a name="GvcNv"></a>
## SpringBoot对静态资源的映射规则
<a name="vd0o1"></a>
### 外部资源
jquery,bootstrap等外部资源<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/1561124/1603792791950-f568ce19-b45f-49fd-94f2-ad111a88c0c0.png#height=474&id=iEpFS&margin=%5Bobject%20Object%5D&name=image.png&originHeight=948&originWidth=1589&originalType=binary&ratio=1&size=1355104&status=done&style=none&width=794.5)<br />从[https://www.webjars.org/](https://www.webjars.org/)引入webjar
- eg
![image.png](https://cdn.nlark.com/yuque/0/2020/png/1561124/1603793549831-fd67ded7-940c-45eb-bcf9-f91ae555e2b1.png#height=108&id=Zj72r&margin=%5Bobject%20Object%5D&name=image.png&originHeight=216&originWidth=2493&originalType=binary&ratio=1&size=40923&status=done&style=none&width=1246.5)![image.png](https://cdn.nlark.com/yuque/0/2020/png/1561124/1603793850679-767dd04b-cdef-49e0-827a-c615238d6f2b.png#height=179&id=TzWNJ&margin=%5Bobject%20Object%5D&name=image.png&originHeight=358&originWidth=569&originalType=binary&ratio=1&size=175905&status=done&style=none&width=284.5)<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/1561124/1603793603634-f30923fe-14e8-466b-a7f4-e29a545b40d6.png#height=376&id=d93sY&margin=%5Bobject%20Object%5D&name=image.png&originHeight=752&originWidth=691&originalType=binary&ratio=1&size=389059&status=done&style=none&width=345.5)<br />对应访问路径http://localhost:8080/**webjars/jquery/3.5.1/jquery.js**
<a name="Scgj4"></a>
### 内部资源
图片,css,js等静态资源
在项目路径下,SpringBoot默认会根据以下顺序访问静态资源
java
classpath:/META-INF/resources/
classpath:/resources/
classpath:/static/
classpath:/public/
/:当前项目的根路径
<a name="zqK19"></a>
#### 自定义路径
- application.yml
yaml
spring:
resources:
#在何处查找静态资源
static-locations: classpath:/static/,classpath:/public/
mvc:
#以什么样的路径访问静态资源
static-path-pattern: /static/
```
### 其他资源
- 首页映射
- 在静态资源映射路径中查找index.html
- 页面图标
- 2.2.X版本之前
- 在静态资源映射路径中查找favicon.ico
- 2.2.X版本之后
-
## Thymeleaf 模板引擎
- 文档
- Spring + Thymeleaf
- Thymeleaf
- maven
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
### 配置
- ThymeleafProperties.java
java
public class ThymeleafProperties {
private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8;
//默认解析路径
public static final String DEFAULT_PREFIX = "classpath:/templates/";
//默认映射后缀
public static final String DEFAULT_SUFFIX = ".html";
}
- 语法提示
- xmlns:th=”http://www.thymeleaf.org“
html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
</body>
</html>
### 语法
https://www.yiibai.com/thymeleaf/standardurlsyntax.html
- 表达式
- ${}
- #{}
- *{}
- @{} 链接地址
-
java
@{/order/{id}/{count}(id=${id},count=${count})}
- ~{}
- 文字替代
- 内联写法
- 内置对象
- dates
- 遍历
-
- if
-
-
-
- 设置标签属性
-
-
- 公共片段
- 在Springboot中,默认读取thymeleaf文件的路径是:src/main/resource/templates,静态文件为src/main/resource/static,这个默认值可以在配置文件中修改:spring.thymeleaf.prefix=classpath:/templates/
- 属性优先级
## SpringBoot 整合JSP
- maven
xml
<!--配置jsp jstl的支持-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<!--对jsp的支持-->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<!-- 热部署 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
- application.yml
yaml
mvc:
view:
prefix: /WEB-INF/jsp/
suffix: .jsp
## Spring MVC自动配置
- 自动配置了ContentNegotiatingViewResolver和BeanNameViewResolver
- ContentNegotiatingViewResolver
- 组合所有视图解析器
- 支持提供静态资源,包括对WebJars的支持
- 自动注册Converter,GenericConverter和Formatter 的Bean类
- Converter 转换器
- Formatter 格式化器
- 表单提交 2020.12.17 ==> Date
- 支持HttpMessageConverters
- 用来转换HTTP请求和响应
- 自动注册MessageCodesResolver
- 定义错误代码生成规则
### 扩展SpringBoot WebMvc默认配置
编写配置类实现接口WebMvcConfigurer,注解@Configuration
java
@Configuration
public class SpringMvcConfig implements WebMvcConfigurer {
//实现方法
}
#### 原理
- WebMvcAutoConfiguration
- WebMvc自动配置类
- WebMvcAutoConfigurationAdapter
- WebMvcAutoConfiguration 的 内部类
- 自动配置了WebMvc
-
- EnableWebMvcConfiguration
- asd
-
- DelegatingWebMvcConfiguration
- EnableWebMvcConfiguration 父类
- 从容器中获取所有WebMvcConfigurer 赋值给 WebMvcConfigurerComposite configurers
-
-
- WebMvcConfigurerComposite
- 存放所有实现了WebMvcConfigurer的接口
-
- 并将所有配置都调用一遍
-
### 全面接管SpringMvc
为配置类添加注解@EnableWebMvc,所有SpringWeb自动配置失效
#### 原理
- @EnableWebMvc
- 导入了DelegatingWebMvcConfiguration,该类继承了WebMvcConfigurationSupport,使WebMvcAutoConfiguration不生效
-
## 创建Web项目
- 静态资源映射
- 项目根目录
- 导入模板引擎
### 国际化
- 编写国际化配置文件
- [文件基础名]_[语言代码].properties
- SpringBoot中的国际化组件 - - spring.messages ==> MessageSourceProperties - 属性
yaml
spring:
messages:
basename: i18n.login #国际化文件的基础名
- 在页面中使用国际化内容
- thyneleaf
- 通过#{}获得国际化内容
-
-
- 通过按钮切换语言
- 重写区域解析器 LocaleResolver
java
//MyLocaleResolver.java
public class MyLocaleResolver implements LocaleResolver {
@Override
public Locale resolveLocale(HttpServletRequest request) {
String language = request.getParameter("language");
Locale locale = Locale.getDefault();
if(language != null && !language.equals(" ")){
String[] split = language.split("_");
locale = new Locale(split[0],split[1]);
}
return locale;
}
@Override
public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
}
}
//Config.java
//注册组件
@Bean
public LocaleResolver localeResolver(){
return new MyLocaleResolver();
}
//page.html
//通过参数获得语言
<div>
<a th:href="@{/index.html(language='zh_CN')}">中文</a>
<a th:href="@{/index.html(language='en_US')}">English</a>
</div>
### 拦截器
- 编写拦截器类 SpringMvc
- 在配置类中注册组件
```java
@Configuration
public class AppConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns(“/“)
.excludePathPatterns(“/login”);
}
}
- SpringBoot已经做好了静态资源映射,在使用拦截器时不用再处理
<a name="DAty5"></a>
#### 实例
- 登录截拦器
java
//LoginInterceptor.java
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Object user = request.getSession().getAttribute(“loginUser”);
if(user != null){
return true;
}else {
request.getRequestDispatcher(“/login”).forward(request,response);
return false;
}
}
//BookManagerConfig.java
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor()).addPathPatterns(“/“).excludePathPatterns(“/login”,”/user/login”,”/“);
}
<a name="NSV6d"></a>
### RESTful
什么是[RESTful](http://www.ruanyifeng.com/blog/2014/05/restful_api.html)<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/1561124/1604111582746-1feb5146-9e49-48d6-a17a-63e83ff0b53b.png#height=279&id=lDkwh&margin=%5Bobject%20Object%5D&name=image.png&originHeight=557&originWidth=1572&originalType=binary&ratio=1&size=439884&status=done&style=none&width=786)
| RESTful | method | url |
| --- | --- | --- |
| 查询所有用户 | GET | /users |
| 查询某一个用户 | GET | /user/id |
| 添加用户 | POST | /user |
| 更新用户(完整信息) | PUT | /user/id |
| 更新用户(部分信息) | PATCH | /user/id |
| 删除用户 | DELETE | /user/id |
<a name="oW7UW"></a>
#### SpringBoot 发送PUT,PATCH,DELETE
![image.png](https://cdn.nlark.com/yuque/0/2020/png/1561124/1604145834171-c2d60640-2322-4191-afae-9e8acb6c1de6.png#height=61&id=p52c3&margin=%5Bobject%20Object%5D&name=image.png&originHeight=122&originWidth=1144&originalType=binary&ratio=1&size=208973&status=done&style=none&width=572)
- 开启MethodFilter
yaml
spring:
mvc:
hiddenmethod:
filter:
enabled: true
```
- 在页面中创建input
html
<input name="_method" value="put" hidden>
### Formatter
- 表单提交时字符串日期格式化格式
java
spring:
mvc:
format:
date: yyyy-MM-dd #表单提交时的字符串日期格式
####
### 错误处理机制
https://www.springcloud.cc/spring-boot.html#boot-features-error-handling
- 一旦系统中出现 4xx 或者 5xx 之类的错误, ErrorPageCustomizer就会生效(定义错误的相应规则),页面转发到/error
- 然后内部的过滤器就会映射到 ‘/error’请求,接着该/error请求就会被BasicErrorController处理;
- 然后BasicErrorController会根据请求中的Accept来区分该请求是浏览器发来的,还是由其它客户端工具发来的.此时一般分为两种处理方式:errorHtml()和error().
- 在errorHtml()方法中,获取错误状态信息,由resolveErrorView解析器解析到默认的错误视图页面,默认的错误页面是/error/404.html页面;
- 而如果templates目录中的error目录里面有这个页面,404错误就会精确匹配404.html;
- 如果没有这个404.html页面它就会模糊匹配4xx.html页面;
- 如果templates中没有找到错误页面,它就会去static文件中找.
- ErrorPageCustomizer
定制错误规则发生错误时页面会被转发到/error
- BasicErrorController 处理/error请求
在浏览器返回error视图
其他客户端返回JSON数据
- DefaultErrorViewResolver
解析视图页 - 有模板引擎 - /error/状态码 - 有对应页查找对应页,否则查找4xx或5xx - 无模板引擎 - /静态资源文件夹/状态码.html - DefaultErrorAttributes 传送错误信息给错误页
默认传递的值
exception,message,errors,trace需要在配置文件配置
java
server:
error:
include-exception: true
include-message: always
#### 添加自己的异常信息
- 重写DefaultErrorAttributes
java
@Component
public class MyErrorAttributes extends DefaultErrorAttributes {
@Override
public Map<String, Object> getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) {
//获得Map
Map<String, Object> map = super.getErrorAttributes(webRequest, options);
//添加自己的信息
map.put("company","cn.landsall");
//获得异常处理器存放的信息
Object attribute = webRequest.getAttribute("ext", 0);
if(attribute!=null)
map.put("ext",attribute);
return map;
}
}
- 如果有异常处理器
java
@ControllerAdvice
public class MyExceptionHandler {
@ExceptionHandler(MyException.class)
public String handleException(Exception e, HttpServletRequest request){
//手动设置错误状态码
request.setAttribute(RequestDispatcher.ERROR_STATUS_CODE,500);
HashMap<String, Object> map = new HashMap<>();
map.put("error_message",e.getMessage());
map.put("error_id",123);
//将异常信息存放到request
request.setAttribute("ext",map);
//转发给BasicErrorController
return "forward:/error";
}
}
### SpringBoot容器定制化
官方文档
#### 修改容器配置
- 通过属性文件
相关属性
javascript
//通用的 servlet?容器设置
server.XXX
// Tomcat的设置
server.tomcat.XXX
- 通过配置类WebServerFactoryCustomizerjava
//XXXConfig.java
@Bean
public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> webServerFactoryCustomizer(){
return new WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>() {
@Override
public void customize(ConfigurableServletWebServerFactory factory) {
factory.setPort(8082);
}
};
}
#### 注册Servlet三大组件
官方文档
java
//WebMvcConfigurer.java
@Bean
public ServletRegistrationBean<MyServlet> myServlet(){
return new ServletRegistrationBean<MyServlet>(new MyServlet(),"/home");
}
@Bean
public FilterRegistrationBean<MyFilter> myFilter(){
FilterRegistrationBean<MyFilter> filterRegistrationBean = new FilterRegistrationBean<MyFilter>();
filterRegistrationBean.setFilter(new MyFilter());
filterRegistrationBean.setUrlPatterns(Arrays.asList("/home","/user"));
return filterRegistrationBean;
}
@Bean
public ServletListenerRegistrationBean<MyListener> myListener(){
return new ServletListenerRegistrationBean<MyListener>(new MyListener());
}
#### 切换其他Servlet容器
视频
#### 嵌入式Servlet容器工作原理
- ServletWebServerFactoryAutoConfiguration
java
@Configuration(proxyBeanMethods = false)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@ConditionalOnClass(ServletRequest.class)
@ConditionalOnWebApplication(type = Type.SERVLET)
@EnableConfigurationProperties(ServerProperties.class)
@Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,
ServletWebServerFactoryConfiguration.EmbeddedTomcat.class,
ServletWebServerFactoryConfiguration.EmbeddedJetty.class,
ServletWebServerFactoryConfiguration.EmbeddedUndertow.class })
public class ServletWebServerFactoryAutoConfiguration {
### 其他
- 返回图片
java
@ResponseBody
@GetMapping("/getImage")
public void getImage(HttpSession session, HttpServletResponse response) throws IOException {
response.setContentType("image/png");
//获得输出流
ServletOutputStream out = response.getOutputStream();
//TODO 获得输出result
//输出图片
out.write(result);
out.flush();
//关闭响应输出流
out.close();
}
java
#开发环境下关闭thymeleaf的缓存
thymeleaf:
cache: false
## 其他
### 验证码
#### EasyCaptcha
- maven
xml
<dependency>
<groupId>com.github.whvcse</groupId>
<artifactId>easy-captcha</artifactId>
<version>1.6.2</version>
</dependency>
### 文件上传
- application.yml
java
spring:
servlet:
multipart:
max-file-size: 2MB #单个文件最大容量
max-request-size: 2MB #上传文件最大容量
#### 获得根目录
java
//获得项目根目录
System.getProperty("user.dir");
//D:\Code\Java\idea_work\JavaWeb\Shiro\springboot-img
//获得classes根路径
ResourceUtils.getURL("classpath:").getPath();
///D:/Code/Java/idea_work/JavaWeb/Shiro/springboot-img/target/classes/
# Spring Boot与Docker
视频
# Spring Boot与数据访问
## 使用JDBC和Mybatis
Spring Initializr创建项目### 配置数据源 - application.yml SpringBoot默认数据源
2.0以前
org.apache.tomcat.jdbc.pool.Datasource
2.0以后
com.zaxxer.hikari.HikariDataSource
yaml
spring:
datasource:
username: username
password: password
url: jdbc:mysql:/ip:port/data
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource #指定数据源(先引入maven)
#### 使用druid作为数据源
druid中文文档
- 引入stater
xml
<!-- druid整合 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.1</version>
</dependency>
- java
@Configuration
public class DruidDataSourceConfig {
@ConfigurationProperties(prefix = "spring.datasource")
@Bean
public DruidDataSource druidDataSource(){
return new DruidDataSource();
}
}
- 配置druid属性
yaml
spring:
datasource:
druid:
# 过滤器设置
filters: stat
##### StatViewServlet配置 -- druid内置监控页面 #######
stat-view-servlet:
enabled: true
login-username: admin
login-password: 123456
reset-enable: false
url-pattern: /druid/*
allow: 127.0.0.1
deny: ''
##### WebStatFilter配置 -- druid监控统计功能 #######
web-stat-filter:
enabled: true
exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*'
session-stat-enable: true
session-stat-max-count: 1000
url-pattern: /*
StatViewServletWebStatFilter ### 整合mybatis Spring Initializr创建项目
或 maven
xml
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
#### 注册mapper
- 在Java类上注解@Mapper
java
@Repository
@Mapper
public interface BookMapper {
.....
}
- 在@SpringBootApplication标注@MapperScan
java
@MapperScan("cn.landsall.mapper")
@SpringBootApplication
public class SpringbootBookmanagerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootBookmanagerApplication.class, args);
}
}
#### 配置mybatis
官方文档
- springBoot 相关类
MybatisProperties 属性类MybatisAutoConfiguration 自动配置类 - application.yml
yaml
mybatis:
config-location: classpath:mybatis-config.xml #配置文件路径
mapper-locations: classpath:cn/landsall/*.xml #映射mapper
configuration:
map-underscore-to-camel-case: true
- 使用配置类
java
@Configuration
public class mybatisConfig {
@Bean
ConfigurationCustomizer configurationCustomizer(){
return new ConfigurationCustomizer() {
@Override
public void customize(org.apache.ibatis.session.Configuration configuration) {
}
};
}
}
- 通过指定mybatis配置文件
yaml
#application.yml
mybatis:
config-location: classpath:mybatis-config.xml #配置文件路径
mapper-locations: classpath:cn/landsall/*.xml #映射mapper
### 使用Mybatis-Plus
- maven
xml
将
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
替换为
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.0</version>
</dependency>
属性配置注解 #### 入门程序 - 实体类
java
@TableName("user_info")
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private Integer age;
private String email;
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.UPDATE)
private Date updateTime;
}
- mapper
java
@Repository
public interface BookMapper extends BaseMapper<Book> {
}
- MapperCRUD
#### 自动填充
- 实体类
注解填充字段 @TableField(.. fill = FieldFill.XXX)
java
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.UPDATE)
private Date updateTime;
}
- 实现元对象处理器接口
java
@Component
public class MyMetaObjectHandle implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
this.strictInsertFill(metaObject,"createTime", Date.class,new Date());
}
@Override
public void updateFill(MetaObject metaObject) {
this.strictUpdateFill(metaObject,"updateTime", Date.class,new Date());
}
}
#### 乐观锁
- 字段上加上@Version
注解
java
@Version
private Integer version;
- 在插件主体添加插件OptimisticLockerInnerInterceptor
java
@Configuration
@MapperScan("cn.landsall.mapper")
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return mybatisPlusInterceptor;
}
}
#### 分页
- 添加分页插件PaginationInnerInterceptor**
- 实现分页
#### 条件构造器
- Map条件查询
- queryWrapper 条件构造器
- 所有方法
#### 逻辑删除
- 为字段添加注解@TableLogic
- 配置逻辑删除
yaml
mybatis-plus:
global-config:
db-config:
logic-delete-field: flag # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
#### 代码生成器
- 引入依赖
```xml
<a name="rt6SK"></a>
#### 动态表名
```java
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
//动态表名插件
DynamicTableNameInnerInterceptor tableNameInnerInterceptor = new DynamicTableNameInnerInterceptor();
HashMap<String, TableNameHandler> map = new HashMap<String,TableNameHandler>();
//映射表名
for(String table : TABLES){
map.put(table, (sql, tableName) -> currentTableName+"_"+tableName);
}
tableNameInnerInterceptor.setTableNameHandlerMap(map);
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(tableNameInnerInterceptor);
return mybatisPlusInterceptor;
}
配置
@Test
void contextLoads() {
//全局配置
GlobalConfig globalConfig = new GlobalConfig();
globalConfig.setOutputDir(System.getProperty("user.dir")+"/src/main/java"); //输出路径
globalConfig.setAuthor("author");
globalConfig.setOpen(false); //完成后是否打开资源管理器
globalConfig.setFileOverride(false); //是否覆盖原文件
//数据源
DataSourceConfig dataSourceConfig = new DataSourceConfig();
dataSourceConfig.setUrl("jdbc:mysql://ip/table?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8");
dataSourceConfig.setUsername("usernmae");
dataSourceConfig.setPassword("password");
dataSourceConfig.setDriverName("com.mysql.cj.jdbc.Driver");
dataSourceConfig.setDbType(DbType.MYSQL);
//包的配置
PackageConfig packageConfig = new PackageConfig();
packageConfig.setParent("cn.landsall");
packageConfig.setModuleName("autoGenerator"); //模块名
//packageConfig.setMapper("mapper");
//packageConfig.setController("controller");
//packageConfig.setEntity("entity");
//packageConfig.setService("service");
//策略配置
StrategyConfig strategyConfig = new StrategyConfig();
strategyConfig.setInclude("user_info"); //要映射的表名
strategyConfig.setNaming(NamingStrategy.underline_to_camel); //表映射到实体的命名策略
strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel); //表字段映射到实体的命名策略
//strategyConfig.setSuperEntityClass("你自己的父类实体,没有就不用设置!");
//strategyConfig.setEntityLombokModel(true); //是否为lombok模型
//strategyConfig.setRestControllerStyle(true); //是否为RestController
//strategyConfig.setLogicDeleteFieldName("is_deleted") //逻辑删除属性名称
//自动填充配置
/*
TableFill create_time = new TableFill("create_time", FieldFill.INSERT);
TableFill update_time = new TableFill("update_time", FieldFill.UPDATE);
strategyConfig.setTableFillList(Arrays.asList(create_time,update_time));
*/
//代码生成器
AutoGenerator autoGenerator = new AutoGenerator();
autoGenerator.setGlobalConfig(globalConfig);
autoGenerator.setDataSource(dataSourceConfig);
autoGenerator.setPackageInfo(packageConfig);
autoGenerator.setStrategy(strategyConfig);
autoGenerator.execute();
}
插件主体
常用属性
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
logic-delete-field: flag # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
mapper-locations: classpath:/mybatis/mapper/*.xml
使用SpringBoot Data JPA
概念
参考
https://www.xncoding.com/2017/07/03/spring/sb-hibernate.html
Spring Data
Spring Data是一个用于简化数据库访问,并支持云服务的开源框架。其主要目标是使得数据库的访问变得方便快捷, 并支持map-reduce框架和云计算数据服务。此外,它还支持基于关系型数据库的数据服务,如Oracle RAC等。
- Spring Data
Repository 统一的接口
CrudRepository 主要提供CRUD功能
PagingAndSortingRepository 提供进行分页和排序记录的方法
- Spring Data JPA
Spring Data JPA
Spring Data JPA是Spring Data中的一个子模块。
它可以极大的简化JPA的写法,可以在几乎不用写实现的情况下,实现对数据的访问和操作。除了CRUD外,还包括如分页、排序等一些常用的功能。
- Spring Data JPA 的默认JPA实现是Hibernate
Spring Data Commons
Spring Data 基础架构JPA
JPA(Java Persistence API)是Sun官方提出的Java持久化规范,它为Java开发人员提供了一种对象/关系映射工具来管理Java应用中的关系数据。
JPA是一种规范和标准,也就是类似于Java中的接口,由Sun公司官方定义,但是并没有指定谁来实现。
现在几个主要的JPA实现技术有Hibernate、EclipseLink、OpenJPA等。JPQL
JPQL(Java持久性查询语言)是一种面向对象的查询语言,用于对持久实体执行数据库操作。 JPQL不使用数据库表,而是使用实体对象模型来操作SQL查询。 这里,JPA的作用是将JPQL转换为SQL
Hibernate
Hibernate是一个开源的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的ORM框架。 Hibernate可以自动生成SQL语句、自动执行,从而使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。
实际上,JPA规范制定过程中就是借鉴了Hibernate等这些开源的持久框架,也就是说Hibernate的出现比JPA还要早些。
在Hibernate中使用的注解就是JPA注解,Hibernate实现了JPA规范。
创建项目
- Spring Initializr
配置JPA
创建实体类
@Entity //告诉JPA这是一个实体类
@Table(name = "book") //指定实体类与哪张表对应 默认为类名小写book 表不存在会自动创建
public class Book {
@Id //主键
@GeneratedValue(strategy = GenerationType.IDENTITY) //自增
private int id;
@Column(name = "bookName")
private String bookName;
@Column //默认列名就是属性名
private String author;
//未标注@Column 默认映射表同名列
private String publish;
}
创建Repository接口
public interface BookRepository extends JpaRepository<Book,Integer> {
}
使用JPA提供的方法
@RestController
public class BookController {
@Autowired
private BookRepository bookRepository;
@GetMapping("/book/books")
public List<Book> ListView() {
return bookRepository.findAll();
}
@GetMapping("/book/{id}")
public Book getBook(@PathVariable Integer id) {
return bookRepository.findById(id).orElse(null);
}
@PostMapping("/book")
public void addBook(Book book){
bookRepository.save(book);
}
@DeleteMapping("/book/{id}")
public void delete(@PathVariable Integer id){
bookRepository.deleteById(id);
}
@PutMapping("/book/{id}")
public void update(Book book){
bookRepository.saveAndFlush(book);
}
}
根据方法名创建查询业务
public interface BookRepository extends JpaRepository<Book,Integer> {
//where BookName = ?
Book findByBookName(String BookName);
//where BookName = %?%
Book findByBookNameContaining(String BookName);
//where BookName = ? AND Author = ?
Book findByBookNameAndAuthor(String BookName,String Author);
}
使用@Query
使用JPQL规范
public interface UserRepository extends JpaRepository<User, Long> {
@Query("select u from User u where u.emailAddress = ?1")
User findByEmailAddress(String emailAddress);
}
基于xml
SpringBoot相关配置
JpaProperties
application.yml
spring:
jpa:
hibernate:
ddl-auto: update #配置自动建表规则 update -- 创建或更新
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
show-sql: true #控制台显示SQL语句
Lombok
Maven添加依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
</dependency>
安装插件
SpringSecurity
入门
- maven
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
配置类
```java @EnableWebSecurity public class DemoSpringSecurityConfig extends WebSecurityConfigurerAdapter { //授权 @Override protected void configure(HttpSecurity http) throws Exception {//授权的规则
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/level1/**").hasRole("vip1")
.antMatchers("/level2/**").hasRole("vip2")
.antMatchers("/level3/**").hasRole("vip3");
//用户登录逻辑
http.formLogin() //开启登入配置
.loginPage("/toLogin") //指定登入界面 /login
.loginProcessingUrl("/login") //表单提交路径 默认和loginPage同名
.usernameParameter("username") //表单提交时的用户名参数名 username
.passwordParameter("password"); //表单提交时的密码的参数名 password
//开启注销 /logout
http.logout().logoutSuccessUrl("/index");
http.rememberMe();
}
//认证
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//从内存中获得用户
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
.withUser("user").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2","vip3")
.and()
.withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
.and()
.withUser("guest").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1");
}
}
<a name="Wv4x7"></a>
### [整合Thymeleaf](https://www.thymeleaf.org/doc/articles/springsecurity.html)
- maven
```xml
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
xmlns
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
使用
使用JDBC
使用Shiro作为安全框架
Spring Boot启动配置原理
Spring Boot自定义 starters
Spring Boot与缓存
Spring Boot与消息
Spring Boot与检索
Spring Boot与任务
Spring Boot与安全
Spring Boot与分布式
Spring Boot与开发热部署
https://zhuanlan.zhihu.com/p/63381268