Найти в Дзене
chto-to na itshnom

Всё о Java для начинающих чайников ч.3

DispatcherServlet — это центральный компонент в архитектуре Spring MVC. Он является реализацией паттерна Front Controller и служит точкой входа для обработки HTTP-запросов в веб-приложении Spring. Основные функции DispatcherServlet: Жизненный цикл обработки запроса: Маппинг в Spring — это процесс связывания HTTP-запросов (или других запросов) с методами в контроллерах, а также привязка параметров запросов к параметрам методов. Spring предоставляет удобные механизмы маппинга через аннотации, такие как @RequestMapping, @GetMapping, @PostMapping, @PutMapping, @DeleteMapping, и другие. Маппинг в Spring играет важную роль в том, как веб-приложение обрабатывает различные типы запросов от клиента и как эти запросы направляются к правильным методам контроллеров. 1. Основные аннотации маппинга 1.1. @RequestMapping Аннотация @RequestMapping является базовой аннотацией для маппинга HTTP-запросов. Она может быть использована для маппинга как классов, так и методов, на определенные URL-шаблоны, HTT
Оглавление
  1. Класс DispatcherServlet, его функции.

DispatcherServlet — это центральный компонент в архитектуре Spring MVC. Он является реализацией паттерна Front Controller и служит точкой входа для обработки HTTP-запросов в веб-приложении Spring.

Основные функции DispatcherServlet:

  1. Роутинг запросов:
  2. Перенаправляет входящие HTTP-запросы к соответствующим обработчикам (контроллерам).
  3. Основан на настройках маршрутов, заданных с помощью аннотаций (@RequestMapping, @GetMapping и т.д.) или конфигурации XML/Java.
  4. Координирует работу различных компонентов, таких как контроллеры, обработчики представлений, резолверы (решатели) и обработчики исключений.
  5. Обработка данных запроса и ответа:
  6. Извлекает данные из запроса (параметры, тело, заголовки) и передает их в контроллеры.
  7. Возвращает ответ клиенту в формате, который задается обработчиком (JSON, XML, HTML и т.д.).
  8. Использует модель данных, сформированную контроллером, и передает ее представлению (например, JSP, Thymeleaf, JSON).
  9. Позволяет обрабатывать исключения централизованно с помощью механизмов, таких как аннотация @ExceptionHandler или глобальные обработчики (ControllerAdvice).
  10. Работает с цепочкой фильтров и интерцепторов (например, для логирования, авторизации, мониторинга).

Жизненный цикл обработки запроса:

  1. Клиент отправляет запрос на сервер.
  2. DispatcherServlet принимает его.
  3. Запрос передается в цепочку обработчиков через HandlerMapping, которая сопоставляет путь запроса с контроллером.
  4. DispatcherServlet вызывает соответствующий метод контроллера.
  5. Контроллер формирует данные модели и возвращает их вместе с именем представления.
  6. С помощью ViewResolver определяется, какое представление будет использоваться (например, JSP, Thymeleaf).
  7. Представление рендерится и отправляется клиенту.
  1. Маппинг в Spring.

Маппинг в Spring — это процесс связывания HTTP-запросов (или других запросов) с методами в контроллерах, а также привязка параметров запросов к параметрам методов. Spring предоставляет удобные механизмы маппинга через аннотации, такие как @RequestMapping, @GetMapping, @PostMapping, @PutMapping, @DeleteMapping, и другие.

Маппинг в Spring играет важную роль в том, как веб-приложение обрабатывает различные типы запросов от клиента и как эти запросы направляются к правильным методам контроллеров.

1. Основные аннотации маппинга

1.1. @RequestMapping

Аннотация @RequestMapping является базовой аннотацией для маппинга HTTP-запросов. Она может быть использована для маппинга как классов, так и методов, на определенные URL-шаблоны, HTTP-методы, параметры запросов и другие атрибуты.

Пример использования @RequestMapping:

@Controller

public class MyController {

@RequestMapping("/home")

public String homePage() {

return "home"; // возвращаем представление "home"

}

}

1.2. @GetMapping, @PostMapping, @PutMapping, @DeleteMapping

Для более специализированного маппинга HTTP-методов Spring 4.3 и выше предоставляет аннотации для конкретных методов HTTP:

  • @GetMapping — для обработки HTTP GET запросов.
  • @PostMapping — для обработки HTTP POST запросов.
  • @PutMapping — для обработки HTTP PUT запросов.
  • @DeleteMapping — для обработки HTTP DELETE запросов.

Пример использования этих аннотаций:

@Controller

public class UserController {

@GetMapping("/users/{id}")

public String getUser(@PathVariable("id") Long id, Model model) {

User user = userService.getUserById(id);

model.addAttribute("user", user);

return "userDetails"; // отображение страницы с деталями пользователя

}

@PostMapping("/users")

public String createUser(@ModelAttribute User user) {

userService.createUser(user);

return "redirect:/users"; // редирект на список пользователей

}

@PutMapping("/users/{id}")

public String updateUser(@PathVariable("id") Long id, @ModelAttribute User user) {

userService.updateUser(id, user);

return "redirect:/users/{id}";

}

@DeleteMapping("/users/{id}")

public String deleteUser(@PathVariable("id") Long id) {

userService.deleteUser(id);

return "redirect:/users";

}

}

1.3. Атрибуты аннотации @RequestMapping

@RequestMapping может использоваться с несколькими атрибутами, чтобы более точно настроить маппинг запросов. Вот основные атрибуты:

  • value — указывает URL-шаблон, с которым будет связано действие.
  • method — указывает HTTP-метод (GET, POST, PUT, DELETE).
  • params — маппинг будет выполняться только при наличии определенных параметров запроса.
  • headers — маппинг выполняется только при наличии определенных HTTP-заголовков.
  • produces — указывает тип контента, который контроллер может вернуть (например, application/json).
  • consumes — указывает тип контента, который метод контроллера может обработать (например, application/json).

Пример с аттрибутами:

@RequestMapping(value = "/users", method = RequestMethod.POST, consumes = "application/json", produces = "application/json")

@ResponseBody

public User createUser(@RequestBody User user) {

return userService.createUser(user);

}

В этом примере запросы с методом POST, типом контента application/json и ожидаемым типом ответа application/json будут обработаны этим методом.

2. Маппинг с использованием параметров

Маппинг параметров — это механизм связывания данных из URL, формы или тела запроса с параметрами метода контроллера. Spring поддерживает несколько способов маппинга параметров:

2.1. Маппинг параметров URL с использованием @PathVariable

@PathVariable используется для извлечения значений из URI.

Пример:

@GetMapping("/users/{id}")

public String getUser(@PathVariable("id") Long id) {

return "User ID: " + id;

}

2.2. Маппинг параметров запроса с использованием @RequestParam

@RequestParam используется для извлечения параметров запроса из строки запроса URL.

Пример:

@GetMapping("/search")

public String search(@RequestParam("query") String query) {

return "Searching for: " + query;

}

Для работы с параметрами, которые могут быть необязательными, можно использовать атрибут defaultValue:

@GetMapping("/search")

public String search(@RequestParam(value = "query", defaultValue = "default") String query) {

return "Searching for: " + query;

}

2.3. Маппинг данных из тела запроса с использованием @RequestBody

@RequestBody используется для извлечения данных из тела запроса, например, в формате JSON или XML, и преобразования их в Java-объект.

Пример:

@PostMapping("/users")

public String createUser(@RequestBody User user) {

userService.createUser(user);

return "User created";

}

2.4. Маппинг данных формы с использованием @ModelAttribute

@ModelAttribute используется для связывания данных из формы (или другого источника) с объектом Java.

Пример:

@PostMapping("/users")

public String createUser(@ModelAttribute User user) {

userService.createUser(user);

return "redirect:/users";

}

3. Маппинг и возвращаемые значения

Методы контроллеров в Spring могут возвращать несколько типов значений, таких как строки, объекты, представления, JSON, и т.д. Spring автоматически обрабатывает эти типы в зависимости от контекста:

  • Строка — возвращаемое значение интерпретируется как имя представления.
  • Объекты — если метод возвращает объект, и тип ответа настроен как JSON или XML, Spring будет автоматически преобразовывать объект в соответствующий формат.
  • @ResponseBody — аннотация, которая указывает, что метод контроллера должен возвращать тело ответа (например, JSON или XML).

Пример:

@GetMapping("/users/{id}")

@ResponseBody

public User getUser(@PathVariable Long id) {

return userService.getUser(id); // Spring автоматически преобразует объект User в JSON

}

  1. Интерфейсы HttpServletRequest и HttpServletResponse.

Основная информация

HttpServletRequest

HttpServletResponse

Получает информацию о запросе клиента.

Формирует ответ клиенту.

Позволяет работать с параметрами, URI, заголовками, cookies.

Позволяет задавать статус, заголовки, cookies и тело ответа.

