Краткое изложение общих аннотаций Spring/Spring объемом почти 8000 слов! договариваться!

Spring Boot Spring

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.

Связанные примечания:

  1. @ControllerAdvice: Аннотация определяет глобальный класс обработки исключений.
  2. @ExceptionHandler: аннотация объявляет метод обработки исключений

Как это использовать? Возьмем пример проверки параметров, который мы видели в разделе 5. Выдает, если параметр метода неверенMethodArgumentNotValidException, давайте обработаем это исключение.

@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {

    /**
     * 请求参数异常处理
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<?> handleMethodArgumentNotValidException(MethodArgumentNotValidException ex, HttpServletRequest request) {
       ......
    }
}

Дополнительные сведения об обработке исключений Spring Boot см. в двух моих статьях:

  1. Несколько общих положений SpringBoot для обработки исключений
  2. Простая инкапсуляция элегантной глобальной обработки исключений 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);
    }
}

Краткое введение в некоторые из аннотаций, разработанных выше:

  1. @CreatedDate: Указывает, что поле является полем времени создания, и когда объект вставляется, значение будет установлено

  2. @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, транзакция метода переопределяет информацию о конфигурации транзакции класса.

Для получения дополнительной информации о весенних транзакциях см.:

  1. Вероятно, самое красивое управление транзакциями Spring
  2. Назовите 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набор текста