0. Предисловие
Всем привет, меня зовут Гид! Вот моя 221 высококачественная оригинальная статья. Если нужно перепечатать, пожалуйста, указывайте адрес в начале текста, краб!
Эта статья была включена в мой проект с открытым исходным кодом 75K Star Java JavaGuide:GitHub.com/snail Climb/…Связанное чтение:Версия "JavaGuide Interview Assault Edition" версии 2.0 уже доступна! А вот и онлайн-версия для чтения!
Не будет преувеличением сказать, что общие аннотации Spring/SpringBoot, представленные в этой статье, в основном охватывают большинство распространенных сценариев, с которыми вы сталкиваетесь в своей работе. Для каждой аннотации я сказал конкретное использование, освоенное и понятое, и использование SpringBoot для разработки проектов в основном не представляет большой проблемы!
Зачем писать эту статью?
Недавно я увидел в Интернете статью об общих аннотациях SpringBoot, которые много раз перепечатывались.После прочтения содержания статьи я действительно чувствую, что качество немного низкое, и это немного вводит в заблуждение людей, которые этого не делают. t имеют большой практический опыт (эти люди занимают большую часть ). Итак, я просто провел около двух дней, подытоживая это.
Поскольку мои личные способности и энергия ограничены, если что-то не так или что-то нужно исправить, пожалуйста, помогите указать! Гид брат очень благодарен!
1. @SpringBootApplication
Вытащите его здесь первым@SpringBootApplication
Обратите внимание, хотя мы обычно не используем его активно.
Руководство Brother: Эта аннотация является краеугольным камнем проекта Spring Boot. Она будет добавлена в основной класс по умолчанию после создания проекта Spring Boot.
@SpringBootApplication
public class SpringSecurityJwtGuideApplication {
public static void main(java.lang.String[] args) {
SpringApplication.run(SpringSecurityJwtGuideApplication.class, args);
}
}
мы можем поставить@SpringBootApplication
рассматривается как@Configuration
,@EnableAutoConfiguration
,@ComponentScan
Сборник аннотаций.
package org.springframework.boot.autoconfigure;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
......
}
package org.springframework.boot;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}
Согласно официальному сайту SpringBoot, эти три аннотации выполняют следующие функции:
-
@EnableAutoConfiguration
: включить механизм автоматической настройки SpringBoot. -
@ComponentScan
: сканирование есть@Component
(@Service
,@Controller
) аннотированный компонент, аннотация будет сканировать все классы в пакете, где класс находится по умолчанию. -
@Configuration
: позволяет зарегистрировать дополнительные bean-компоненты или импортировать другие классы конфигурации в контексте Spring.
2. Весенняя фасоль
2.1. @Autowired
Объект автоматически импортируется в класс, а внедренный класс также должен управляться контейнером Spring, например, класс Service внедряется в класс Controller.
@Service
public class UserService {
......
}
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
......
}
2.2. Component
,@Repository
,@Service
, @Controller
Обычно мы используем@Autowired
Аннотации позволяют контейнеру Spring автоматически подключать bean-компоненты для нас. Чтобы пометить курс как доступный для@Autowired
Аннотирование классов автосвязанных компонентов может быть реализовано с использованием следующих аннотаций:
-
@Component
: Общая аннотация, которая может помечать любой класс какSpring
компоненты. Если бин не знает, к какому слою он принадлежит, вы можете использовать@Component
Аннотация аннотация. -
@Repository
: соответствующий уровень сохраняемости — это уровень Dao, который в основном используется для операций, связанных с базой данных. -
@Service
: Что касается сервисного уровня, он в основном включает в себя некоторую сложную логику и должен использовать уровень Dao. -
@Controller
: в соответствии с уровнем управления Spring MVC основной пользователь принимает запросы пользователей и вызывает уровень службы для возврата данных на интерфейсную страницу.
2.3. @RestController
@RestController
Аннотация@Controller和
@ResponseBody
Это означает, что это bean-компонент контроллера, который напрямую заполняет возвращаемое значение функции в тело ответа HTTP, которое является контроллером в стиле REST.
Brother Guide: Передняя и задняя части теперь разделены, Честно говоря, я не использовал это в течение длительного времени.@Controller
. Если ваш проект слишком стар, просто притворитесь, что я этого не говорил.
Использовать отдельно@Controller
не добавлять@ResponseBody
Обычно он используется в случае возврата представления, принадлежащего более традиционному приложению Spring MVC, что соответствует ситуации, когда передняя и задняя части не разделены.@Controller
+@ResponseBody
Возвращает данные в формате JSON или XML
о@RestController
и@Controller
Для сравнения смотрите эту статью:@RestController vs @Controller.
2.4. @Scope
Чтобы объявить область действия Spring Bean, используйте метод:
@Bean
@Scope("singleton")
public Person personSingleton() {
return new Person();
}
Четыре общих области действия Spring Bean:
- singleton : единственный экземпляр bean-компонента, bean-компоненты в Spring по умолчанию являются одноэлементными.
- прототип: новый экземпляр компонента создается при каждом запросе.
- request : каждый HTTP-запрос будет генерировать новый bean-компонент, который действителен только в рамках текущего HTTP-запроса.
- session : каждый HTTP-запрос будет генерировать новый bean-компонент, который действителен только в рамках текущего HTTP-сеанса.
2.5. Configuration
Обычно используется для объявления классов конфигурации, вы можете использовать@Component
Вместо этого используйте аннотацию, но используйтеConfiguration
Аннотации, объявляющие классы конфигурации, более семантичны.
@Configuration
public class AppConfig {
@Bean
public TransferService transferService() {
return new TransferServiceImpl();
}
}
3. Обработка распространенных типов HTTP-запросов
5 распространенных типов запросов:
-
GET: запрос на получение определенного ресурса с сервера. Например:
GET /users
(Собрать всех учеников) -
POST: Создает новый ресурс на сервере. Например:
POST /users
(создать ученика) -
PUT: обновить ресурс на сервере (клиент предоставляет весь обновленный ресурс). Например:
PUT /users/12
(Обновление для ученика №12) -
DELETE: удалить определенный ресурс с сервера. Например:
DELETE /users/12
(удалить учащегося номер 12) - PATCH: Обновление ресурсов на сервере (клиент предоставляет измененные свойства, что можно расценивать как частичное обновление), которое меньше используется, поэтому здесь нет примера.
3.1. ПОЛУЧИТЬ запрос
@GetMapping("users")
Эквивалентно@RequestMapping(value="/users",method=RequestMethod.GET)
@GetMapping("/users")
public ResponseEntity<List<User>> getAllUsers() {
return userRepository.findAll();
}
3.2. POST-запрос
@PostMapping("users")
Эквивалентно@RequestMapping(value="/users",method=RequestMethod.POST)
о@RequestBody
Использование аннотаций будет рассмотрено ниже в разделе «Передача значений между интерфейсом и интерфейсом».
@PostMapping("/users")
public ResponseEntity<User> createUser(@Valid @RequestBody UserCreateRequest userCreateRequest) {
return userRespository.save(user);
}
3.3. PUT-запрос
@PutMapping("/users/{userId}")
Эквивалентно@RequestMapping(value="/users/{userId}",method=RequestMethod.PUT)
@PutMapping("/users/{userId}")
public ResponseEntity<User> updateUser(@PathVariable(value = "userId") Long userId,
@Valid @RequestBody UserUpdateRequest userUpdateRequest) {
......
}
3.4. Удалить запрос
@DeleteMapping("/users/{userId}")
Эквивалентно@RequestMapping(value="/users/{userId}",method=RequestMethod.DELETE)
@DeleteMapping("/users/{userId}")
public ResponseEntity deleteUser(@PathVariable(value = "userId") Long userId){
......
}
3.5. ИСПРАВЛЕНИЕ запрос
Как правило, в практических проектах мы используем только запросы PATCH для обновления данных после того, как PUT недостаточно.
@PatchMapping("/profile")
public ResponseEntity updateStudent(@RequestBody StudentUpdateRequest studentUpdateRequest) {
studentRepository.updateDetail(studentUpdateRequest);
return ResponseEntity.ok().build();
}
4. Передача значений между фронтом и бекендом
Овладение правильной позицией переноса стоимости через интерфейс и сервер — это первый шаг для запуска CRUD!
4.1. @PathVariable
и@RequestParam
@PathVariable
для получения параметров пути,@RequestParam
Используется для получения параметров запроса.
Возьмем простой пример:
@GetMapping("/klasses/{klassId}/teachers")
public List<Teacher> getKlassRelatedTeachers(
@PathVariable("klassId") Long klassId,
@RequestParam(value = "type", required = false) String type ) {
...
}
Если наш запрошенный URL:/klasses/{123456}/teachers?type=web
Тогда данные, полученные нашим сервисом:klassId=123456,type=web
.
4.2. @RequestBody
Используется для чтения части тела запроса запроса (возможно, запроса POST, PUT, DELETE, GET) иContent-Type — это приложение/json.После получения данных данные будут автоматически привязаны к объекту Java. система будет использоватьHttpMessageConverter
или обычайHttpMessageConverter
Преобразуйте строку json в теле запроса в объект java.
Я использую простой пример, чтобы продемонстрировать основное использование!
У нас есть зарегистрированный интерфейс:
@PostMapping("/sign-up")
public ResponseEntity signUp(@RequestBody @Valid UserRegisterRequest userRegisterRequest) {
userService.save(userRegisterRequest);
return ResponseEntity.ok().build();
}
UserRegisterRequest
Объект:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserRegisterRequest {
@NotBlank
private String userName;
@NotBlank
private String password;
@FullName
@NotBlank
private String fullName;
}
Мы отправляем post-запрос на этот интерфейс, а тело несет данные JSON:
{"userName":"coder","fullName":"shuangkou","password":"123456"}
Таким образом, наш бэкэнд может напрямую сопоставлять данные в формате json с нашимUserRegisterRequest
класс.
👉 Обратите внимание, что:Метод запроса может иметь только один@RequestBody
, но их может быть несколько@RequestParam
и@PathVariable
. Если ваш метод должен использовать два@RequestBody
Если вы приходите принимать данные, есть большая вероятность, что есть проблема с вашей базой данных или дизайном системы!
5. Прочтите информацию о конфигурации
Во многих случаях нам нужно поместить в файл конфигурации некоторую часто используемую информацию о конфигурации, такую как операционная система Alibaba Cloud, отправка SMS и информация о конфигурации, связанная с аутентификацией WeChat.
Давайте посмотрим, какие способы Spring предоставляет нам, чтобы помочь нам прочитать эту информацию о конфигурации из файлов конфигурации.
Наши источники данныхapplication.yml
Содержание следующее:
wuhan2020: 2020年初武汉爆发了新型冠状病毒,疫情严重,但是,我相信一切都会过去!武汉加油!中国加油!
my-profile:
name: Guide哥
email: koushuangbwcx@163.com
library:
location: 湖北武汉加油中国加油
books:
- name: 天才基本法
description: 二十二岁的林朝夕在父亲确诊阿尔茨海默病这天,得知自己暗恋多年的校园男神裴之即将出国深造的消息——对方考取的学校,恰是父亲当年为她放弃的那所。
- name: 时间的秩序
description: 为什么我们记得过去,而非未来?时间“流逝”意味着什么?是我们存在于时间之内,还是时间存在于我们之中?卡洛·罗韦利用诗意的文字,邀请我们思考这一亘古难题——时间的本质。
- name: 了不起的我
description: 如何养成一个新习惯?如何让心智变得更成熟?如何拥有高质量的关系? 如何走出人生的艰难时刻?
5.1. @value
(обычно используется)
использовать@Value("${property}")
Прочитайте относительно простую информацию о конфигурации:
@Value("${wuhan2020}")
String wuhan2020;
5.2. @ConfigurationProperties
(обычно используется)
пройти через@ConfigurationProperties
Прочитайте информацию о конфигурации и выполните привязку с помощью bean-компонентов.
@Component
@ConfigurationProperties(prefix = "library")
class LibraryProperties {
@NotEmpty
private String location;
private List<Book> books;
@Setter
@Getter
@ToString
static class Book {
String name;
String description;
}
省略getter/setter
......
}
Вы можете внедрить его в класс и использовать как обычный компонент Spring.
5.3. PropertySource
(используется редко)
@PropertySource
Прочитать указанный файл свойств
@Component
@PropertySource("classpath:website.properties")
class WebSite {
@Value("${url}")
private String url;
省略getter/setter
......
}
Для получения дополнительной информации ознакомьтесь с моей статьей: "Как SpringBoot элегантно читает файлы конфигурации за 10 минут?".
6. Проверка параметров
Важность проверки данных очевидна.Даже если внешний интерфейс проверяет данные, нам все равно необходимо снова проверить данные, переданные на серверную часть, чтобы пользователи не обходили браузер и напрямую не передавали некоторые инструменты HTTP. данные непосредственно в серверную часть.
JSR (запросы спецификаций Java)Это набор стандартов для проверки параметров JavaBean. Он определяет множество общих аннотаций проверки. Мы можем напрямую добавить эти аннотации к свойствам нашего JavaBean, чтобы можно было выполнять проверку, когда требуется проверка, что очень удобно.
При проверке мы фактически используемHibernate ValidatorРамка. Hibernate Validator — это исходная среда проверки данных команды Hibernate, Hibernate Validator 4.x — эталонная реализация Bean Validation 1.0 (JSR 303), а Hibernate Validator 5.x — эталонная реализация Bean Validation 1.1 (JSR 349). Hibernate Validator 6.x — это эталонная реализация Bean Validation 2.0 (JSR 380).
Пакет hibernate-validator уже существует в зависимости spring-boot-starter-web проекта SpringBoot, и нет необходимости ссылаться на связанные зависимости. Как показано на следующем рисунке (создан плагином idea — Maven Helper):
Проекты, отличные от SpringBoot, должны сами вводить соответствующие пакеты зависимостей. Я не буду здесь много объяснять. Подробности вы можете найти в этой моей статье: "Как выполнить проверку параметров в Spring/Spring Boot? Все, что вам нужно знать, здесь!".
👉 Обратите внимание, что:Для всех аннотаций рекомендуется использовать аннотации JSR, а именноjavax.validation.constraints
, вместоorg.hibernate.validator.constraints
6.1 Некоторые распространенные аннотации проверки поля
-
@NotEmpty
Аннотированная строка не может быть нулевой или пустой -
@NotBlank
Аннотированная строка не является нулевой и должна содержать символ, отличный от пробела. -
@Null
Аннотированный элемент должен быть нулевым -
@NotNull
Аннотированный элемент не должен быть пустым -
@AssertTrue
Аннотированный элемент должен быть истинным -
@AssertFalse
Аннотированный элемент должен быть ложным -
@Pattern(regex=,flag=)
Аннотированный элемент должен соответствовать указанному регулярному выражению. -
@Email
Аннотированный элемент должен быть в формате электронной почты. -
@Min(value)
Аннотированный элемент должен быть числом, значение которого должно быть больше или равно указанному минимальному значению. -
@Max(value)
Аннотированный элемент должен быть числом, значение которого должно быть меньше или равно указанному максимальному значению. -
@DecimalMin(value)
Аннотированный элемент должен быть числом, значение которого должно быть больше или равно указанному минимальному значению. -
@DecimalMax(value)
Аннотированный элемент должен быть числом, значение которого должно быть меньше или равно указанному максимальному значению. -
@Size(max=, min=)
Размер аннотируемого элемента должен быть в пределах указанного диапазона. -
@Digits (integer, fraction)
Аннотируемый элемент должен быть числом, и его значение должно быть в допустимом диапазоне. -
@Past
Аннотированный элемент должен быть датой в прошлом -
@Future
Аннотированный элемент должен быть датой в будущем - ......
6.2. Проверка RequestBody
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
@NotNull(message = "classId 不能为空")
private String classId;
@Size(max = 33)
@NotNull(message = "name 不能为空")
private String name;
@Pattern(regexp = "((^Man$|^Woman$|^UGM$))", message = "sex 值不在可选范围")
@NotNull(message = "sex 不能为空")
private String sex;
@Email(message = "email 格式不正确")
@NotNull(message = "email 不能为空")
private String email;
}
Мы добавили к параметрам, которые необходимо проверить@Valid
аннотация, если проверка не пройдена, она выдастMethodArgumentNotValidException
.
@RestController
@RequestMapping("/api")
public class PersonController {
@PostMapping("/person")
public ResponseEntity<Person> getPerson(@RequestBody @Valid Person person) {
return ResponseEntity.ok().body(person);
}
}
6.3 Проверка параметров запроса (переменные пути и параметры запроса)
Не забудьте добавить в классValidated
Аннотированный, этот параметр может указать Spring на проверку параметров метода.
@RestController
@RequestMapping("/api")
@Validated
public class PersonController {
@GetMapping("/person/{id}")
public ResponseEntity<Integer> getPersonByID(@Valid @PathVariable("id") @Max(value = 5,message = "超过 id 的范围了") Integer id) {
return ResponseEntity.ok().body(id);
}
}
Дополнительные сведения о том, как выполнить проверку параметров в проектах Spring, см. в разделе "Как выполнить проверку параметров в Spring/Spring Boot? Все, что вам нужно знать, здесь!"Эта статья.
7. Глобальная обработка исключений уровня контроллера
Представьте глобальную обработку исключений уровня контроллера, которые необходимы для нашего проекта Spring.
Связанные примечания:
-
@ControllerAdvice
: Аннотация определяет глобальный класс обработки исключений. -
@ExceptionHandler
: аннотация объявляет метод обработки исключений
Как это использовать? Возьмем пример проверки параметров, который мы видели в разделе 5. Выдает, если параметр метода неверенMethodArgumentNotValidException
, давайте обработаем это исключение.
@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {
/**
* 请求参数异常处理
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<?> handleMethodArgumentNotValidException(MethodArgumentNotValidException ex, HttpServletRequest request) {
......
}
}
Дополнительные сведения об обработке исключений Spring Boot см. в двух моих статьях:
- Несколько общих положений SpringBoot для обработки исключений
- Простая инкапсуляция элегантной глобальной обработки исключений Spring Boot с использованием перечислений!
8. Связанные с JPA
8.1 Создание таблиц
@Entity
Объявите класс, соответствующий объекту базы данных.
@Table
настройка указывает
@Entity
@Table(name = "role")
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String description;
省略getter/setter......
}
8.2. Создание первичных ключей
@Id
: объявить поле первичным ключом.
использовать@Id
После объявления нам также необходимо определить стратегию генерации первичного ключа. мы можем использовать@GeneratedValue
Указывает стратегию генерации первичного ключа.
1. Пройти@GeneratedValue
Непосредственно используйте четыре встроенные стратегии генерации первичного ключа, предоставляемые JPA, чтобы указать стратегию генерации первичного ключа.
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
JPA определяет 4 общие стратегии генерации первичных ключей с использованием перечислений, а именно:
Брат гида: использование перечисления вместо констант
public enum GenerationType {
/**
* 使用一个特定的数据库表格来保存主键
* 持久化引擎通过关系数据库的一张特定的表格来生成主键,
*/
TABLE,
/**
*在某些数据库中,不支持主键自增长,比如Oracle、PostgreSQL其提供了一种叫做"序列(sequence)"的机制生成主键
*/
SEQUENCE,
/**
* 主键自增长
*/
IDENTITY,
/**
*把主键生成策略交给持久化引擎(persistence engine),
*持久化引擎会根据数据库在以上三种主键生成 策略中选择其中一种
*/
AUTO
}
@GeneratedValue
Стратегия по умолчанию, используемая аннотацией,GenerationType.AUTO
public @interface GeneratedValue {
GenerationType strategy() default AUTO;
String generator() default "";
}
Если вы обычно используете базу данных MySQL, используйтеGenerationType.IDENTITY
Стратегия более общая (для распределенных систем нужно рассматривать использование распределенных ID отдельно).
2. Пройти@GenericGenerator
Объявите политику первичного ключа, затем@GeneratedValue
использовать эту стратегию
@Id
@GeneratedValue(generator = "IdentityIdGenerator")
@GenericGenerator(name = "IdentityIdGenerator", strategy = "identity")
private Long id;
Эквивалентно:
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
Стратегии генерации первичного ключа, предоставляемые jpa, следующие:
public class DefaultIdentifierGeneratorFactory
implements MutableIdentifierGeneratorFactory, Serializable, ServiceRegistryAwareService {
@SuppressWarnings("deprecation")
public DefaultIdentifierGeneratorFactory() {
register( "uuid2", UUIDGenerator.class );
register( "guid", GUIDGenerator.class ); // can be done with UUIDGenerator + strategy
register( "uuid", UUIDHexGenerator.class ); // "deprecated" for new use
register( "uuid.hex", UUIDHexGenerator.class ); // uuid.hex is deprecated
register( "assigned", Assigned.class );
register( "identity", IdentityGenerator.class );
register( "select", SelectGenerator.class );
register( "sequence", SequenceStyleGenerator.class );
register( "seqhilo", SequenceHiLoGenerator.class );
register( "increment", IncrementGenerator.class );
register( "foreign", ForeignGenerator.class );
register( "sequence-identity", SequenceIdentityGenerator.class );
register( "enhanced-sequence", SequenceStyleGenerator.class );
register( "enhanced-table", TableGenerator.class );
}
public void register(String strategy, Class generatorClass) {
LOG.debugf( "Registering IdentifierGenerator strategy [%s] -> [%s]", strategy, generatorClass.getName() );
final Class previous = generatorStrategyToClassNameMap.put( strategy, generatorClass );
if ( previous != null ) {
LOG.debugf( " - overriding [%s]", previous.getName() );
}
}
}
8.3 Настройка типов полей
@Column
Объявить поля.
Пример:
Задайте для имени поля базы данных, соответствующего атрибуту userName, значение user_name, длину 32 и не пустое.
@Column(name = "user_name", nullable = false, length=32)
private String userName;
Установка типа поля и добавление значения по умолчанию довольно распространены.
Column(columnDefinition = "tinyint(1) default 1")
private Boolean enabled;
8.4 Укажите, чтобы определенные поля не сохранялись
@Transient
: Объявить поля, которые не нужно сопоставлять с базой данных, и не нужно сохранять в базе данных при сохранении.
Если мы хотимsecrect
Это поле не сохраняется, вы можете использовать@Transient
объявление ключевого слова.
Entity(name="USER")
public class User {
......
@Transient
private String secrect; // not persistent because of @Transient
}
Кроме@Transient
Объявление ключевого слова, вы также можете использовать следующие методы:
static String secrect; // not persistent because of static
final String secrect = “Satish”; // not persistent because of final
transient String secrect; // not persistent because of transient
Существует множество способов использования аннотаций.
8.5 Объявление больших полей
@Lob
: Объявите поле как большое поле.
@Lob
private String content;
Более подробное заявление:
@Lob
//指定 Lob 类型数据的获取策略, FetchType.EAGER 表示非延迟 加载,而 FetchType. LAZY 表示延迟加载 ;
@Basic(fetch = FetchType.EAGER)
//columnDefinition 属性指定数据表对应的 Lob 字段类型
@Column(name = "content", columnDefinition = "LONGTEXT NOT NULL")
private String content;
8.6 Создание полей типов перечисления
Можно использовать поля типов перечисления, но поля перечисления используют@Enumerated
Модификация аннотации.
public enum Gender {
MALE("男性"),
FEMALE("女性");
private String value;
Gender(String str){
value=str;
}
}
@Entity
@Table(name = "role")
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String description;
@Enumerated(EnumType.STRING)
private Gender gender;
省略getter/setter......
}
Соответствующее хранилище в базе данных — MAIL/FEMAIL.
8.7. Добавить функцию аудита
только что унаследовалAbstractAuditBase
По умолчанию класс добавит следующие четыре поля.
@Data
@AllArgsConstructor
@NoArgsConstructor
@MappedSuperclass
@EntityListeners(value = AuditingEntityListener.class)
public abstract class AbstractAuditBase {
@CreatedDate
@Column(updatable = false)
@JsonIgnore
private Instant createdAt;
@LastModifiedDate
@JsonIgnore
private Instant updatedAt;
@CreatedBy
@Column(updatable = false)
@JsonIgnore
private String createdBy;
@LastModifiedBy
@JsonIgnore
private String updatedBy;
}
Соответствующий класс конфигурации для нашей соответствующей функции аудита может быть следующим (проект Spring Security):
@Configuration
@EnableJpaAuditing
public class AuditSecurityConfiguration {
@Bean
AuditorAware<String> auditorAware() {
return () -> Optional.ofNullable(SecurityContextHolder.getContext())
.map(SecurityContext::getAuthentication)
.filter(Authentication::isAuthenticated)
.map(Authentication::getName);
}
}
Краткое введение в некоторые из аннотаций, разработанных выше:
-
@CreatedDate
: Указывает, что поле является полем времени создания, и когда объект вставляется, значение будет установлено -
@CreatedBy
: указывает, что поле является создателем, при вставке объекта значение будет установлено@LastModifiedDate
,@LastModifiedBy
То же самое справедливо.
@EnableJpaAuditing
: включить функцию аудита JPA.
8.8. Удаление/изменение данных
@Modifying
Аннотация напоминает JPA, что эта операция - это операция модификации, обращая внимание на сотрудничество@Transactional
Используется аннотация.
@Repository
public interface UserRepository extends JpaRepository<User, Integer> {
@Modifying
@Transactional(rollbackFor = Exception.class)
void deleteByUserName(String userName);
}
8.9 Ассоциация
-
@OneToOne
объявить отношение один к одному -
@OneToMany
Объявить отношение «один ко многим» -
@ManyToOne
Объявите отношение «многие к одному» -
MangToMang
Объявить связь многие ко многим
Дополнительные статьи о Spring Boot JPA см. в этой моей статье:Узнайте, как правильно использовать JPA с Spring Boot.
9. Транзакции@Transactional
Используйте на методе, чтобы начать транзакцию@Transactional
Просто аннотируйте!
@Transactional(rollbackFor = Exception.class)
public void save() {
......
}
Мы знаем, что Exception делится на исключение во время выполнения RuntimeException и исключение во время выполнения. существует@Transactional
Если не настроено в аннотацииrollbackFor
свойства, то вещи будут встречаться толькоRuntimeException
будет откатываться, когдаrollbackFor=Exception.class
, что позволяет выполнять откат при возникновении исключений, не относящихся к среде выполнения.
@Transactional
Аннотации обычно используются, когда они могут быть использованы в类
или方法
начальство.
-
Действовать в классе: когда
@Transactional 注解放在类上时,表示所有该类的
Все общедоступные методы настроены с использованием одной и той же информации об атрибутах транзакции. -
Действуйте по методу: когда класс настроен
@Transactional
, метод также настроен@Transactional
, транзакция метода переопределяет информацию о конфигурации транзакции класса.
Для получения дополнительной информации о весенних транзакциях см.:
- Вероятно, самое красивое управление транзакциями Spring
- Назовите 6 сценариев сбоя аннотации @Transactional за один раз
10. обработка данных json
10.1 Фильтрация json-данных
@JsonIgnoreProperties
Используется в классах для фильтрации определенных полей, которые не возвращаются или не анализируются.
//生成json时将userRoles属性过滤
@JsonIgnoreProperties({"userRoles"})
public class User {
private String userName;
private String fullName;
private String password;
@JsonIgnore
private List<UserRole> userRoles = new ArrayList<>();
}
@JsonIgnore
Обычно используется для свойств класса, роли и выше@JsonIgnoreProperties
Такой же.
public class User {
private String userName;
private String fullName;
private String password;
//生成json时将userRoles属性过滤
@JsonIgnore
private List<UserRole> userRoles = new ArrayList<>();
}
10.2 Форматирование json-данных
@JsonFormat
Обычно используется для форматирования данных json. :
Например:
@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", timezone="GMT")
private Date date;
10.3 Сведение объектов
@Getter
@Setter
@ToString
public class Account {
@JsonUnwrapped
private Location location;
@JsonUnwrapped
private PersonInfo personInfo;
@Getter
@Setter
@ToString
public static class Location {
private String provinceName;
private String countyName;
}
@Getter
@Setter
@ToString
public static class PersonInfo {
private String userName;
private String fullName;
}
}
Перед сглаживанием:
{
"location": {
"provinceName":"湖北",
"countyName":"武汉"
},
"personInfo": {
"userName": "coder1234",
"fullName": "shaungkou"
}
}
использовать@JsonUnwrapped
После выравнивания объекта:
@Getter
@Setter
@ToString
public class Account {
@JsonUnwrapped
private Location location;
@JsonUnwrapped
private PersonInfo personInfo;
......
}
{
"provinceName":"湖北",
"countyName":"武汉",
"userName": "coder1234",
"fullName": "shaungkou"
}
11. Связанные с тестами
@ActiveProfiles
Обычно применяется к тестовому классу, используемому для объявления эффективного файла конфигурации Spring.
@SpringBootTest(webEnvironment = RANDOM_PORT)
@ActiveProfiles("test")
@Slf4j
public abstract class TestBase {
......
}
@Test
Объявите метод как метод тестирования
@Transactional
Данные объявленного тестового метода будут откатываться, чтобы не загрязнять тестовые данные.
@WithMockUser
Предоставляется Spring Security для олицетворения реального пользователя и предоставления разрешений.
@Test
@Transactional
@WithMockUser(username = "user-id-18163138155", authorities = "ROLE_TEACHER")
void should_import_student_success() throws Exception {
......
}
Подведем итоги здесь на данный момент! Хотя написание заняло много времени, некоторые часто используемые аннотации все же могут быть упущены, поэтому я также синхронизировал статью с Github, адрес Github:GitHub.com/snail Climb/…Совершенство приветствуется!
Эта статья была включена в мой проект с открытым исходным кодом 75K Star Java JavaGuide:GitHub.com/snail Climb/….
В этой статье используетсяmdniceнабор текста