Используется для обработки данных, отправленных клиентом.

Используется для отправки данных клиенту.

Интерфейс HttpServletRequest используется для получения информации о клиентском запросе. Он наследует интерфейс ServletRequest и предоставляет методы для обработки данных запроса.
Основные методы:

1) Получение параметров и атрибутов:

  • String getParameter(String name) — возвращает значение параметра.
  • String[] getParameterValues(String name) — возвращает все значения параметра.

2) Информация о запросе:

  • String getMethod() — возвращает метод HTTP-запроса (GET, POST и т. д.).
  • String getQueryString() — возвращает строку параметров запроса.
  • String getRemoteAddr() — возвращает IP-адрес и имя клиента.

3) Работа с cookies:

  • Cookie[] getCookies() — возвращает массив cookies, переданных с запросом.

Пример использования: String param = request.getParameter("username");

Интерфейс HttpServletResponse используется для формирования HTTP-ответа, отправляемого клиенту. Он наследует интерфейс ServletResponse.

Основные методы:

1) Формирование тела ответа:

  • ServletOutputStream getOutputStream() — поток для записи бинарных данных.
  • PrintWriter getWriter() — поток для записи текстовых данных.

2) Управление заголовками и статусом:

  • void setHeader(String name, String value) — добавляет или изменяет заголовок.
  • void setDateHeader(String name, long date) — добавляет дату в заголовок.
  • void sendError(int sc, String msg) — отправляет HTTP-ошибку.

3) Работа с cookies:

  • void addCookie(Cookie c) — добавляет cookie в ответ.

4) Перенаправление:

  • void sendRedirect(String location) — перенаправляет запрос на указанный URL.
  1. Архитектурный стиль CRUD, его соответствие REST и HTTP.
Архитектурный стиль CRUD (Create, Read, Update, Delete) является фундаментальным подходом к управлению данными, который часто ассоциируется с операциями над сущностями в базе данных.

REST (Representational State Transfer) — это архитектурный стиль для проектирования распределенных систем, таких как веб-сервисы. CRUD является важной составляющей REST, поскольку операции CRUD используются для взаимодействия с ресурсами.

Связь между CRUD и REST выражается в том, что операции CRUD находят отражение в действиях REST через HTTP-методы:


REST строится поверх HTTP, но не ограничивается им. HTTP предоставляет стандартные методы (например, GET, POST, PUT, DELETE), которые REST использует для реализации взаимодействия с ресурсами. Ключевые принципы REST, реализуемые через HTTP:
Архитектурный стиль CRUD (Create, Read, Update, Delete) является фундаментальным подходом к управлению данными, который часто ассоциируется с операциями над сущностями в базе данных. REST (Representational State Transfer) — это архитектурный стиль для проектирования распределенных систем, таких как веб-сервисы. CRUD является важной составляющей REST, поскольку операции CRUD используются для взаимодействия с ресурсами. Связь между CRUD и REST выражается в том, что операции CRUD находят отражение в действиях REST через HTTP-методы: REST строится поверх HTTP, но не ограничивается им. HTTP предоставляет стандартные методы (например, GET, POST, PUT, DELETE), которые REST использует для реализации взаимодействия с ресурсами. Ключевые принципы REST, реализуемые через HTTP:
  • Идентификация ресурсов через URI.
  • Статусы ответов HTTP, которые указывают на результат операции.
  • Без состояния (Stateless). Каждый запрос содержит всю необходимую информацию для выполнения операции, сервер не хранит информацию о предыдущих запросах.
  • Управляемость через гипермедиа (HATEOAS). Сервер может возвращать гиперссылки, чтобы клиент знал, какие действия можно выполнить с ресурсом.
  1. Шаблон Data Access Object (DAO).

Шаблон проектирования DAO (Data Access Object) — это способ организации кода для управления взаимодействием между вашей программой и базой данных.

Основная идея заключается в том, что создаётся интерфейс (или абстрактный класс), который описывает все возможные операции с данными. Это может быть операции добавления, удаления, обновления и извлечения данных. Затем для каждого конкретного источника данных создается своя реализация этого интерфейса, в которой эти операции выполняются конкретным для этого источника данных способом.

-3

Класс User — это просто контейнер для пользовательских данных, поэтому он не реализует никаких других функций

-4

Интерфейс Dao определяет абстрактный API, который выполняет операции CRUD над объектами типа T. Благодаря высокому уровню абстракции, который обеспечивает интерфейс, легко создать конкретную, детализированную реализацию, работающую с объектами User.

Класс UserDao

Давайте определим пользовательскую реализацию интерфейса Dao:

(фрагмент)
(фрагмент)

Класс UserDao реализует все функции, необходимые для получения, обновления и удаления объектов User.

Хотя классы User и UserDao сосуществуют независимо друг от друга в рамках одного приложения, нам всё равно нужно понять, как можно использовать последний для сокрытия уровня сохранения данных от логики приложения:

-6

В этом случае метод main просто использует экземпляр UserDao для выполнения операций CRUD с несколькими объектами User.

Наиболее важным аспектом этого процесса является то, что UserDao скрывает от приложения все низкоуровневые детали сохранения, обновления и удаления объектов.

  1. Основные понятия Объектно-реляционного отображения (ORM - Object-Relational Mapping).

Объектно-реляционное отображение (ORM) — это техника программирования, которая позволяет взаимодействовать с базами данных через объекты и классы языка программирования вместо использования SQL-запросов. ORM упрощает работу с базами данных, минимизирует ручное написание SQL-кода и позволяет разработчикам сосредоточиться на логике приложения.

Модель данных (Entity, Сущность)

В ORM сущности представляют собой объекты, которые соответствуют таблицам в базе данных.Каждая таблица базы данных мапится на класс, а строки таблицы — на экземпляры этого класса.

Отношения между сущностями

ORM поддерживает отображение отношений между таблицами . Например, One-to-One (Один-к-одному), One-to-Many (Один-ко-многим), Many-to-Many (Многие-ко-многим).

Сессии

С помощью сессий выполняются все CRUD-операции с объектами-сущностями. Объект типа Session получают из экземпляра типа SessionFactory, который должен присутствовать в приложении в виде singleton.

Управление состоянием объектов

Объект-сущность может находиться в одном из 3-х состояний (статусов):

  • transient object. Объекты в данном статусе — это заполненные экземпляры классов-сущностей. Могут быть сохранены в БД. Не присоединены к сессии. Поле Id не должно быть заполнено, иначе объект имеет статус detached ;
  • persistent object. Объект в данном статусе — так называемая хранимая сущность, которая присоединена к конкретной сессии. Только в этом статусе объект взаимодействует с базой данных. При работе с объектом данного типа в рамках транзакции все изменения объекта записываются в базу;
  • detached object. Объект в данном статусе — это объект, отсоединённый от сессии, может существовать или не существовать в БД.
  1. Спецификация Java Persistence API (JPA).

Java Persistence API (JPA) — это спецификация Java API, которая заполняет пробел между реляционными базами данных и объектно-ориентированным программированием, обрабатывая объекты Java в таблицах баз данных и обратно. Этот процесс известен как объектно-реляционное сопоставление (ORM) . JPA может определить способ отображения классов Java (сущностей) в таблицах баз данных и то, как они могут взаимодействовать с базовыми данными через EntityManager, постоянство контекста и передачу данных.

JPA состоит из трех основных пунктов:

  • API - интерфейсы в пакете javax.persistance. Набор интерфейсов, которые позволяют организовать взаимодействие с ORM провайдером.
  • JPQL - объектный язык запросов. Очень похож на SQL, но запросы выполняются к объектам.
  • Metadata - аннотации над объектами. Набор аннотаций, которыми мы описываем метаданные отображения. Тогда уже JPA знает какой объект в какую таблицу нужно сохранить. Метаданные можно описывать двумя способами: XML-файлом или через аннотации.

Ключевые термины в JPA

  • Сущность (Entity) : Лёгкий объект, представляющий символ в таблице базы данных. Например, класс Userможет соответствовать таблице users.
  • EntityManager : Основной интерфейс для работы с сущностями. Он отвечает за управление их жизненным циклом, синхронизацию данных с базой и выполнение запросов.
  • Сохранение контекста (Persistence Context) : Это набор отслеживаемых объектов EntityManager. Контекст синхронизирует состояние объектов с базой данных, выявляя их согласованность. Например, изменения в объектах автоматически применяются к базе в конце передачи.

Сама по себе JPA является спецификацией и не содержит особенностей реализации. Одной из самых популярных реализаций является Hibernate, которая предоставляет дополнительные возможности, не описанные в JPA, но при этом полностью соответствующие критериям.

Используя JPA, разработчики могут создавать, читать, обновлять и удалять объекты в базе данных, не прибегая к написанию сложных SQL-запросов, что способствует повышению производительности и упрощению разработки Java-приложений.

  1. Архитектура ORM Java Persistence API (JPA).

