# springboot-learn
**Repository Path**: hrbu2023/springboot-learn
## Basic Information
- **Project Name**: springboot-learn
- **Description**: springboot-学习
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-03-24
- **Last Updated**: 2026-03-31
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# SpringBoot介绍
金山老师的笔记: https://blog.fulfill.com.cn/course/01-java/springboot/springboot-9.html
Spring Boot 让你轻松创建独立的基于生产级别的 Spring 应用程序,这些应用程序你可以“只需运行”。我们对Spring平台和第三方库持独特观点,让你能轻松上手。大多数
Spring Boot 应用只需极少的 Spring
配置。如果你想了解某个特定版本的信息,或者如何从早期版本升级,可以查看我们维基上的[项目发布说明部分](https://github.com/spring-projects/spring-boot/wiki#release-notes)。
## 特色
- 创建独立的 Spring 应用程序
- 直接嵌入Tomcat、Jetty或Undertow(无需部署WAR文件)
- 提供有主见的“起始”依赖,简化你的构建配置
- 尽可能自动配置 Spring 和第三方库
- 提供生产准备的功能,如指标、健康检查和外部配置
- 完全不需要代码生成,也不需要XML配置
## [文档](https://docs.spring.io/spring-boot/3.5/index.html) https://docs.spring.io/spring-boot/3.5/index.html
# 开发工具
[Spring | Tools](https://spring.io/tools)



# 入门项目
## 快速搭建springmvc
### 父项目

### 创建组合项目的子项目

### 添加依赖
[spring-boot-starter-web](https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web)
使用 Spring MVC 构建网页应用(包括 RESTful)的 Starter。使用 Tomcat 作为默认嵌入式容器(已被 spring-boot-starter-webmvc 取代)
在项目中引入 spring-boot-dependencies,让项目继承自`spring-boot-starter-parent`
```xml
4.0.0
org.springframework.boot
spring-boot-starter-parent
3.5.12
com.neuedu.boot
boot-01-helloworld
jar
boot-01-helloworld
http://maven.apache.org
UTF-8
org.springframework.boot
spring-boot-starter-web
```
### main方法
```java
package com.neuedu.boot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Hello world!
*
*/
@SpringBootApplication
public class App
{
public static void main( String[] args )
{
SpringApplication.run(App.class ,args );
}
}
```
测试Controller
```java
package com.neuedu.boot.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class IndexController {
@RequestMapping("/index")
String index(){
return "success";
}
}
```

# 使用[Spring Initializr](https://start.spring.io/)创建项目


# 使用IDEA的插件


# 启动器
起始词是一组方便的依赖描述符,你可以在申请中包含。 你可以一站式获取所有 Spring 及相关技术,无需翻找样本代码和复制粘贴大量依赖描述符。
例如,如果你想开始使用 Spring 和 JPA 进行数据库访问,可以在项目中包含依赖关系。`spring-boot-starter-data-jpa`
起始程序包含了许多你需要快速启动项目并拥有一致且受控的可管理传递依赖所需的依赖。
| Name | Description |
|:--------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `spring-boot-starter` | Core starter, including auto-configuration support, logging and YAML |
| `spring-boot-starter-activemq` | Starter for JMS messaging using Apache ActiveMQ |
| `spring-boot-starter-amqp` | Starter for using Spring AMQP and Rabbit MQ |
| `spring-boot-starter-aop` | Starter for aspect-oriented programming with Spring AOP and AspectJ |
| `spring-boot-starter-artemis` | Starter for JMS messaging using Apache Artemis |
| `spring-boot-starter-batch` | Starter for using Spring Batch |
| `spring-boot-starter-cache` | Starter for using Spring Framework’s caching support |
| `spring-boot-starter-data-cassandra` | Starter for using Cassandra distributed database and Spring Data Cassandra |
| `spring-boot-starter-data-cassandra-reactive` | Starter for using Cassandra distributed database and Spring Data Cassandra Reactive |
| `spring-boot-starter-data-couchbase` | Starter for using Couchbase document-oriented database and Spring Data Couchbase |
| `spring-boot-starter-data-couchbase-reactive` | Starter for using Couchbase document-oriented database and Spring Data Couchbase Reactive |
| `spring-boot-starter-data-elasticsearch` | Starter for using Elasticsearch search and analytics engine and Spring Data Elasticsearch |
| `spring-boot-starter-data-jdbc` | Starter for using Spring Data JDBC |
| `spring-boot-starter-data-jpa` | Starter for using Spring Data JPA with Hibernate |
| `spring-boot-starter-data-ldap` | Starter for using Spring Data LDAP |
| `spring-boot-starter-data-mongodb` | Starter for using MongoDB document-oriented database and Spring Data MongoDB |
| `spring-boot-starter-data-mongodb-reactive` | Starter for using MongoDB document-oriented database and Spring Data MongoDB Reactive |
| `spring-boot-starter-data-neo4j` | Starter for using Neo4j graph database and Spring Data Neo4j |
| `spring-boot-starter-data-r2dbc` | Starter for using Spring Data R2DBC |
| `spring-boot-starter-data-redis` | Starter for using Redis key-value data store with Spring Data Redis and the Lettuce client |
| `spring-boot-starter-data-redis-reactive` | Starter for using Redis key-value data store with Spring Data Redis reactive and the Lettuce client |
| `spring-boot-starter-data-rest` | Starter for exposing Spring Data repositories over REST using Spring Data REST and Spring MVC |
| `spring-boot-starter-freemarker` | Starter for building MVC web applications using FreeMarker views |
| `spring-boot-starter-graphql` | Starter for building GraphQL applications with Spring GraphQL |
| `spring-boot-starter-groovy-templates` | Starter for building MVC web applications using Groovy Templates views |
| `spring-boot-starter-hateoas` | Starter for building hypermedia-based RESTful web application with Spring MVC and Spring HATEOAS |
| `spring-boot-starter-integration` | Starter for using Spring Integration |
| `spring-boot-starter-jdbc` | Starter for using JDBC with the HikariCP connection pool |
| `spring-boot-starter-jersey` | Starter for building RESTful web applications using JAX-RS and Jersey. An alternative to [`spring-boot-starter-web`](https://docs.spring.io/spring-boot/3.5/reference/using/build-systems.html#spring-boot-starter-web) |
| `spring-boot-starter-jooq` | Starter for using jOOQ to access SQL databases with JDBC. An alternative to [`spring-boot-starter-data-jpa`](https://docs.spring.io/spring-boot/3.5/reference/using/build-systems.html#spring-boot-starter-data-jpa) or [`spring-boot-starter-jdbc`](https://docs.spring.io/spring-boot/3.5/reference/using/build-systems.html#spring-boot-starter-jdbc) |
| `spring-boot-starter-json` | Starter for reading and writing json |
| `spring-boot-starter-mail` | Starter for using Java Mail and Spring Framework’s email sending support |
| `spring-boot-starter-mustache` | Starter for building web applications using Mustache views |
| `spring-boot-starter-oauth2-authorization-server` | Starter for using Spring Authorization Server features |
| `spring-boot-starter-oauth2-client` | Starter for using Spring Security’s OAuth2/OpenID Connect client features |
| `spring-boot-starter-oauth2-resource-server` | Starter for using Spring Security’s OAuth2 resource server features |
| `spring-boot-starter-pulsar` | Starter for using Spring for Apache Pulsar |
| `spring-boot-starter-pulsar-reactive` | Starter for using Spring for Apache Pulsar Reactive |
| `spring-boot-starter-quartz` | Starter for using the Quartz scheduler |
| `spring-boot-starter-rsocket` | Starter for building RSocket clients and servers |
| `spring-boot-starter-security` | Starter for using Spring Security |
| `spring-boot-starter-test` | Starter for testing Spring Boot applications with libraries including JUnit Jupiter, Hamcrest and Mockito |
| `spring-boot-starter-thymeleaf` | Starter for building MVC web applications using Thymeleaf views |
| `spring-boot-starter-validation` | Starter for using Java Bean Validation with Hibernate Validator |
| `spring-boot-starter-web` | Starter for building web, including RESTful, applications using Spring MVC. Uses Tomcat as the default embedded container |
| `spring-boot-starter-web-services` | Starter for using Spring Web Services |
| `spring-boot-starter-webflux` | Starter for building WebFlux applications using Spring Framework’s Reactive Web support |
| `spring-boot-starter-websocket` | Starter for building WebSocket applications using Spring Framework’s MVC WebSocket support |
| 名称 | 描述 |
|:--------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `spring-boot-starter` | 核心启动功能,包括自动配置支持、日志记录和 YAML |
| `spring-boot-starter-activemq` | 使用 Apache ActiveMQ 进行 JMS 消息传递的入门 |
| `spring-boot-starter-amqp` | 使用 Spring AMQP 和 Rabbit MQ 的入门程序 |
| `spring-boot-starter-aop` | Spring AOP和AspectJ面向切面编程的入门程序 |
| `spring-boot-starter-artemis` | 使用 Apache Artemis 的 JMS 消息发送入门 |
| `spring-boot-starter-batch` | 使用春季批次的起始剂 |
| `spring-boot-starter-cache` | 使用 Spring Framework 缓存支持的 Starter |
| `spring-boot-starter-data-cassandra` | 用于使用 Cassandra 分布式数据库和 Spring Data Cassandra 的入门程序 |
| `spring-boot-starter-data-cassandra-reactive` | 用于使用 Cassandra 分布式数据库和 Spring Data Cassandra Reactive 的入门工具 |
| `spring-boot-starter-data-couchbase` | 用于使用 Couchbase 文档导向数据库和 Spring Data Couchbase 的 Starter |
| `spring-boot-starter-data-couchbase-reactive` | 用于使用 Couchbase 文档导向数据库和 Spring Data Couchbase Reactive 的 Starter |
| `spring-boot-starter-data-elasticsearch` | 用于使用 Elasticsearch 搜索和分析引擎以及 Spring Data Elasticsearch 的入门工具 |
| `spring-boot-starter-data-jdbc` | 使用 Spring Data JDBC 的入门 |
| `spring-boot-starter-data-jpa` | 使用 Spring Data JPA 搭配 Hibernate 的起始程序 |
| `spring-boot-starter-data-ldap` | 使用 Spring Data LDAP 的起始码 |
| `spring-boot-starter-data-mongodb` | 用于使用 MongoDB 文档导向数据库和 Spring Data MongoDB 的入门工具 |
| `spring-boot-starter-data-mongodb-reactive` | 用于使用 MongoDB 文档导向数据库和 Spring Data MongoDB Reactive 的入门 |
| `spring-boot-starter-data-neo4j` | 使用 Neo4j 图数据库和 Spring Data Neo4j 的起始程序 |
| `spring-boot-starter-data-r2dbc` | 使用 Spring Data R2DBC 的起始程序 |
| `spring-boot-starter-data-redis` | Starter 用于使用 Redis 键值数据存储,配合 Spring Data Redis 和 Lettuce 客户端 |
| `spring-boot-starter-data-redis-reactive` | 使用 Redis 键值数据存储,配合 Spring Data Redis 反应式和 Lettuce 客户端 |
| `spring-boot-starter-data-rest` | 使用 Spring Data REST 和 Spring MVC 在 REST 上暴露 Spring Data 仓库的起始程序 |
| `spring-boot-starter-freemarker` | 用于使用 FreeMarker 视图构建 MVC 网络应用的 Starter |
| `spring-boot-starter-graphql` | 用 Spring GraphQL 构建 GraphQL 应用的入门工具 |
| `spring-boot-starter-groovy-templates` | 使用 Groovy 模板视图构建 MVC 网页应用的入门 |
| `spring-boot-starter-hateoas` | 用于构建基于超媒体的RESTful网页应用的Spring MVC和Spring HATEOAS的入门程序 |
| `spring-boot-starter-integration` | 使用 Spring 集成的起始程序 |
| `spring-boot-starter-jdbc` | 使用 JDBC 搭配 HikariCP 连接池的入门 |
| `spring-boot-starter-jersey` | 用于使用 JAX-RS 和 Jersey 构建 RESTful 网页应用的 Starter。[`spring-boot-starter-web`](https://docs.spring.io/spring-boot/3.5/reference/using/build-systems.html#spring-boot-starter-web) 的替代方案 |
| `spring-boot-starter-jooq` | 用jOOQ访问JDBC的SQL数据库的入门工具。[`spring-boot-starter-data-jpa`](https://docs.spring.io/spring-boot/3.5/reference/using/build-systems.html#spring-boot-starter-data-jpa) 或 [`spring-boot-starter-jdbc`](https://docs.spring.io/spring-boot/3.5/reference/using/build-systems.html#spring-boot-starter-jdbc) 的替代方案 |
| `spring-boot-starter-json` | 用于读写json的起始程序 |
| `spring-boot-starter-mail` | 用于使用 Java Mail 和 Spring Framework 邮件发送支持的 Starter |
| `spring-boot-starter-mustache` | 使用 Mustache 视图构建网页应用的 Starter |
| `spring-boot-starter-oauth2-authorization-server` | 使用 Spring 授权服务器功能的起始工具 |
| `spring-boot-starter-oauth2-client` | 用于使用 Spring Security OAuth2/OpenID Connect 客户端功能的入门 |
| `spring-boot-starter-oauth2-resource-server` | 使用 Spring Security OAuth2 资源服务器功能的起始程序 |
| `spring-boot-starter-pulsar` | 使用 Spring for Apache Pulsar 的入门工具 |
| `spring-boot-starter-pulsar-reactive` | 使用 Apache Pulsar Reactive 的 Spring 起始器 |
| `spring-boot-starter-quartz` | 使用 Quartz 调度器的起始程序 |
| `spring-boot-starter-rsocket` | 构建 RSocket 客户端和服务器的入门程序 |
| `spring-boot-starter-security` | 使用 Spring Security 的起始工具 |
| `spring-boot-starter-test` | 用于测试包含 JUnit Jupiter、Hamcrest 和 Mockito 等库的 Spring Boot 应用的 Starter |
| `spring-boot-starter-thymeleaf` | 用于使用 Thymeleaf 视图构建 MVC 网页应用的 Start。 |
| `spring-boot-starter-validation` | 使用 Java Bean 验证与 Hibernate Validator 的入门 |
| **`spring-boot-starter-web`** | 使用 Spring MVC 构建网页应用(包括 RESTful)的 Starter。默认嵌入式容器使用 Tomcat |
| `spring-boot-starter-web-services` | 使用 Spring Web Services 的起始程序 |
| `spring-boot-starter-webflux` | 使用 Spring Framework 的反应式网页支持构建 WebFlux 应用的起始程序 |
| `spring-boot-starter-websocket` | 用于使用 Spring Framework 的 MVC WebSocket 支持构建 WebSocket 应用的 Starter |
# 自动配置

通过加载 META-INF/spring.factories中定义的 自动配置类


注册内嵌的Tomcat
```java
/*
* Copyright 2012-present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.autoconfigure.web.servlet;
import io.undertow.Undertow;
import jakarta.servlet.Servlet;
import org.apache.catalina.startup.Tomcat;
import org.apache.coyote.UpgradeProtocol;
import org.eclipse.jetty.ee10.webapp.WebAppContext;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.Loader;
import org.xnio.SslClientAuthMode;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer;
import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer;
import org.springframework.boot.web.embedded.tomcat.TomcatProtocolHandlerCustomizer;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.embedded.undertow.UndertowBuilderCustomizer;
import org.springframework.boot.web.embedded.undertow.UndertowDeploymentInfoCustomizer;
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Configuration classes for servlet web servers
*
* Those should be {@code @Import} in a regular auto-configuration class to guarantee
* their order of execution.
*
* @author Phillip Webb
* @author Dave Syer
* @author Ivan Sopov
* @author Brian Clozel
* @author Stephane Nicoll
* @author Raheela Asalm
* @author Sergey Serdyuk
*/
@Configuration(proxyBeanMethods = false)
class ServletWebServerFactoryConfiguration {
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ Servlet.class, Tomcat.class, UpgradeProtocol.class })
@ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT)
static class EmbeddedTomcat {
@Bean
TomcatServletWebServerFactory tomcatServletWebServerFactory(
ObjectProvider connectorCustomizers,
ObjectProvider contextCustomizers,
ObjectProvider> protocolHandlerCustomizers) {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
factory.getTomcatConnectorCustomizers().addAll(connectorCustomizers.orderedStream().toList());
factory.getTomcatContextCustomizers().addAll(contextCustomizers.orderedStream().toList());
factory.getTomcatProtocolHandlerCustomizers().addAll(protocolHandlerCustomizers.orderedStream().toList());
return factory;
}
}
/**
* Nested configuration if Jetty is being used.
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ Servlet.class, Server.class, Loader.class, WebAppContext.class })
@ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT)
static class EmbeddedJetty {
@Bean
JettyServletWebServerFactory jettyServletWebServerFactory(
ObjectProvider serverCustomizers) {
JettyServletWebServerFactory factory = new JettyServletWebServerFactory();
factory.getServerCustomizers().addAll(serverCustomizers.orderedStream().toList());
return factory;
}
}
/**
* Nested configuration if Undertow is being used.
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ Servlet.class, Undertow.class, SslClientAuthMode.class })
@ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT)
static class EmbeddedUndertow {
@Bean
UndertowServletWebServerFactory undertowServletWebServerFactory(
ObjectProvider deploymentInfoCustomizers,
ObjectProvider builderCustomizers) {
UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory();
factory.getDeploymentInfoCustomizers().addAll(deploymentInfoCustomizers.orderedStream().toList());
factory.getBuilderCustomizers().addAll(builderCustomizers.orderedStream().toList());
return factory;
}
@Bean
UndertowServletWebServerFactoryCustomizer undertowServletWebServerFactoryCustomizer(
ServerProperties serverProperties) {
return new UndertowServletWebServerFactoryCustomizer(serverProperties);
}
}
}
```
## 自动配置DispatcherServlet

不是所有的自动配置类都加载其自动配置的对象,包含条件才会自动配置,比如
`org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration` 需要包含数据源和驱动


用不到 的包尽量先不要添加到依赖中,否则可能会出发自动配置(但是可能因为配置缺少导致报错)
## 排除自动配置
```java
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })
```

# SpringBoot的Maven插件
对Spring开发进行支持,比如说打包、热部署等
```xml
org.springframework.boot
spring-boot-maven-plugin
```
使用插件打的jar是可以直接运行的,而不使用插件则jar不能运行

# Spring的配置
可以没有配置文件,默认有一些配置项,例如:
- 默认的服务器 端口号 8080
- 上下文名称 "/"
使用application.properties 或者 application.yaml
常见的配置 [Common Application Properties :: Spring Boot](https://docs.spring.io/spring-boot/3.5/appendix/application-properties/index.html)
- yaml格式
```yaml
#yaml 格式的 配置文件在运行的时候,底层会转换成 properties
server:
port: 7001
servlet:
context-path: /boot
```
- properties
```properties
server.port=9090
server.servlet.context-path=/boot
```
## 日志开关

```
logging:
level:
com.neuedu.boot.controller.LogController: TRACE
```
```java
package com.neuedu.boot.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class LogController {
Logger logger = LoggerFactory.getLogger(LogController.class);
/**
* http://127.0.0.1:7001/boot/doLog
* @return
*/
@RequestMapping("/doLog")
String doLog(){
logger.trace("trace");
logger.debug("debug ....");
logger.info("info");
logger.warn("warn");
logger.error("error");
return "success";
}
}
```


springboot使用的是 上层SLF4J的库,调用其他日志框架,默认logback

## 使用Lombok自动注册Log对象
添加依赖
```
org.projectlombok
lombok
```
在需要打印日志的类上面 添加注解
```java
package com.neuedu.boot.controller;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j
public class LogController {
//使用SLF4j工具
//Logger log = LoggerFactory.getLogger(LogController.class);
/**
* http://127.0.0.1:7001/boot/doLog
* @return
*/
@RequestMapping("/doLog")
String doLog(){
log.trace("trace");
log.debug("debug ....");
log.info("info");
log.warn("warn");
log.error("error");
return "success";
}
}
```
## 自定义配置
可以在application配置文件中定义属性,在Bean中使用@Value读取
```yaml
#自定义配置项目
jwt:
# 生成JWT的秘钥
secret: JWT_S_123456
random: true
```
使用@Value获取值 `@Value("${key:default}")`
- key 就是 application中的key
- default 则为 找不到可以的默认值
```
package com.neuedu.boot.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
public class JWTController {
@Value("${jwt.secret}")
private String jwtSecret;
@Value("${jwt.random}")
private boolean random;
@Value("${jwt.key:123456}")
private String key;
/**
* http://127.0.0.1:7001/boot/jwt
* @return
*/
@RequestMapping("/jwt")
public Map getJwtSecret(){
Map map = new HashMap();
map.put("jwt.secret",jwtSecret);
map.put("jwt.random",random);
map.put("jwt.key",key);
return map;
}
}
```
如果key 没有配置,也没有默认值,则会抛出异常

# jackson配置
无需引入jar ,已经传递依赖了,
```
#yaml 格式的 配置文件在运行的时候,底层会转换成 properties
#server:
# port: 8080
# servlet:
# context-path: /
# debug开关
debug: false
spring:
jackson:
# 全局配置日期格式
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
```
可以使用 @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") 覆盖全局的配置,实现个性化
# 热部署
- 不需要重启,自动更新发布
- 添加插件支持
```xml
4.0.0
com.neuedu.boot
springboot-learn
1.0
boot-04-json-support
1.0
jar
boot-04-json-support
UTF-8
org.springframework.boot
spring-boot-starter-web
org.projectlombok
lombok
org.springframework.boot
spring-boot-devtools
org.springframework.boot
spring-boot-maven-plugin
```
开启IDEA的支持
- 开启运行时自动编译
- File-Settings-Build,Execution...--Compiler



当改动完IDEA的代码后,让IDEA失去焦点,会自动重新部署,不需要手动重启
# 测试支持
```xml
org.springframework.boot
spring-boot-starter-test
```
## 普通测试
```java
package com.neuedu.boot;
import org.junit.jupiter.api.Test;
public class JunitTest {
@Test
public void test01(){
System.out.println("hello junit");
}
}
```
## 使用容器获取Bean
需要添加注解 `@SpringBootTest`
```java
package com.neuedu.boot.service;
import com.neuedu.boot.App06;
import com.neuedu.boot.po.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import static org.junit.jupiter.api.Assertions.*;
//@SpringBootTest(classes = App04.class)
@SpringBootTest
class UserServiceTest {
@Autowired
private UserService userService;
@Test
void doService() {
userService.doService();
}
}
```
## 对MVC进行测试(Mockit)
需要@SPringBootTest+@AutoConfigureMockMvc
```java
package com.neuedu.boot.controller;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.web.context.WebApplicationContext;
import static org.junit.jupiter.api.Assertions.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest
@AutoConfigureMockMvc //在容器中注册一个对象 MockMvc
class UserControllerTest {
@Autowired
MockMvc mockMvc;
@Test
void list() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/user/list"))
.andExpect(status().isOk())
.andDo(result -> System.out.println(result.getResponse().getContentAsString()));
}
}
```
# profile
- application-dev.yaml
```yaml
#开发的配置项目
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/boot?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8
username: root
password: root
```
- application-prod.yaml
```yaml
#生产的配置项目
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.0.100:3306/boot?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8
username: product
password: production
```
- application.yaml
```yaml
spring:
application:
name: ProfileAPP
profiles:
active: prod
```

## 在jar中通过命令行激活配置项
- java -jar xxxxx.jar 运行springboot的项目
额外携带参数
- 给虚拟机添加参数
```
java -Dspring.profiles.active=dev -jar xxxxx.jar
java -Dspring.profiles.active=prod -jar xxxxx.jar
```
- 给main方法添加额外的启动参数
```
java -jar xxxxx.jar --spring.profiles.active=dev --
java -jar xxxxx.jar --spring.profiles.active=prod
```
# Banner

# 使用其他的Servlet服务器替代Tomcat
在pom文档中 排除 Tomcat部分,引入Jetty等starter
```xml
4.0.0
com.neuedu.boot
springboot-learn
1.0
boot-05-profile
jar
boot-05-profile
http://maven.apache.org
UTF-8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-tomcat
org.springframework.boot
spring-boot-starter-jetty
org.springframework.boot
spring-boot-starter-test
org.projectlombok
lombok
org.springframework.boot
spring-boot-devtools
org.springframework.boot
spring-boot-maven-plugin
```
# 异常处理器
Spring MVC已经支持了全局的异常处理器,SpringBoot将所有的错误,默认发送给 /error 的Handler


## 在Controller中添加异常处理
```java
package com.neuedu.boot.controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class IndexController {
/**
* http://127.0.0.1:8080/index?numa=10&numb=2
* @param numa
* @param numb
* @return
*/
@RequestMapping("/index")
public String index(int numa,int numb) {
return "result = ("+(numa/numb)+")";
}
/**
* 异常处理的方法
* http://127.0.0.1:8080/index?numa=10&numb=2
*/
@ExceptionHandler(exception = Exception.class)
public String handlerException(Exception ex) {
ex.printStackTrace();
return "error";
}
}
```
使用ControllerAdvice,添加全局的异常处理器
```
package com.neuedu.boot.advice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.resource.NoResourceFoundException;
import java.util.HashMap;
import java.util.Map;
@RestControllerAdvice
public class MyControllerExceptionHandler {
/**
* 异常处理的方法
* http://127.0.0.1:8080/index?numa=10&numb=2
*
* 默认的 @ControllerAdvice 的方法返回值,之试图 return 的之 应该是 error.html
* RestControllerAdvice 的方法返回值, 直接响应给客户端
*/
@ExceptionHandler(exception = Exception.class)
public Map handlerException(Exception ex) {
HashMap map = new HashMap<>();
if(ex instanceof NoResourceFoundException){
map.put("code",404);
}else{
map.put("code",500);
}
map.put("msg",ex.getMessage());
map.put("data",null);
return map;
}
}
```

# 静态资源
如果需要再springboot项目中添加静态资源,可以放在Resources/static
- /resources
- /public
- /static


# 使用spring-starter-validation进行数据验证
添加依赖
在需要校验的Controller参数上添加@Valid

添加校验规则


## 接受错误消息,抛出异常
```java
package com.neuedu.boot.controller;
import com.neuedu.boot.exception.ControllerException;
import com.neuedu.boot.po.User;
import jakarta.validation.Valid;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
@RestController
@RequestMapping("/user")
public class UserController {
/**
* http://127.0.0.1:8080/user/save?username=admin
* @param user
* @return
*/
@RequestMapping("/save")
public boolean save(@Valid User user , BindingResult rs) throws ControllerException {
System.out.println("模拟保存 user = " + user);
List allErrors = rs.getAllErrors();
StringBuffer errormsg = new StringBuffer();
for (ObjectError allError : allErrors) {
String defaultMessage = allError.getDefaultMessage();
String objectName = allError.getObjectName();
System.out.println("defaultMessage = " + defaultMessage);
System.out.println("objectName = " + objectName);
errormsg.append(defaultMessage);
}
if(errormsg.length()>0){
throw new ControllerException(errormsg.toString());
}
return true;
}
}
```

## 使用全局异常处理器捕获异常
```
package com.neuedu.boot.advice;
import com.neuedu.boot.exception.ControllerException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.resource.NoResourceFoundException;
import java.util.HashMap;
import java.util.Map;
@RestControllerAdvice
public class MyControllerExceptionHandler {
/**
* 异常处理的方法
* http://127.0.0.1:8080/user/save?username=admin222222222222222222222222222222222
*
* 默认的 @ControllerAdvice 的方法返回值,之试图 return 的之 应该是 error.html
* RestControllerAdvice 的方法返回值, 直接响应给客户端
*/
@ExceptionHandler(exception = Exception.class)
public Map handlerException(Exception ex) {
HashMap map = new HashMap<>();
if(ex instanceof NoResourceFoundException){
map.put("code",404);
}else if(ex instanceof ControllerException){
map.put("code",503);
} else{
map.put("code",500);
}
map.put("msg",ex.getMessage());
map.put("data",null);
return map;
}
}
```
# SpringJDBC
[Using the JDBC Core Classes to Control Basic JDBC Processing and Error Handling :: Spring Framework](https://docs.spring.io/spring-framework/reference/6.2/data-access/jdbc/core.html#jdbc-JdbcTemplate)
# 注册Servlet组件:
在SpringBoot中声明Servlet、Filter、Listener可以通过`@ServletComponentScan ` 去扫描 @WebServlet 、@WebFilter、@WebListener
```java
package com.neuedu.boot.servletcomponent;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(urlPatterns = "/oldServlet")
public class OldServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
out.write("原始的ServletAPI ");
out.flush();
out.close();
}
}
```

## 使用@Bean注册三大组件
```java
package com.neuedu.boot;
import com.neuedu.boot.servletcomponent.OldFilter;
import com.neuedu.boot.servletcomponent.OldListener;
import com.neuedu.boot.servletcomponent.OldServlet;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
/**
* Hello world!
*/
@SpringBootApplication
//@ServletComponentScan("com.neuedu.boot.servletcomponent")
public class App08 {
public static void main(String[] args) {
//SpringApplication.run(App08.class, args);
SpringApplication.run(App08.class, args);
}
//通过registion
@Bean
ServletRegistrationBean getServletRegistrationBean(){
ServletRegistrationBean registrationBean = new ServletRegistrationBean();
registrationBean.setServlet(new OldServlet());
registrationBean.addUrlMappings("/oldServlet");
return registrationBean;
}
@Bean
FilterRegistrationBean getFilterRegistrationBean(){
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(new OldFilter());
registrationBean.addUrlPatterns("/oldServlet");
return registrationBean;
}
@Bean
ServletListenerRegistrationBean getServletListenerRegistrationBean(){
ServletListenerRegistrationBean registrationBean = new ServletListenerRegistrationBean();
registrationBean.setListener(new OldListener());
return registrationBean;
}
}
```
# 跨域
## 使用@CrossOrigin注解,
```java
@RestController
@RequestMapping("/account")
public class AccountController {
@CrossOrigin
@GetMapping("/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
}
@DeleteMapping("/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}
```
```java
@CrossOrigin(origins = "https://domain2.com", maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {
@GetMapping("/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
}
@DeleteMapping("/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}
```
## 全局的配置
### CORS Filter
```java
@Bean
FilterRegistrationBean corsFilter() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("https://127.0.0.1");//前端的 URL浏览器的地址
config.addAllowedHeader("*");
config.addAllowedMethod("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
CorsFilter filter = new CorsFilter(source);
registrationBean.setFilter(filter);
registrationBean.addUrlPatterns("/*");
return registrationBean;
}
```
### 使用WebMvcConfigurer的实现类,重写addCorsMappings方法注册跨域
# 拦截器(MVC配置)
```java
package com.neuedu.boot.interceptors;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@Component
public class LoginHandlerInteceptors implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("LoginHandlerInteceptors.preHandle=== 1 ");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
System.out.println("LoginHandlerInteceptors.preHandle=== 2 ");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("LoginHandlerInteceptors.preHandle=== 3 ");
}
}
```
```java
package com.neuedu.boot.config;
import com.neuedu.boot.interceptors.LoginHandlerInteceptors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
//@EnableWebMvc springboot不需要编写
public class BootAppWebMvcConfiger implements WebMvcConfigurer {
@Autowired
LoginHandlerInteceptors loginHandlerInteceptors;
@Override
public void addInterceptors(InterceptorRegistry registry) {
//registry.addInterceptor(new LoginHandlerInteceptors())
registry.addInterceptor(loginHandlerInteceptors)
//拦截的请求
.addPathPatterns("/*/**")
//不拦截的请求
.excludePathPatterns("/login");
}
@Override
public void addCorsMappings(CorsRegistry registry) {
//注册跨域
registry.addMapping("/*/**")
.allowedOrigins("https://127.0.0.1")
.allowedMethods("*");
//.allowedHeaders("header1", "header2", "header3")
//.exposedHeaders("header1", "header2")
//.allowCredentials(true).maxAge(3600);
}
}
```
# 整合MyBatis
## 创建Boot的mvc项目
基础包:com.neuedu.mybatis
- SpringBoot的启动类
- 测试的Controller
## 整合
在Boot中整合MyBatis 使用 starter`MyBatis Spring Boot Starter`:Spring Boot starter for MyBatis that simplifies
integration of MyBatis SQL mapping framework in Spring Boot applications.
- 添加依赖
- 配置数据源 url、username、password、dirverClassName
- 使用工具生成
- Mapper.java
- Mapper.xml
- PO
- 扫描 @MapperScan
-
- 测试
### 依赖
```xml
org.mybatis.spring.boot
mybatis-spring-boot-starter
${mybatis.version}
compile
com.mysql
mysql-connector-j
```
添加完依赖之后启动报错
,因为引入mybatis-starter会自动配置数据源但是缺少url、username、password、driverClassname的配置,配之完数据源,因为依赖中有自动配置,所以无需额外注册SQLSessionFactory等,其中自动配置类
`MybatisAutoConfiguration`自动注册SQLSessionFactory



### 配置数据源
- 在application.yaml
```
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/his?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&&useSSL=false
username: root
password: root
```
### 生成Mapper.java ,PO、Mapper.xml



## 注册Mapper
在IOC容器中注册Mapper

## 测试Mapper使用
```java
package com.neuedu.mybatis.mapper;
import com.neuedu.mybatis.MyBatisApp;
import com.neuedu.mybatis.po.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import static org.junit.jupiter.api.Assertions.*;
//@SpringBootTest(classes = MyBatisApp.class)
@SpringBootTest()
class UserMapperTest {
@Autowired
private UserMapper userMapper;
@Test
void selectByPrimaryKey() {
long id = 1;
User user = userMapper.selectByPrimaryKey(id);
System.out.println(user);
}
}
```

# 使用Springboot+myabtis 实现crud
整合依赖,jwt、分页插件
```xml
4.0.0
com.neuedu.boot
springboot-learn
1.0
boot-09-mybatis
jar
boot-09-mybatis
http://maven.apache.org
UTF-8
3.0.5
4.5.0
6.1.1
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-validation
org.springframework.boot
spring-boot-starter-test
org.projectlombok
lombok
org.springframework.boot
spring-boot-devtools
org.mybatis.spring.boot
mybatis-spring-boot-starter
${mybatis.version}
compile
com.mysql
mysql-connector-j
com.auth0
java-jwt
${auth0.version}
com.github.pagehelper
pagehelper
${pagerhelper.version}
org.springframework.boot
spring-boot-maven-plugin
```
复制Ret、JWTUtils、异常管理器、拦截器等,改下包名

配置拦截器
```java
package com.neuedu.mybatis.config;
import com.neuedu.mybatis.interceptor.LoginInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MvcConfig implements WebMvcConfigurer {
/**
* 配置拦截器
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/*/**")
.excludePathPatterns("/login");
}
}
```
全局的异常处理器
```java
package com.neuedu.mybatis.framework;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
@RestControllerAdvice
public class BusinessHandlerExceptionResolver {
@ExceptionHandler(Exception.class)
public Ret resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
String message = ex.getMessage();
ObjectMapper objectMapper = new ObjectMapper();
//String userJson = objectMapper.writeValueAsString(users);
Ret ret = Ret.fail(message != null ? message : "操作失败");
return ret;
}
}
```
# MyBatisPlus搭建
- **无侵入**:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
- **损耗小**:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
- **强大的 CRUD 操作**:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
- **支持 Lambda 形式调用**:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
- **支持主键自动生成**:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
- **支持 ActiveRecord 模式**:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
- **支持自定义全局通用操作**:支持全局通用方法注入( Write once, use anywhere )
- **内置代码生成器**:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
- **内置分页插件**:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
- **分页插件支持多种数据库**:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
- **内置性能分析插件**:可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
- **内置全局拦截插件**:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
## 创建一个空的 Spring Boot 工程 添加依赖
```xml
4.0.0
com.neuedu.boot
springboot-learn
1.0
boot-10-mp
jar
boot-10-mp
http://maven.apache.org
UTF-8
4.5.0
3.5.15
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-validation
org.springframework.boot
spring-boot-starter-test
org.projectlombok
lombok
org.springframework.boot
spring-boot-devtools
com.baomidou
mybatis-plus-spring-boot3-starter
${mp.version}
com.mysql
mysql-connector-j
com.auth0
java-jwt
${auth0.version}
org.springframework.boot
spring-boot-maven-plugin
```
配置数据源
```yaml
spring:
# 数据源的配置
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/his?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&&useSSL=false
username: root
password: root
```
## 启动类添加MapperScan
```java
package com.neuedu.boot;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Hello world!
*
*/
@SpringBootApplication
@MapperScan("com.neuedu.boot.mapper")
public class MPApp
{
public static void main( String[] args )
{
SpringApplication.run(MPApp.class,args);
}
}
```
## 实体类
User
```java
package com.neuedu.boot.po;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableName;
/**
* 用户表
*
* @TableName user
*/
@Data
@TableName("`user`")
public class User implements Serializable {
/**
* 主键
*/
private Long userId;
/**
* 用户名
*/
private String username;
/**
* 密码
*/
private String password;
/**
* 过期时间
*/
private Date expire;
/**
* 最后一次登录四件
*/
private Date lastLogin;
/**
* 真实姓名
*/
private String realName;
/**
* 部门ID
*/
private Long deptId;
/**
* 部门名称
*/
private String deptName;
/**
* 级别ID
*/
private Long levelId;
/**
* 创建时间
*/
private Date createTime;
private static final long serialVersionUID = 1L;
@Override
public boolean equals(Object that) {
if (this == that) {
return true;
}
if (that == null) {
return false;
}
if (getClass() != that.getClass()) {
return false;
}
User other = (User) that;
return (this.getUserId() == null ? other.getUserId() == null : this.getUserId().equals(other.getUserId()))
&& (this.getUsername() == null ? other.getUsername() == null : this.getUsername().equals(other.getUsername()))
&& (this.getPassword() == null ? other.getPassword() == null : this.getPassword().equals(other.getPassword()))
&& (this.getExpire() == null ? other.getExpire() == null : this.getExpire().equals(other.getExpire()))
&& (this.getLastLogin() == null ? other.getLastLogin() == null : this.getLastLogin().equals(other.getLastLogin()))
&& (this.getRealName() == null ? other.getRealName() == null : this.getRealName().equals(other.getRealName()))
&& (this.getDeptId() == null ? other.getDeptId() == null : this.getDeptId().equals(other.getDeptId()))
&& (this.getDeptName() == null ? other.getDeptName() == null : this.getDeptName().equals(other.getDeptName()))
&& (this.getLevelId() == null ? other.getLevelId() == null : this.getLevelId().equals(other.getLevelId()))
&& (this.getCreateTime() == null ? other.getCreateTime() == null : this.getCreateTime().equals(other.getCreateTime()));
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((getUserId() == null) ? 0 : getUserId().hashCode());
result = prime * result + ((getUsername() == null) ? 0 : getUsername().hashCode());
result = prime * result + ((getPassword() == null) ? 0 : getPassword().hashCode());
result = prime * result + ((getExpire() == null) ? 0 : getExpire().hashCode());
result = prime * result + ((getLastLogin() == null) ? 0 : getLastLogin().hashCode());
result = prime * result + ((getRealName() == null) ? 0 : getRealName().hashCode());
result = prime * result + ((getDeptId() == null) ? 0 : getDeptId().hashCode());
result = prime * result + ((getDeptName() == null) ? 0 : getDeptName().hashCode());
result = prime * result + ((getLevelId() == null) ? 0 : getLevelId().hashCode());
result = prime * result + ((getCreateTime() == null) ? 0 : getCreateTime().hashCode());
return result;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getClass().getSimpleName());
sb.append(" [");
sb.append("Hash = ").append(hashCode());
sb.append(", userId=").append(userId);
sb.append(", username=").append(username);
sb.append(", password=").append(password);
sb.append(", expire=").append(expire);
sb.append(", lastLogin=").append(lastLogin);
sb.append(", realName=").append(realName);
sb.append(", deptId=").append(deptId);
sb.append(", deptName=").append(deptName);
sb.append(", levelId=").append(levelId);
sb.append(", createTime=").append(createTime);
sb.append(", serialVersionUID=").append(serialVersionUID);
sb.append("]");
return sb.toString();
}
}
```
## 编写 Mapper 接口类 `UserMapper.java`
单表的CRUD 不需要额外写内容个
```java
public interface UserMapper extends BaseMapper {
}
```
## 添加测试类,进行功能测试:
```java
package com.neuedu.boot.mapper;
import com.neuedu.boot.MPApp;
import com.neuedu.boot.po.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest(classes = MPApp.class)
class UserMapperTest {
@Autowired
private UserMapper userMapper;
@Test
public void testSelectByID(){
long id = 1L;
User user = userMapper.selectById(id);
System.out.println(user);
}
@Test
public void test(){
List list = userMapper.selectList(null);
System.out.println(list);
}
}
```
## Service层接口的用法
跟Mapper层的区别是更新操作会携带事务
```java
package com.neuedu.boot.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.neuedu.boot.mapper.UserMapper;
import com.neuedu.boot.po.User;
import org.springframework.stereotype.Service;
@Service
public class UserService extends ServiceImpl {
}
```
```java
package com.neuedu.boot.service;
import com.neuedu.boot.po.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
class UserServiceTest {
@Autowired
private UserService userService;
/**
*
*/
@Test
public void testGetById(){
long id = 1L;
User user = userService.getById(id);
System.out.println(user);
}
}
```
# MP使用
持久层接口
- Mapper
- Service
## Service层方法
service方法详见官网文档,[传送门](https://www.baomidou.com/guides/data-interface/)
```java
package com.neuedu.boot.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.neuedu.boot.po.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.Date;
import java.util.List;
@SpringBootTest
class UserServiceTest {
@Autowired
private UserService userService;
@Test
public void testList() {
//全量查询
//List list = userService.list();
//list.forEach(System.out::println);
//带条件查询
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.like("username", "a");
List list = userService.list(queryWrapper);
list.forEach(System.out::println);
}
/**
*
*/
@Test
public void testGetById() {
long id = 1L;
User user = userService.getById(id);
System.out.println(user);
}
@Test
public void testSave() {
User user = new User();
user.setUsername("mp-user");
user.setPassword("mp-123456");
user.setRealName("mp-管理员");
boolean success = userService.save(user);
System.out.println(success);
}
//删除
@Test
public void testRemove() {
//根据主键删除
//long id = 20L;
//boolean success = userService.removeById(id);
//System.out.println(success);
//根据条件删除 删除条件 QueryWrapper 条件构造器
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.eq("username", "mp-user");
queryWrapper.like("password", "mp-123456");
boolean success = userService.remove(queryWrapper);
System.out.println(success);
}
@Test
public void testUpdate() {
//User user = userService.getById(17L);
//user.setRealName("使用MP更新");
//
//boolean success = userService.updateById(user);
//System.out.println(success);
User user = new User();
user.setExpire(new Date());
//根据条件删除 删除条件 QueryWrapper 条件构造器
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.eq("password", "123456");
boolean success = userService.update(user,queryWrapper);
System.out.println(success);
}
}
```
## Mapper分层方法
mapper层已经实现的方法 [传送门](https://www.baomidou.com/guides/data-interface/#mapper-interface)
```java
package com.neuedu.boot.mapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.neuedu.boot.MPApp;
import com.neuedu.boot.po.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.Date;
import java.util.List;
@SpringBootTest(classes = MPApp.class)
class UserMapperTest {
@Autowired
private UserMapper userMapper;
@Test
public void testSelectByID() {
long id = 1L;
User user = userMapper.selectById(id);
System.out.println(user);
}
@Test
public void test() {
List list = userMapper.selectList(null);
System.out.println(list);
}
@Test
public void testList() {
//全量查询
//List list = userService.list();
//list.forEach(System.out::println);
//带条件查询
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.like("username", "a");
List list = userMapper.selectList(queryWrapper);
list.forEach(System.out::println);
}
/**
*
*/
@Test
public void testGetById() {
long id = 1L;
User user = userMapper.selectById(id);
System.out.println(user);
}
@Test
public void testSave() {
User user = new User();
user.setUsername("mp-user-mapper");
user.setPassword("mp-123456-mapper");
user.setRealName("mp-管理员-mapper");
int count = userMapper.insert(user);
System.out.println(count);
}
//删除
@Test
public void testRemove() {
//根据主键删除
//long id = 20L;
//boolean success = userService.removeById(id);
//System.out.println(success);
//根据条件删除 删除条件 QueryWrapper 条件构造器
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.eq("username", "mp-user");
queryWrapper.like("password", "mp-123456");
int count = userMapper.delete(queryWrapper);
System.out.println(count);
}
@Test
public void testUpdate() {
//User user = userMapper.selectById(17L);
//user.setRealName("使用MP更新");
//
//int count = userMapper.updateById(user);
//System.out.println(count);
User user = new User();
user.setExpire(new Date());
//根据条件删除 删除条件 QueryWrapper 条件构造器
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.eq("password", "123456");
int count = userMapper.update(user, queryWrapper);
System.out.println(count);
}
}
```
## 分页
### 添加依赖
```xml
com.baomidou
mybatis-plus-jsqlparser
${mp.version}
```
### 注册分页插件
```java
package com.neuedu.boot.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyBatisPlusConfig {
/**
* 添加分页插件
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
```
### 使用分页
```java
package com.neuedu.boot.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.neuedu.boot.po.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.Date;
import java.util.List;
@SpringBootTest
class UserServicePageTest {
@Autowired
private UserService userService;
@Test
public void testPage() {
int current = 1;
int size = 5;
Page page = userService.page(new Page<>(current, size));
//总页数
long pages = page.getPages();
//总条数
long total = page.getTotal();
//分页数据
List records = page.getRecords();
System.out.println("current = " + current);
System.out.println("size = " + size);
System.out.println("pages = " + pages);
System.out.println("total = " + total);
System.out.println("records = " + records);
current = 2;
//size = 5;
System.out.println("\r\n\r\n\r\n");
//第二页的数据
page = userService.page(new Page<>(current, size));
//总页数
pages = page.getPages();
//总条数
total = page.getTotal();
//分页数据
records = page.getRecords();
System.out.println("current = " + current);
System.out.println("size = " + size);
System.out.println("pages = " + pages);
System.out.println("total = " + total);
System.out.println("records = " + records);
}
}
```
## LambdaQueryWarpper
### JDK1.8添加了一个Lambda的功能
```java
package com.neuedu;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Stream;
public class Runner {
public static void main(String[] args) {
List list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
//filter 的作用是过滤 Stream
//Stream stream = list.stream().filter(new Predicate() {
// @Override
// public boolean test(Integer num) {
// return num % 2 == 0;
// }
//});
//
////循环
//stream.forEach(new Consumer(){
//
// @Override
// public void accept(Integer integer) {
// System.out.println(integer);
// }
//});
//filter 的作用是过滤
//Stream stream = list.stream().filter( (Integer num) ->{
// return num % 2 == 0;
// }
//);
//lambda 过滤
Stream stream = list.stream().filter( num-> num % 2 == 0 );
//stream.forEach((Integer num)->{
// System.out.println( num);
//});
//stream.forEach( num-> System.out.println( num) );
//方法 的传递 对象的方法发
stream.forEach( System.out::println );
//静态方法的传递
stream.forEach( Out::show );
//构造方法的传递
//Runnable aNew = Out::new;
}
}
class Out{
public static void show(int a){
System.out.println(a);
}
}
```
```
package com.neuedu.boot.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.neuedu.boot.po.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.Date;
import java.util.List;
@SpringBootTest
class UserServiceLambdaQueryWrapperTest {
@Autowired
private UserService userService;
@Test
public void testList() {
//全量查询
//List list = userService.list();
//list.forEach(System.out::println);
//带条件查询
LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.like(User::getUsername, "a");
List list = userService.list(queryWrapper);
list.forEach(System.out::println);
}
}
```
## 主键生成策略
```java
CREATE TABLE `his`.`mybatisplus`(
`id` VARCHAR(50) NOT NULL COMMENT '主键',
`name` VARCHAR(100) COMMENT '姓名',
`age` int(100) COMMENT '年龄',
PRIMARY KEY (`id`)
);
```
```java
package com.neuedu.boot.po;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* 用户表
*
* @TableName user
*/
@Data
@TableName("`mybatisplus`")
public class MyBaitsPlusPO implements Serializable {
/**
* 主键
*/
@TableId(type = IdType.ASSIGN_UUID)
private String id; //user_id
private String name; //user_id
private Integer age; //user_id
}
```
## 逻辑删除
```sql
ALTER TABLE `his`.`mybatisplus`
ADD COLUMN `is_delete` VARCHAR(3) DEFAULT '0' NULL COMMENT '是否删除,0 正常,1 已删除' AFTER `age`;
```

## 乐观锁:
为了解决并发下更新数据的问题,可以给数据加个锁

### for update
需要再事务的下面才生效,悲观锁,只要操作数据直接加锁,

```添加锁的字段
ALTER TABLE `his`.`mybatisplus`
ADD COLUMN `version` INT DEFAULT 0 NULL COMMENT '自定义的锁' AFTER `is_delete`;
```

```java
@Configuration
public class MyBatisPlusConfig {
/**
* 添加分页插件
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
//乐观锁插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
```
### 测试
```java
package com.neuedu.boot.service;
import com.neuedu.boot.po.MyBaitsPlusPO;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class LockTest {
//@Resource
@Autowired
private MyBaitsPlusService myBaitsPlusService;
@Test
public void testLock1() {
//先查询数据
String id = "5c2ea8366411cf26d9bd3a78aaa39aad";
MyBaitsPlusPO po = myBaitsPlusService.getById(id);
//断点
System.out.println();
po.setAge(po.getAge() + 10);
//更新
boolean success = myBaitsPlusService.updateById(po);
System.out.println(success);
}
}
```
第二个更新会失败,乐观锁生效

## 代码生成器(MyBatisX插件)
基础的包:
```
com.neuedu.boot
```
- Controller : com.neuedu.boot.controller
- Service:
- 接口: com.neuedu.boot.service
- impl: com.neuedu.boot.service.impl
- Mapper: com.neuedu.boot.mapper
- 实体类: com.neuedu.boot.domain com.neuedu.boot.po
### 使用程序生成代码
添加依赖 [Maven Repository: com.baomidou » mybatis-plus-generator](https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-generator)
```xml
com.baomidou
mybatis-plus-generator
3.5.15
compile
或者
com.baomidou
mybatis-plus-generator
${mp.version}
test
freemarker模版的依赖
org.freemarker
freemarker
2.3.34
compile
```
```java
package com.neuedu.boot;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import org.junit.jupiter.api.Test;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import java.nio.file.Paths;
import java.util.Collections;
/**
* @author 张金山
* @date 2023/4/17 16:05
*/
public class MPGenerator {
@Test
public void test() {
String url = "jdbc:mysql://localhost:3306/his?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&&useSSL=false";
String username = "root";
String password = "root";
String tables[] = {"user", "upload"};
//jdbc 4.0
//String driverName = "com.mysql.cj.jdbc.Driver";
FastAutoGenerator.create(url, username, password)
.globalConfig(builder -> builder
.author("金山老师")
.outputDir(Paths.get(System.getProperty("user.dir")) + "/src/main/java")
.commentDate("yyyy-MM-dd")
)
//包的配置
.packageConfig(builder -> builder
.parent("com.neuedu.boot")
.entity("po")
.mapper("mapper")
.service("service")
.serviceImpl("service.impl")
.xml("mapper")
//单独映射 Mapper。xml的位置
.pathInfo(Collections.singletonMap(OutputFile.xml, Paths.get(System.getProperty("user.dir"))+"/src/main/resources/mapper")) // 设置路径配置信息
)
//策略的配置
.strategyConfig(builder -> builder
//.addInclude("user", "upload") // 设置需要生成的表名
//.addInclude(tables) // 设置需要生成的表名
.entityBuilder()
.enableLombok()
//覆盖原来的文件
.enableFileOverride()
)
.templateEngine(new FreemarkerTemplateEngine())
.execute();
}
@Test
public void testPath(){
String property = System.getProperty("user.dir");
System.out.println(property);
}
}
```
添加springboot的配置,测试mapper是否生效
```java
package com.neuedu.boot.mapper;
import com.neuedu.boot.po.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
class UserMapperTest {
@Autowired
private UserMapper userMapper;
@Test
void insert() {
long id = 1L;
User user = userMapper.selectById(id);
System.out.println(user);
}
}
```
### 使用插件
安装

创建数据源
选择表右键生成代码


## 自动填充字段
MyBatis-Plus 提供了一个便捷的自动填充功能,用于在插入或更新数据时自动填充某些字段,如创建时间、更新时间等。以下是如何使用这一功能的详细说明。
```sql
CREATE TABLE `his`.`person`(
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '人员id',
`name` VARCHAR(100) COMMENT '姓名',
`age` INT COMMENT '年龄',
`create_by` VARCHAR(100) COMMENT '创建人',
`create_time` DATETIME COMMENT '创建时间',
`update_by` VARCHAR(100) COMMENT '更新人',
`update_time` DATETIME COMMENT '更新时间',
PRIMARY KEY (`id`)sql
);
```
使用代码生成器生成代码
包扫描
```java
package com.neuedu.boot;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Hello world!
*
*/
@SpringBootApplication
@MapperScan("com.neuedu.boot.mapper")
public class AppAuoFill {
public static void main(String[] args) {
SpringApplication.run(AppAuoFill.class, args);
}
}
```
在实体类中添加自动填充注解
```java
package com.neuedu.boot.po;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
*
*
*
*
* @author 金山老师
* @since 2026-03-31
*/
@Getter
@Setter
@ToString
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 人员id
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 姓名
*/
private String name;
/**
* 年龄
*/
private Integer age;
/**
* 创建人
*/
@TableField(fill = FieldFill.INSERT)
private String createBy;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
/**
* 更新人
*/
@TableField(fill = FieldFill.UPDATE)
private String updateBy;
/**
* 更新时间
*/
@TableField(fill = FieldFill.UPDATE)
private LocalDateTime updateTime;
}
```
在容器中注册一个实现MetaObjectHandler的类,其中需要自动填充的字段名称可以自己定义
```java
package com.neuedu.boot.common.mp;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
// java example
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
/**
* 插入的时候会出发这个方法,使用通用的代码来 进行田中
* @param metaObject
*/
@Override
public void insertFill(MetaObject metaObject) {
log.info("开始插入填充...");
this.strictInsertFill(metaObject, "createBy", String.class, "admin");
this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
}
@Override
public void updateFill(MetaObject metaObject) {
log.info("开始更新填充...");
this.strictUpdateFill(metaObject, "updateBy", String.class, "root");
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
}
}
```
### 测试添加和更新
```java
package com.neuedu.boot.mapper;
import com.neuedu.boot.po.Person;
import com.neuedu.boot.service.IPersonService;
import com.neuedu.boot.service.impl.PersonServiceImpl;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
class PersonMapperTest {
@Autowired
private IPersonService personService;
@Test
void insert() {
Person person = new Person();
person.setName("李四");
person.setAge(28);
//设置冗余字段 create——by time update_by time ,每一个表都有,可以使用全局的 自动填充字段
boolean success = personService.save(person);
System.out.println(success);
}
@Test
void update() {
Person person = new Person();
person.setId(2L);
person.setName("王五");
boolean success = personService.updateById(person);
System.out.println(success);
}
}
```
## 注解配置
- @TableName : 该注解用于指定实体类对应的数据库表名。当实体类名与数据库表名不一致,或者实体类名不是数据库表名的驼峰写法时,您需要使用这个注解来明确指定表名
- value 表名
- excludeProperty 指定在映射时需要排除的属性名。这些属性将不会被包含在生成的 SQL 语句
- @TableId : 该注解用于标记实体类中的主键字段。如果你的主键字段名为 id,你可以省略这个注解。
- TableField: 该注解用于标记实体类中的非主键字段,它告诉 MyBatis-Plus
如何映射实体类字段到数据库表字段。如果你的实体类字段名遵循驼峰命名规则,并且与数据库表字段名一致,你可以省略这个注解。
- value: 指定数据库中的字段名。如果你的实体类字段名与数据库字段名不同,使用这个属性来指定正确的数据库字段名
- exist: 指示这个字段是否存在于数据库表中。如果设置为 false,MyBatis-Plus 在生成 SQL 时会忽略这个字段。
- fill: 段自动填充策略。该属性用于指定在执行数据库操作(如插入、更新)时,如何自动填充字段的值。通过使用 FieldFill
枚举,可以灵活地控制字段的填充行为
- @Version: 该注解用于标记实体类中的字段作为乐观锁版本号字段。乐观锁是一种并发控制机制,它假设多个事务可以同时进行而不会互相干扰,只在提交事务时检查是否有冲突。通过在实体类中使用
`@Version`注解,MyBatis-Plus 会在更新操作时自动检查版本号,确保在更新过程中数据没有被其他事务修改
- @EnumValue: 该注解用于标记枚举类中的字段,指定在数据库中存储的枚举值。当实体类中的某个字段是枚举类型时,使用@EnumValue注解可以告诉MyBatis-Plus在数据库中存储枚举值的哪个属性
@TableLogic:该注解用于标记实体类中的字段作为逻辑删除字段。逻辑删除是一种数据管理策略,它不是真正地从数据库中删除记录,而是在记录中标记该记录为已删除状态。通过使用
`@TableLogic`注解,MyBatis-Plus 可以在查询、更新和删除操作中自动处理逻辑删除字段的值。
- OrderBy:注解用于指定实体类中的字段在执行查询操作时的默认排序方式。通过在实体类字段上使用@OrderBy注解,可以确保在执行查询时,如果没有显式指定排序条件,MyBatis-Plus
将按照注解中定义的排序规则返回结果。