Java Persistence API (JPA) — это спецификация для управления реляционными данными в Java-приложениях с использованием объектно-ориентированного подхода. JPA предоставляет стандартный способ работы с базами данных, позволяя разработчикам использовать объекты Java для взаимодействия с реляционными данными. Основная цель JPA — упростить работу с базами данных, скрывая детали SQL и предоставляя более высокоуровневый API для работы с данными.

Архитектура JPA

Архитектура JPA состоит из нескольких ключевых компонентов, которые взаимодействуют друг с другом для управления персистентностью объектов. Основные компоненты архитектуры JPA включают:

-Entity:

Это класс, который представляет собой таблицу в базе данных. Каждый экземпляр класса Entity соответствует строке в таблице.

Классы Entity аннотируются с помощью аннотаций JPA, таких как @Entity, @Table, @Id, и других, чтобы указать, как они должны быть сопоставлены с таблицами базы данных.

-EntityManager:

Это основной интерфейс для взаимодействия с контекстом персистентности. Он управляет жизненным циклом объектов Entity, выполняет операции CRUD (создание, чтение, обновление, удаление) и управляет транзакциями.

EntityManager предоставляет методы для поиска, сохранения и удаления объектов.

-EntityManagerFactory:

Это интерфейс, который создает экземпляры EntityManager. Он управляет настройками подключения к базе данных и конфигурацией JPA.

Обычно EntityManagerFactory создается один раз за время жизни приложения, а EntityManager создается по мере необходимости.

-Persistence Context:

Это среда, в которой управляются объекты Entity. Она отслеживает изменения объектов и синхронизирует их с базой данных.

Все изменения, сделанные в объектах Entity, будут автоматически отслеживаться и синхронизироваться с базой данных при завершении транзакции.

-Query Language (JPQL):

JPA предоставляет собственный язык запросов, называемый Java Persistence Query Language (JPQL), который позволяет выполнять запросы к объектам Entity, а не к таблицам базы данных.

JPQL основан на SQL, но работает с объектами и их свойствами.

-Transaction Management:

JPA поддерживает управление транзакциями, что позволяет выполнять несколько операций над базой данных как единое целое. Если одна из операций не удалась, все изменения могут быть отменены.

JPA может работать с различными механизмами управления транзакциями, такими как JTA (Java Transaction API) или JDBC.

  1. Основные аннотации Java Persistence API (JPA).

Основные аннотации Java Persistence API (JPA)

Java Persistence API (JPA) — это спецификация для работы с объектно-реляционным отображением (ORM) в Java, позволяющая взаимодействовать с базами данных через объектную модель. JPA предоставляет удобный способ управления данными в СУБД без необходимости написания сложного SQL-кода.

Аннотации JPA используются для определения структуры и поведения сущностей в базе данных.

Основные аннотации JPA позволяют:

  • Определять сущности и маппинг на таблицы (@Entity, @Table).
  • Работать с первичными ключами (@Id, @GeneratedValue).
  • Определять свойства полей (@Column, @Enumerated, @Temporal).
  • Определять связи между сущностями (@OneToOne, @OneToMany, @ManyToOne, @ManyToMany).
  • Работать с вложенными объектами (@Embeddable, @Embedded).

1. Аннотация @Entity

Обозначает класс как JPA-сущность (таблицу в базе данных). Класс, помеченный этой аннотацией, должен иметь конструктор без аргументов, а его поля должны быть связаны с колонками таблицы.

2. Аннотация @Table

Позволяет задать имя таблицы и схему в базе данных для сущности.

Если аннотация @Table не указана, то по умолчанию имя таблицы соответствует имени класса.

3. Аннотация @Id

Определяет первичный ключ (Primary Key) сущности. Поле, помеченное @Id, должно быть уникальным и непустым.

4. Аннотация @GeneratedValue

Используется вместе с @Id для автоматической генерации значений первичного ключа.

Стратегии генерации ключей:

  • GenerationType.AUTO – стратегия по умолчанию, выбор зависит от используемой СУБД.
  • GenerationType.IDENTITY – использует автоинкремент (например, AUTO_INCREMENT в MySQL).
  • GenerationType.SEQUENCE – использует последовательность (работает с БД, поддерживающими SEQUENCE).
  • GenerationType.TABLE – использует таблицу для хранения идентификаторов.

Пример:

import jakarta.persistence.GeneratedValue;

import jakarta.persistence.GenerationType;

@Entity

public class User {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

private Long id;

}

5. Аннотация @Column

Определяет параметры колонки в таблице.

Атрибуты:

  • name — имя колонки.
  • nullable — допускается ли NULL (по умолчанию true).
  • length — максимальная длина строки (по умолчанию 255).
  • unique — должно ли значение быть уникальным.

6. Аннотация @Transient

Позволяет исключить поле из маппинга в базу данных. Поле не будет сохранено в таблице.

Пример:

import jakarta.persistence.Transient;

@Entity

public class User {

private String username;

@Transient

private String tempData; // Не будет сохраняться в БД

}

7. Аннотация @Enumerated

Используется для хранения enum-типов в базе данных.

Режимы:

  • EnumType.STRING – сохраняет строковое представление.
  • EnumType.ORDINAL – сохраняет числовой индекс (по умолчанию).

Пример:

import jakarta.persistence.Enumerated;

import jakarta.persistence.EnumType;

@Entity

public class User {

public enum Status { ACTIVE, INACTIVE }

@Enumerated(EnumType.STRING)

private Status status;

}

8. Аннотация @Temporal (для дат)

Используется для работы с полями типа Date и Calendar, задавая формат хранения в базе данных.

Режимы:

  • TemporalType.DATE – только дата (год, месяц, день).
  • TemporalType.TIME – только время (часы, минуты, секунды).
  • TemporalType.TIMESTAMP – дата и время.

Пример:

import jakarta.persistence.Temporal;

import jakarta.persistence.TemporalType;

import java.util.Date;

@Entity

public class Event {

@Temporal(TemporalType.TIMESTAMP)

private Date eventDate;

}

9. Аннотации связей между сущностями

@OneToOne (Связь "один-к-одному") и тд, остальные выше написаны

10. Аннотация @JoinColumn

Используется для задания имени колонки, хранящей внешний ключ в связях между сущностями.

Пример:

import jakarta.persistence.JoinColumn;

import jakarta.persistence.OneToOne;

@Entity

public class User {

@OneToOne

@JoinColumn(name = "address_id")

private Address address;

}

11. Аннотация @MappedSuperclass

Позволяет создать класс с полями, которые будут унаследованы другими сущностями, но сам класс не становится сущностью.

Пример:

import jakarta.persistence.MappedSuperclass;

@MappedSuperclass

public class BaseEntity {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

private Long id;

}

12. Аннотация @Embeddable и @Embedded

Используется для встраивания объектов в сущности (композиция).

  1. Библиотека Hibernate, основные аннотации.

Библиотека Hibernate и её основные аннотации

Hibernate — это библиотека Java для работы с базами данных, реализующая концепцию ORM (Object-Relational Mapping). Она позволяет преобразовывать объекты Java в таблицы базы данных и наоборот, скрывая сложность работы с SQL.

Основные аннотации Hibernate

1. Аннотации для классов

  1. @Entity
  • Помечает класс как сущность, связанную с таблицей в базе данных.
  • Класс должен иметь уникальный идентификатор (@Id).

@Entity

public class User {

@Id

private Long id;

private String name;

}

  1. @Table
  • Указывает таблицу, с которой будет связана сущность.
  • Необязательна, если имя таблицы совпадает с именем класса.

@Entity

@Table(name = "users")

public class User {

@Id

private Long id;

}

2. Аннотации для полей

  1. @Id
  • Определяет первичный ключ сущности.

@Id

private Long id;

  1. @GeneratedValue
  • Автоматическая генерация значения первичного ключа.
  • Стратегии:
  • GenerationType.AUTO: стратегия выбирается Hibernate автоматически.
  • GenerationType.IDENTITY: автогенерация на уровне базы данных.
  • GenerationType.SEQUENCE: использует последовательности (sequence) базы данных.
  • GenerationType.TABLE: хранение ключей в отдельной таблице.

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

private Long id;

  1. @Column
  • Настройка столбца в таблице.
  • Атрибуты:
  • name: имя столбца.
  • nullable: допускает ли значение NULL.
  • length: длина строки.

@Column(name = "user_name", nullable = false, length = 50)

private String name;

  1. @Transient
  • Указывает, что поле не должно сохраняться в базу данных.
    @Transient

private String tempData;

  1. @Lob
  • Используется для хранения больших объектов, например, текста (CLOB) или файлов (BLOB).

@Lob

private String description;

  1. @Enumerated
  • Для хранения перечислений (enum).
  • Типы:
  • EnumType.STRING: сохраняет строковые значения.
  • EnumType.ORDINAL: сохраняет порядковые номера.

@Enumerated(EnumType.STRING)

private Status status;

3. Аннотации для связей между сущностями

  1. @OneToOne
  • Связь "один к одному".
  • Используется атрибут mappedBy для двусторонней связи.

@OneToOne

@JoinColumn(name = "profile_id")

private Profile profile;

  1. @OneToMany
  • Связь "один ко многим".
  • Используется с коллекциями.

@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)

private List<Post> posts;

  1. @ManyToOne
  • Связь "многие к одному".

@ManyToOne

@JoinColumn(name = "user_id")

private User user;

  1. @ManyToMany
  • Связь "многие ко многим".
  • Создаётся промежуточная таблица.

@JoinTable(

name = "user_roles",

joinColumns = @JoinColumn(name = "user_id"),

inverseJoinColumns = @JoinColumn(name = "role_id")

)

private Set<Role> roles;

4. Аннотации для жизненного цикла сущности

  1. @PrePersist
  • Метод вызывается перед сохранением новой сущности.

java
КопироватьРедактировать
@PrePersist

public void onPrePersist() {

createdAt = LocalDateTime.now();

}

  1. @PostPersist
  • Метод вызывается после сохранения новой сущности.
  1. @PreUpdate
  • Вызывается перед обновлением сущности.
  1. @PostUpdate
  • Вызывается после обновления сущности.
  1. @PreRemove
  • Вызывается перед удалением сущности.
  1. @PostRemove
  • Вызывается после удаления сущности.

Пример сущности с аннотациями

import jakarta.persistence.*;

import java.time.LocalDateTime;

import java.util.List;

@Entity

@Table(name = "users")

public class User {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

private Long id;

@Column(name = "username", nullable = false, length = 50)

private String name;

@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)

private List<Post> posts;

@PrePersist

public void onPrePersist() {

createdAt = LocalDateTime.now();

}

private LocalDateTime createdAt;

// Геттеры и сеттеры

}

Основные преимущества Hibernate

Автоматизация работы с базой данных: Не нужно писать сложные SQL-запросы вручную.

Поддержка кэширования: Ускорение доступа к данным.

Портативность: Работает с разными базами данных без изменений в коде.

Легкость работы с ассоциациями: Упрощает работу с отношениями между сущностями.

Поддержка транзакций: Простое управление транзакциями с помощью аннотаций.

  1. Объявление сущности и таблицы в Hibernate.

В Hibernate для работы с базой данных сущности представляются в виде Java-классов, а таблицы — в виде соответствующих аннотаций. Эти аннотации позволяют сопоставлять поля класса с колонками таблицы, задавать ограничения и связи между сущностями.

Основные аннотации для объявления сущности и таблицы

  1. @Entity - обозначает класс как сущность Hibernate, которая будет связана с таблицей в базе данных (Hibernate ожидает, что класс с этой аннотацией будет иметь аннотацию @Id).
  2. @Table - опционально используется для указания имени таблицы, если оно отличается от имени класса.
  3. @Id - Обозначает первичный ключ.
  4. @GeneratedValue - указывает стратегию генерации значения для первичного ключа
  • GenerationType.IDENTITY: Автоинкремент.
  • GenerationType.SEQUENCE: Использует последовательности (например, в PostgreSQL).
  • GenerationType.TABLE: Хранит значения в специальной таблице.
  • GenerationType.AUTO: Автоматический выбор стратегии на основе базы данных.
  1. @Column - Позволяет задать параметры для столбцов таблицы, такие как имя, длина, уникальность и т.д.
  • name: Имя столбца в таблице.
  • nullable: Разрешает или запрещает NULL (по умолчанию true).
  • unique: Указывает, что значения в столбце должны быть уникальными.
  • length: Максимальная длина строки (для строковых полей).

Hibernate поддерживает различные типы связей между сущностями:

  • @OneToOne (Одна запись в таблице A связана с одной записью в таблице B):

@Entity

@Table(name = "users")

public class User {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

private Long id;

@Column(name = "name")

private String name;

@OneToOne(cascade = CascadeType.ALL)

@JoinColumn(name = "profile_id", referencedColumnName = "id") // Связь с Profile

private Profile profile;

// Геттеры и сеттеры

}

@Entity

@Table(name = "profiles")

class Profile {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

private Long id;

@Column(name = "bio")

private String bio;

// Геттеры и сеттеры

}

  • @OneToOne: Указывает связь “один к одному”.
  • @JoinColumn: Указывает имя внешнего ключа в таблице users, который ссылается на id таблицы profiles.
  • @OneToMany (Одна запись в таблице A связана с несколькими записями в таблице B)

@Entity

@Table(name = "categories")

public class Category {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

private Long id;

@Column(name = "name")

private String name;

@OneToMany(mappedBy = "category", cascade = CascadeType.ALL, orphanRemoval = true)

private List<Product> products;

// Геттеры и сеттеры

}

@Entity

@Table(name = "products")

class Product {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

private Long id;

@Column(name = "name")

private String name;

@ManyToOne

@JoinColumn(name = "category_id", nullable = false)

private Category category;

// Геттеры и сеттеры

}

  • @OneToMany: Указывает, что одна категория связана с несколькими продуктами.
  • mappedBy: Указывает поле в классе Product, которое отвечает за связь.
  • @ManyToOne: Указывает обратную связь из продукта к категории.
  • @ManyToOne (Несколько записей в таблице A могут ссылаться на одну запись в таблице B)

@Entity

@Table(name = "employees")

public class Employee {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

private Long id;

@Column(name = "name")

private String name;

@ManyToOne

@JoinColumn(name = "department_id", nullable = false)

private Department department;

// Геттеры и сеттеры

}

@Entity

@Table(name = "departments")

class Department {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

private Long id;

@Column(name = "name")

private String name;

@OneToMany(mappedBy = "department", cascade = CascadeType.ALL)

private List<Employee> employees;

// Геттеры и сеттеры

}

  • @ManyToOne: Указывает связь из сотрудника в департамент.
  • @OneToMany: Указывает обратную связь из департамента к сотрудникам.
  • @ManyToMany (Несколько записей из таблицы A могут быть связаны с несколькими записями из таблицы B).

@Entity

@Table(name = "students")

public class Student {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

private Long id;

@Column(name = "name")

private String name;

@ManyToMany

@JoinTable(

name = "student_course",

joinColumns = @JoinColumn(name = "student_id"),

inverseJoinColumns = @JoinColumn(name = "course_id")

)

private Set<Course> courses;

// Геттеры и сеттеры

}

@Entity

@Table(name = "courses")

class Course {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

private Long id;

@Column(name = "title")

private String title;

@ManyToMany(mappedBy = "courses")

private Set<Student> students;

// Геттеры и сеттеры

}

  • @ManyToMany: Указывает связь “многие ко многим”.
  • @JoinTable: Определяет промежуточную таблицу student_course, которая связывает студентов и курсы.
  • joinColumns: Указывает внешний ключ для таблицы students.
  • inverseJoinColumns: Указывает внешний ключ для таблицы courses.
  1. Интерфейс Session в Hibernate.

Интерфейс Session в Hibernate является ключевым компонентом ORM-фреймворка Hibernate. Он предоставляет API для взаимодействия с базой данных. Session управляет жизненным циклом объектов, выполняет CRUD-операции, и позволяет выполнять запросы к базе данных.

  • Session отвечает за создание транзакции и взаимодействие с базой данных.
  • Использует соединение JDBC под капотом для выполнения запросов.
  • Обеспечивает поддержку операций CRUD:
  • save(), persist(), update(), merge(), delete().
  • Сопоставляет объекты Java с таблицами в базе данных согласно настройкам в ORM-модели.
  • Использует первичный кэш (First Level Cache), что означает, что все изменения объектов отслеживаются в пределах одного сеанса.
  • Кэш на уровне сеанса позволяет минимизировать количество обращений к базе данных.
  • Поддерживает выполнение HQL (Hibernate Query Language), SQL, а также Criteria API.
  • Session позволяет создавать объекты Transaction и явно управлять ими.
  • Transaction transaction = session.beginTransaction();
  • Объект Session не является потокобезопасным и должен использоваться в пределах одного потока.
  • После завершения работы с Session, её нужно закрыть через session.close().
  • Автоматически сохраняет изменения объектов в базе данных при закрытии сессии или выполнении транзакции.

Сессия управляет состояниями объектов:

  • Transient: объект не связан с базой данных.
  • Persistent: объект управляется Hibernate и синхронизируется с базой данных.
  • Detached: объект больше не управляется Hibernate.

Session — это интерфейс, представляющий собой обертку над соединением с базой данных. Он обеспечивает прозрачную работу с объектами, их синхронизацию с базой данных и эффективное управление кэшированием.

  1. Ассоциация сущностей в Hibernate.

Hibernate — это инструмент ORM (Object-Relational Mapping), который облегчает работу Java-разработчиков с базами данных.

Связи между сущностями (Associations): Hibernate поддерживает различные типы ассоциаций (один-к-одному, один-ко-многим, многие-ко-многим) - это упрощает управления связанными объектами.

Для определения связей между сущностями Hibernate использует аннотации @OneToOne, @OneToMany, @ManyToOne, @ManyToMany.

@OneToOne

Каждый гражданин может иметь только один паспорт. И у каждого паспорта может быть только один владелец. Такая связь двух объектов в Hibernate определяется как @OneToOne (один-к-одному).

-7

просто для справки:

Параметр optional говорит JPA, является ли значение в этом поле обязательным или нет. Связанное поле в User объявлено с помощью аннотации @JoinColumn, параметр name которой обозначает поле в БД для создания связи. Для того, чтобы объявить сторону, которая не несет ответственности за отношения, используется атрибут mappedBy в сущности Passport. Он ссылается на имя свойства связи (passport) на стороне владельца.

Со стороны владельца к аннотации @OneToOne добавляется параметр cascade. В однонаправленных отношениях одна из сторон (и только одна) должна быть владельцем и нести ответственность за обновление связанных полей. В этом случае владельцем выступает сущность User. Каскадирование позволяет указать JPA, что необходимо «сделать со связанным объектом при выполнении операции с владельцем». То есть, когда удаляется Person из базы, JPA самостоятельно определит наличие у него паспорта и удалит сначала паспорт, потом гражданина.

@OneToMany и @ManyToOne

Аннотации @OneToMany (один-ко-многим) и @ManyToOne (многие-к-одному) рассмотрим на примере гражданина и его места проживания.

-8

Поскольку по одному адресу может проживать несколько жильцов, то поле tenants представлено коллекцией, которая имеет аннотацию @OneToMany. Параметр mappedBy также указывает на поле в классе владельца. Параметр fetch=FetchType.EAGER говорит о том, что при загрузке владеемого объекта необходимо сразу загрузить и коллекцию владельцев.

Для чтения связанных объектов из БД используются следующие стратегии загрузок (fetch) : EAGER и LAZY. В первом случае объекты коллекции сразу загружаются в память, во втором случае — только при обращении к ним.

@ManyToMany

Примером ассоциации @ManyToMany (многие-ко-многим) могут быть отношения студентов и ВУЗов. В одном институте может быть много студентов, студент может учиться в нескольких ВУЗах.

Для определения связи @ManyToMany в примере потребуется три таблицы : таблица студентов students, таблица ВУЗов university и таблица связей student_university, в которой будут связаны студенты и ВУЗы. Кроме этого в таблице student_university определены внешние ключи (FOREIGN KEY), предупреждающие появление непрошенных записей при отсутствии родительских.

-9

Список институтов в сущности Student аннотирован с помощью @ManyToMany. Далее следует аннотация @JoinTable, которая определяет таблицу и поля для связи. Параметр name указывает название таблицы (student_university). Параметр joinColumns указывает на поле, которое используется для прямой связи (идентификатор student_id). Параметр inverseJoinColumns указывает на поле, которое используется для обратной связи (идентификатор university_id). Для указания столбцов связи из таблицы используется аннотация @JoinColumn.

Также существуют двунаправленные и однонаправленные ассоциации:

  • Двунаправленная ассоциация в Hibernate — это связь между двумя объектами, где каждый объект имеет ссылку на другой объект. Это позволяет перемещаться от одной сущности к другой, связанной с ней, и наоборот.
  • Однонаправленная ассоциация возникает, когда только одна из двух сущностей содержит ссылку на другую.
  1. Spring Boot: определение, характеристики, преимущества.

Spring Boot — это инструмент на базе фреймворка Spring, предназначенный для упрощения разработки, настройки и развертывания приложений. Основная цель Spring Boot — минимизировать сложность конфигурации и ускорить процесс создания приложений за счет автоматизации и предустановленных настроек.

Характеристики Spring Boot

1) Автоконфигурация (Auto-Configuration):
Автоматически настраивает компоненты приложения на основе зависимостей в проекте. Например, если в зависимости добавлена база данных, Spring Boot автоматически подключает JDBC и настраивает соединение.
2)
Встроенные серверы (Embedded Servers):
Включает встроенные серверы, такие как Tomcat, Jetty, Undertow, что позволяет запускать приложение как автономный Java-приложение без необходимости установки внешнего сервера.
3)
Spring Initializer:
Предоставляет веб-инструмент для быстрого создания проекта с предустановленными зависимостями.
4)
Упрощенная настройка:
Использование файла конфигурации application.properties или application.yml вместо обширных XML-конфигураций.
5)
Поддержка микросервисов:
Spring Boot идеально подходит для создания микросервисной архитектуры благодаря своей легковесности и совместимости с инструментами, такими как Spring Cloud.
6)
Модульное подключение зависимостей:
Spring Boot Starter-пакеты предоставляют готовые зависимости для разных функций, например:
spring-boot-starter-web — для веб-приложений.
spring-boot-starter-data-jpa — для работы с базами данных.

Преимущества:

1) Быстрое развертывание:
Благодаря автоконфигурации и встроенным серверам, приложение можно запустить с минимальными настройками.

2) Минимум кода и конфигурации:
Нет необходимости писать много шаблонного кода или конфигураций XML. Всё настраивается с помощью аннотаций и файлов свойств.

3) Легкость тестирования:
Поддерживает встроенные инструменты для модульного и интеграционного тестирования.

4) Совместимость с экосистемой Spring:
Полностью интегрируется с библиотеками Spring, такими как Spring Security, Spring Data, Spring Cloud и др.

5) Гибкость:
Позволяет переопределять настройки автоконфигурации, если это необходимо.

  1. Spring Initializr, особенности и преимущества применения.

Spring Initializr — это веб-сервис и инструмент для быстрого создания проекта на основе фреймворка Spring. Он позволяет легко генерировать готовый шаблон проекта с необходимыми зависимостями, минимальной конфигурацией и структурой.

Сервис доступен через веб-интерфейс
https://start.spring.io, а также интегрирован в популярные IDE, такие как IntelliJ IDEA, Eclipse, и Visual Studio Code.

Особенности Spring Initializr

  • Поддержка различных зависимостей (например, Spring Web, Spring Data JPA, Spring Security)
  • Выбор языка и версий: Поддержка Java, Kotlin и Groovy. Возможность выбора версии Spring Boot
  • Различные системы сборки (Maven и Gradle)
  • Интеграция с IDE
  • Поддержка микросервисной архитектуры

Преимущества применения Spring Initializr

  • Экономия времени: Вместо ручной настройки проекта, зависимости и структуры, Spring Initializr автоматически генерирует рабочий проект, что сокращает время начала разработки.
  • Минимизация ошибок: Генератор автоматически добавляет необходимые зависимости и конфигурации, что снижает вероятность ошибок.
  • Гибкость и кастомизация: Пользователь может настроить проект под свои потребности, выбирая только нужные библиотеки и версии.
  • Обеспечение совместимости: Initializr подбирает правильные версии зависимостей, которые совместимы с выбранной версией Spring Boot, что экономит время на проверку совместимости.
  • Удобство для новичков: Простота выбора и минимальная необходимость знаний о внутренних зависимостях Spring делают Initializr отличным стартовым инструментом для начинающих.
  1. Структура фреймворка JUnit.

JUnit — фреймворк для автоматического юнит-тестирования приложений. Он содержит специальные функции и правила, которые позволяют легко писать и запускать тесты, то есть проверять, что каждый блок кода, или модуль, ответственный за определенную функцию программы, работает как надо. Такой вид тестирования называют модульным, или юнит-тестированием.

Аннотации в JUnit — это специальные метки, которые Java-разработчик размещает перед методами в тестовом классе. Они позволяют настраивать процесс тестирования, указывая фреймворку, как именно их следует обрабатывать. Например, можно явно указать, какие из методов являются тестовыми случаями, какие из них выполнять перед тестами и после и так далее.

Вот несколько базовых аннотаций.

  • @Test. Эту аннотацию ставим перед методами, которые относятся к тестовым случаям. JUnit поймёт, что их следует выполнять в качестве теста, а по завершении проверить результат.
  • @Before. Используется для методов, которые должны быть выполнены перед каждым тестовым случаем. Например, если у нас есть несколько тестов, которые требуют одних и тех же начальных условий, мы можем обозначить метод с аннотацией @Before, задав необходимые условия тестирования один раз.
  • @After. Эту аннотацию используем перед методом, который должен быть выполнен после тестового случая.
  • @BeforeClass, @AfterClass. Методы с аннотацией @BeforeClass выполняются перед запуском первого теста в классе, а методы с аннотацией @AfterClass — после завершения всех тестов в классе.
  • @Ignore. Используется перед методом, чтобы отключить его выполнение в тесте. Это может быть полезно, если мы не уверены в работоспособности отдельных тестов и не хотим их использовать, но должны оставить в коде.

public class MyTest {

@BeforeEach

public void setUp() {

// Метод, выполняющийся перед каждым тестовым случаем

}

@AfterEach

public void tearDown() {

// Метод, выполняющийся после каждого тестового случая

}

Assertions - методы для проверки условий (результатов теста):

  • assertEquals(expected, actual) — проверяет равенство.
  • assertNotEquals(expected, actual) — проверяет, что значения не равны.
  • assertTrue(condition) — проверяет, что условие истинно.
  • assertFalse(condition) — проверяет, что условие ложно.
  • assertThrows(Exception.class, executable) — проверяет, что выбрасывается исключение.
  • assertNull(object) — проверяет, что объект равен null.
  • assertNotNull(object) — проверяет, что объект не равен null
-10
  1. JUnit аннотации @Test, @DisplayName.

Аннотация @Test

Указывает, что метод является тестовым. Не объявляет никаких атрибутов.

Используются утверждения (assertions) для проверки правильности выполнения кода (например, assertEquals, assertTrue).

Такие методы наследуются, если не переопределены.

-11

Аннотация @DisplayName

Объявляет пользовательское имя для отображения класса или метода тестирования(могут содержать пробелы, специальные символы и даже эмодзи). Такие аннотации не наследуются.
Объявляет пользовательское имя для отображения класса или метода тестирования(могут содержать пробелы, специальные символы и даже эмодзи). Такие аннотации не наследуются.
  1. JUnit аннотации @BeforeEach, @AfterEach.

Аннотации @BeforeEach и @AfterEach использование в библиотеке JUnit для подготовки и выполнения тестов. Они позволяют определять методы, которые будут автоматически включаться до и после каждого тестового метода в тестовом классе.

Особенности :

  1. Замена аннотации @Before и @After из JUnit 4.
  2. Метод НЕ ДОЛЖЕН быть статическим, иначе возникнет ошибка при выполнении.
  3. Методы @BeforeEach и @AfterEach из родительских классов наследуются дочерними классами, если они не переопределены.

Аннотация @BeforeEach используется для обозначения того, что аннотированный метод должен выполняться перед каждым методом @Test, @RepeatedTest, @ParameterizedTest, или @TestFactory в текущем классе.

По умолчанию тестовые методы будут выполняться в том же потоке, что и аннотированный @BeforeEach метод.

Использование @BeforeEach

Добавьте аннотацию @BeforeEach к методу, как указано ниже:

@BeforeEach

public void initEach(){

//test setup code

}

@Test

void succeedingTest() {

//test code and assertions

}

Аннотация @AfterEach используется для обозначения того, что аннотированный метод должен выполняться после каждого метода, помеченного @Test, @RepeatedTest, @ParameterizedTest, или @TestFactory в текущем классе.

По умолчанию тестовые методы будут выполняться в том же потоке, что и аннотированный @AfterEach метод.

Использование @AfterEach

Добавьте аннотацию @AfterEach к методу, как указано ниже:

@AfterEach

public void cleanUpEach(){

//Test cleanup code

}

@Test

void succeedingTest() {

//test code and assertions

}

Особенности наследования

  • Методы @BeforeEach и @AfterEach из родительских классов проводятся для испытаний в дочерних классах, если они не переопределены.
  • Последовательность выполнения:

@BeforeEach из родительского класса → @BeforeEach из дочернего класса → тестовый метод → @AfterEach из дочернего класса → @AfterEach из родительского класса.

Практическое применение

  • @BeforeEach обычно используется для подготовки данных, организации объектов или настройки независимых зависимостей.
  • @AfterEach подает заявку на освобождение ресурсов, таких как закрытие соединений с базой данных, удаление временных файлов и т. д. д.
  1. Тестовые классы и методы JUnit.

JUnit — это популярный фреймворк для модульного тестирования в Java. Он позволяет разработчикам писать и выполнять тесты для проверки корректности работы их кода. JUnit предоставляет аннотации и методы, которые упрощают процесс написания тестов и управления ими.

Основные аннотации JUnit

  1. @Test: Эта аннотация используется для обозначения метода как тестового. JUnit будет выполнять этот метод как тест.
  2. @Before: Этот метод будет выполняться перед каждым тестом. Он часто используется для настройки тестовой среды.
  3. @After: Этот метод будет выполняться после каждого теста. Он может использоваться для очистки ресурсов или сброса состояния.
  4. @BeforeClass: Этот метод будет выполняться один раз перед выполнением всех тестов в классе. Он должен быть статическим.
  5. @AfterClass: Этот метод будет выполняться один раз после выполнения всех тестов в классе. Он также должен быть статическим.
  6. @Ignore: Эта аннотация используется для временного игнорирования теста. Тест, помеченный этой аннотацией, не будет выполняться.
  7. @ParameterizedTest: Эта аннотация используется для параметризованных тестов, позволяя запускать один и тот же тест с различными наборами данных.
  8. Утверждения JUnit. Класс Assert.

Ассерты (asserts) — это специальные проверки, которые можно вставить в разные места кода. Их задача определять, что что-то пошло не так.

Основной целью тестирования является проверка того, что код работает корректно, а утверждения (assertions) позволяют сравнивать ожидаемый и фактический результат.

В JUnit для проверки условий используется класс org.junit.jupiter.api.Assertions (в JUnit 5) или org.junit.Assert (в JUnit 4).

-13
-14

Функция

JUnit 4

JUnit 5

Аннотация для теста

@Test (из org.junit)

@Test (из org.junit.jupiter.api)

Утверждения

org.junit.Assert.*

org.junit.jupiter.api.Assertions.*

Группировка

Отсутствует

assertAll()

Проверка исключений

Аннотация @Test(expected=Exception)

Метод assertThrows()

  1. Тестирование исключений JUnit.

JUnit предоставляет встроенные возможности для тестирования сценариев, где методы выбрасывают исключения. В зависимости от используемой версии JUnit, подходы могут отличаться.

1. Использование @Test(expected = Exception.class) (JUnit 4)

При помощи аннотации @Test можно указать ожидаемый тип исключения. Если метод выбрасывает указанное исключение, тест считается успешным.

2. Использование блока try-catch

Этот способ позволяет проверить как факт выбрасывания исключения, так и его содержимое (например, сообщение).

3. Использование assertThrows (JUnit 5)

JUnit 5 предоставляет метод Assertions.assertThrows, который делает тестирование исключений удобным и читаемым.

4. Проверка исключений с использованием библиотеки AssertJ

Если используется библиотека AssertJ, можно ещё более лаконично проверять исключения.

  1. Генератор документирования Javadoc. Виды комментариев.

можете обратиться к вопросу 6

Комментарии в Java бывают трех видов:

  • Однострочные комментарии начинаются с //. После этих двух символов может следовать любой текст, вся строка не будет анализироваться и исполняться.
  • Многострочные комментарии начинаются с /* и заканчиваются на */. Принято каждую строку начинать с символа *, хотя технически это и необязательно:
  • Документирующие комментарии начинаются с /** и заканчиваются на */. Уже для них обязательно каждую строку начинать с символа *.
    Документирующие комментарии — это подвид многострочных. При этом несут дополнительную функцию — их можно собрать при помощи специальной утилиты
    javadoc и выдать в качестве документации к вашему коду.

Javadoc — это инструмент для автоматической генерации документации в Java. Он позволяет извлекать комментарии из исходного кода и формировать HTML-документацию.

Дескрипторы Javadoc:

-15

Форма документирования кода:

Документирование класса, метода или переменной начинается с комбинации символов /** , после которого следует тело комментариев; заканчивается комбинацией символов */.

В тело комментариев можно вставлять различные дескрипторы. Каждый дескриптор, начинающийся с символа '@' должен стоять первым в строке. Несколько дескрипторов одного и того же типа необходимо группировать вместе. Встроенные дескрипторы (начинаются с фигурной скобки) можно помещать внутри любого описания.

Пример:

/**

* Класс продукции со свойствами <b>maker</b> и <b>price</b>.

* @autor NN

* @version 2.1

*/

class Product

{

/** Поле производитель */

private String maker;

/** Поле цена */

public double price;

/**

* Конструктор - создание нового объекта

* @see Product#Product(String, double)

*/

Product()

{

setMaker("");

price=0;

}

/**

* Конструктор - создание нового объекта с определенными значениями

* @param maker - производитель

* @param price - цена

* @see Product#Product()

*/

Product(String maker,double price){

this.setMaker(maker);

this.price=price;

}

/**

* Функция получения значения поля {@link Product#maker}

* @return возвращает название производителя

*/

public String getMaker() {

return maker;

}

/**

* Процедура определения производителя {@link Product#maker}

* @param maker - производитель

*/

public void setMaker(String maker) {

this.maker = maker;

}

}

  1. Дескрипторы Javadoc.

Дескрипторы Javadoc — это специальные аннотации или теги, которые используются в комментариях Javadoc для автоматической генерации документации по коду на Java. Эти дескрипторы помогают описывать классы, методы, поля, параметры и другие элементы программы, чтобы разработчики могли легко понимать назначение и использование кода.

Дескрипторы Javadoc начинаются с символа @ и располагаются в комментариях вида /** ... */. Ниже приведен список часто используемых дескрипторов Javadoc:

Дескриптор

Описание

Применим к

@author

Автор

Класс, интерфейс

@version

Версия. Не более одного дескриптора на класс.

Класс, интерфейс

@since

Указывает, с какой версии доступно.

Класс, интерфейс, поле, метод

@see

Ссылка на другое место в документации.

Класс, интерфейс, поле, метод

@param

Входной параметр метода.

Метод

@return

Описание возвращаемого значения.

Метод

@deprecated

Описание устаревших блоков кода.

Класс, интерфейс, поле, метод

{@link reference}

Ссылка.

Класс, интерфейс, поле, метод

{@value}

Описание значения переменной.

Статичное поле

пример класса

-16

Задачи

  1. Условие: «Реализовать программу для выполнения следующих математических операций с целочисленным, байтовым и вещественным типами данных: сложение, вычитание, умножение, деление, деление по модулю (остаток), модуль числа, возведение в степень. Все данные вводятся с клавиатуры (класс Scanner, System.in, nextint).» По данному условию необходимо реализовать программу с интерактивным консольным меню, (т.е. вывод списка действий по цифрам. При этом при нажатии на цифру у нас должно выполняться определенное действие). При этом в программе данные пункты должны называться следующим образом:
  2. Вывести все таблицы из MySQL.
  3. Создать таблицу в MySQL.
  4. Сложение чисел, результат сохранить в MySQL с последующим выводом в консоль.
  5. Вычитание чисел, результат сохранить в MySQL с последующим выводом в консоль.
  6. Умножение чисел, результат сохранить в MySQL с последующим выводом в консоль.
  7. Деление чисел, результат сохранить в MySQL с последующим выводом в консоль.
  8. Деление чисел по модулю (остаток), результат сохранить в MySQL с последующим выводом в консоль.
  9. Возведение числа в модуль, результат сохранить в MySQL с последующим выводом в консоль.
  10. Возведение числа в степень, результат сохранить в MySQL с последующим выводом в консоль.
  11. Сохранить все данные (вышеполученные результаты) из MySQL в Excel и вывести на экран.

https://github.com/AliceAnd0/java_exam/tree/main/NumbersInDB

  1. Напишите программу, в которой из строки "I have 3 cats, 4 dogs, and 1 turtle" отбираются цифры. Из этих цифр формируется массив.

https://github.com/polinatut/exem_java/blob/main/ex_2/ExtractNumbers.java

  1. Разработайте программу, которая выводит в консоль все цифры, входящие в натуральное число n. К примеру, если дано число 2359, то в консоль выводятся отдельно числа 2, 3, 5, 9.

https://github.com/mirrrler/task3

  1. Написать калькулятор для строковых выражений вида "<число> <операция> <число>", где <число> - положительное целое число меньшее 10, записанное словами, например, "четыре", <арифметическая операция> - одна из операций "плюс", "минус", "умножить". Результат выполнения операции вернуть в виде текстового представления числа. Пример: "пять плюс четыре" --> "девять".

https://github.com/dariadegt/java_exam/blob/main/Task_4.java

  1. Напишите программную реализацию бинарного дерева поиска.

https://github.com/gavalone/for_work/blob/main/src/Task_5.java

  1. Разработайте программу, которая выводит буквы английского алфавита, используя цикл while в MySQL/PostgreSQL.

https://github.com/bshkrrr/java_exam/tree/main/src/main/java/com/example/demo

  1. Напишите программу, которая будет выводить в консоль введенное слово 6 раз и сохранять в MySQL/PostgreSQL.

https://github.com/flamingo99900/JavaEkz/tree/task_7

  1. Разработать программу для вывода на экран кубов первых десяти положительных чисел.

https://github.com/gavalone/for_work/blob/main/src/Task_8.java

  1. Напишите программу, которая по дате определяет день недели, на который эта дата приходится.

https://github.com/itsvakonst/javaexam/blob/main/Task9.java

  1. Написать класс, который при введении даты в формате ДД.ММ.ГГ (к примеру, 22.10.20) выводит номер недели. Даты начиная с 2020 по 2022 годы. К примеру, первая неделя в 2020 году: 1-5 января, вторая неделя – 6-12 января. Значит при вводе 08.01.20 вывод должен быть: Неделя 2.

https://github.com/Delia0001/java_exam/blob/main/Task_10.java

  1. Разработайте программу, реализующую рекурсивное вычисление факториала.

https://github.com/NafaNaniz/exam/blob/main/RecursiveFactorial.java

  1. Разработать класс-оболочку для числового типа double. Реализовать статические методы сложения, деления, возведения в степень.

https://github.com/AliceAnd0/java_exam/blob/main/DoubleWrapper.java

  1. Разработать программу, которая заполняет двумерный массив случайными положительными числами в диапазоне от 1 до 100 до тех пор, пока сумма граничных элементов не станет равной 666. Пользователь вначале вводит размер матрицы.

https://github.com/polinatut/exem_java/blob/main/ex_13/MatrixSum.java

  1. Разработать программу, в которой требуется создать класс, описывающий геометрическую фигуру – треугольник. Методами класса должны быть – вычисление площади, периметра. Создать класс-наследник, определяющий прямоугольный треугольник.

https://github.com/mirrrler/task14

  1. Разработать программу, в которой требуется создать абстрактный класс. В этом абстрактном классе определить абстрактные методы вычисления функции в определенной точке. Создать классы-наследники абстрактного класса, описывающими уравнения прямой и параболы. Программа должна выводить в консоль значение функции при вводе определенного значения.

https://github.com/dariadegt/java_exam/blob/main/Task_15.java

  1. Создать интерфейс Progress c методами вычисления любого элемента прогрессии и суммы прогрессии. Разработать классы арифметической и геометрической прогрессии, которые имплементируют интерфейс Progress.

https://github.com/max33128/tasks

  1. Разработать интерфейс InArray, в котором предусмотреть метод сложения двух массивов. Создать класс ArraySum, в котором имплементируется метод сложения массивов. Создать класс OrArray, в котором метод сложения массивов имплементируется как логическая операция ИЛИ между элементами массива.

https://github.com/bshkrrr/java_exam/tree/main/src/main/java/com/example/demo

  1. Создать класс Binary для работы с двоичными числами фиксированной длины. Число должно быть массивом тип char, каждый элемент которого принимает значение 0 или 1. Младший бит имеет младший индекс. Отрицательные числа представляются в дополнительном коде. Дополнительный код получается инверсией всех битов с прибавлением 1 к младшему биту. Например, +1 – это в двоичном коде будет выглядеть, как 0000 0001. А -1 в двоичном коде будет выглядеть, как 1111 1110 + 0000 0001 = 1111 1111. Создать методы конвертации десятичного числа в массив и обратно.

https://github.com/flamingo99900/JavaEkz/tree/task_18

  1. Создать класс Matrix для работы с двумерными матрицами. Создать методы для генерации нулевой матрицы, а также для генерации матрицы со случайными величинами – применить Math.random(). Реализовать метод сложения матриц.

https://github.com/gavalone/for_work/blob/main/src/Matrix.java

  1. Реализовать класс MyMath для работы с числами. Реализовать статический метод класса MyMath.round(), который округляет дробь до целого числа. Также статический метод abs(), который находит модуль числа. Статический метод MyMath.pow() для нахождения степени числа. Библиотеку Math не использовать.

https://github.com/itsvakonst/javaexam/blob/main/Task20.java

  1. Разработать программу для игры «Угадайка». Программа загадывает случайное число от 1 до 10, требуется его отгадать с трех попыток. После каждой попытки, если результат неверен, игроку выводится сообщение, меньше или больше названное игроком число, чем загаданное. Сет заканчивается или если игрок угадывает число, или если исчерпывает три попытки, не угадав. Игра должна быть выполнена в бесконечном цикле, и продолжается до тех пор, пока на предложение «Сыграем еще раз?» игрок не напишет «Нет».

https://github.com/Delia0001/java_exam/blob/main/Task_21.java

  1. Разработайте программу-генератор рабочего календаря. Слесарь механосборочного цеха работает сутки через трое. Если смена попадает на воскресенье, то переносится на понедельник. По введенной дате программа должна генерировать расписание из дат на текущий месяц на 2022 год.

https://github.com/NafaNaniz/exam/blob/main/WorkScheduleGenerator.java

  1. Разработать класс для представления комплексных чисел с возможностью задания вещественной и мнимой частей в виде массива из двух чисел типа int. Определить методы для выполнения операций сложения, вычитания и умножения комплексных чисел.

https://github.com/AliceAnd0/java_exam/blob/main/ComplexNumber.java

  1. Создайте класс Form - оболочку для создания и ввода пароля. Он должен иметь методы input, submit, password. Создайте класс SmartForm, который будет наследовать от Form и сохранять значения password.

https://github.com/polinatut/exem_java/tree/main/ex_24

  1. Сделайте класс User, в котором будут следующие protected поля - name (имя), age (возраст), public методы setName, getName, setAge, getAge. Сделайте класс Worker, который наследует от класса User и вносит дополнительное private поле salary (зарплата), а также методы public getSalary и setSalary. Создайте объект этого класса 'Иван', возраст 25, зарплата 1000. Создайте второй объект этого класса 'Вася', возраст 26, зарплата 2000. Найдите сумму зарплата Ивана и Васи. Сделайте класс Student, который наследует от класса User и вносит дополнительные private поля стипендия, курс, а также геттеры и сеттеры для них.

https://github.com/mirrrler/task25

  1. Создайте класс ColorModel для определения цветовой модели. Разработайте подклассы RGBconverter и CMYKconverter для конвертации цвета из одной модели в другую. Конвертация CMYK в RGB производится по следующим формулам: R = 255 × (1-C) × (1-K), G = 255 × (1-M) × (1-K), B = 255 × (1-Y) × (1-K) (где R – red, G – green, B – black, C – Cyan, M - Magenta, Y - Yellow, K- Black))

https://github.com/dariadegt/java_exam/blob/main/Task_26.java

  1. Создайте класс Number для конвертации десятичного числа в бинарный, восьмеричный, шестнадцатеричный вид. Реализовать в виде статических методов класса. Числа вводятся с клавиатуры с запросом в какой численный вид конвертировать.

https://github.com/gavalone/for_work/blob/main/src/Number.java

  1. Разработать класс Neuron для реализации нейронной сети из двух нейронов и одного выхода. Сделать функцию прямого распространения с функцией активации в виде сигмоиды.

https://github.com/bshkrrr/java_exam/tree/main/src/main/java/com/example/demo

  1. Напишите программу, которая заполняет списочный массив случайными числами типа Integer (значения этих чисел были от 1 до 100). Список должен содержать 100 элементов. Затем отсортируйте по убыванию список и выведите первые 10 значений в консоль. Результаты сохраните в MySQL/PostgreSQL.

https://github.com/flamingo99900/JavaEkz/tree/task_29

  1. Разработайте программу, которая заполняет список случайными числами. Количество элементов и числовой диапазон вводятся пользователем. Программа должна проверять, входит ли число (также вводится пользователем) в данный список. Должен быть реализован бинарный поиск. Результаты должны сохраняться в MySQL/PostgreSQL и выводиться оттуда же.

https://github.com/max33128/tasks

  1. На основе класса BitSet разработайте программу для реализации битовых операций AND, OR, XOR, а также маскирования.

https://github.com/itsvakonst/javaexam/blob/main/Task31.java

  1. Напишите программу, которая получает в качестве входных данных два числа. Эти числа являются количество строк и столбцов двумерной коллекции целых чисел. Далее элементы заполняются случайными числами и выводятся в консоль в виде таблицы.

https://github.com/Delia0001/java_exam/blob/main/Task_32.java

  1. Разработайте программу, которая получает в качестве параметра два числа –количество строк и столбцов двумерной коллекции целых чисел. Коллекция заполняется случайными числами, после чего на экран выводятся максимальное и минимальное значения с индексами ячеек.

https://github.com/NafaNaniz/exam/blob/main/Array2D.java

  1. Разработайте программу, в которой создайте две коллекции с именами людей (строковые переменные). Результат сохранить в MySQL/PostgreSQL. Затем последовательно выводите в консоль имена.

https://github.com/AliceAnd0/java_exam/tree/main/NamesToDB

  1. Напишите программу, которая реализует класс Matrix и следующие методы:
  2. Сложение и вычитание матриц.
  3. Умножение матрицы на число.
  4. Произведение двух матриц.
  5. Транспонированная матрица.
  6. Возведение матрицы в степень.
  7. Если метод, возвращает матрицу, то он должен возвращать новый объект, а не менять базовый.

https://github.com/polinatut/exem_java/tree/main/ex_35

  1. Разработать программу для поочередной обработки текстовых файлов. Файлы созданы со следующими именами: n.txt, где n – натуральное число. В файлах записаны: в первой строке одно число с плавающей запятой, во второй строке – второе число. Пользователь вводит название файла и требуемую операцию над числами (сложение, умножение, разность). Результат выводится на экран и файл n_out.txt.

https://github.com/mirrrler/task36

  1. Написать приложение для сложения, вычитания, умножения, деления, возведения в степень логарифмов. Программа должна выполнять ввод данных, проверку правильности введенных данных, выдачу сообщений в случае ошибок. Результат выводится на экран и записывается в файл.

https://github.com/dariadegt/java_exam/blob/main/Task_37.java

  1. Разработать программу шифровки-дешифровки по алгоритму AES-128. Данные берутся из файла, зашифрованные данные сохраняются в указанный файл.

https://github.com/gavalone/for_work/blob/main/src/Task_38.java

  1. Разработать программу нахождения наибольшего общего делителя двух натуральных чисел. Требуется реализовать рекурсивный и без рекурсии варианты. Результат сохранить в MySQL/PostgreSQL.

https://github.com/bshkrrr/java_exam/tree/main/src/main/java/com/example/demo

  1. Напишите программу, которая каждые 5 секунд отображает на экране данные о времени, прошедшем от начала запуска программы, а другой её поток выводит сообщение каждые 7 секунд. Третий поток выводит на экран сообщение каждые 10 секунд. Программа работает одну минуту, затем останавливается. Все результаты после вывода необходимо сохранить в MySQL/PostgreSQL.

https://github.com/flamingo99900/JavaEkz/tree/task_40

  1. Условие задачи: «Ввести две строки (не менее 50 символов каждая) с клавиатуры. Необходимо вывести на экран две введенных ранее строки, подсчитать и вывести размер длины каждой строки, объединить данные строки в одну, сравнить данные строки и результат сравнения вывести на экран». По данному условию необходимо реализовать программу с интерактивным консольным меню, (т.е. вывод списка действий по цифрам. При этом при нажатии на цифру у нас должно выполняться определенное действие). При этом в программе данные пункты должны называться следующим образом:
  2. Вывести все таблицы из MySQL.
  3. Создать таблицу в MySQL.
  4. Ввести две строки с клавиатуры, результат сохранить в MySQL с последующим выводом в консоль.
  5. Подсчитать размер ранее введенных строк, результат сохранить в MySQL с последующим выводом в консоль.
  6. Объединить две строки в единое целое, результат сохранить в MySQL с последующим выводом в консоль.
  7. Сравнить две ранее введенные строки, результат сохранить в MySQL с последующим выводом в консоль.
  8. Сохранить все данные (вышеполученные результаты) из MySQL в Excel и вывести на экран.

https://github.com/max33128/tasks

  1. Написать на основе Spring Boot клиент-серверное приложение MyUser, в котором можно управлять данными пользователей из базы данных через веб-интерфейс: имя, фамилия, возраст, номер группы. База данных может быть любой – MySQL, PostgreSQL и т.д. При этом должна быть доступна возможность добавления/удаления/редактирования пользователей.

https://github.com/itsvakonst/javaexam/tree/main/Task42/main

  1. Написать на основе Spring Boot Security форму для авторизации и регистрации пользователя. При этом после авторизации пользователя должно быть перенаправление на главную страницу. Главная страница должна содержать запись «Hello World!». При этом до авторизации главная страница не должна быть доступна для пользователя.

Код из main: https://github.com/Delia0001/java_exam/tree/main/Task43/main

Весь проект в формате zip: https://github.com/Delia0001/java_exam/blob/main/task_43.zip

  1. Разработать MVC-приложение арифметический калькулятор на основе Spring Boot. Применить шаблонизатор Thymeleaf. Все результаты вычисления должны сохраняться и выводиться из MySQL.

https://github.com/NafaNaniz/calc

  1. Разработка веб-MVC приложения на основе Spring Boot. Приложение должно генерировать последовательность из 1000 случайных чисел в диапазоне, заданном пользователем, и выводит эти числа на экран и вычисляет их среднее арифметическое.

https://github.com/AliceAnd0/java_exam/tree/main/WebMVCRandomNumbers

  1. Разработать приложение для работы с локальной базой данных MySQL. Создайте базу данных мобильных телефонов (не менее 10 позиций), со следующими полями: производитель, модель, год выпуска, диагональ экрана. Напишите методы для выполнения запросов к базе данных. Все данные должны выводиться в консоли на экран.

https://github.com/polinatut/exem_java/tree/main/ex_46