добавлена документация

This commit is contained in:
styazhkoV 2025-03-31 23:20:46 +05:00
parent 332abbcb8a
commit ea0b08b413
5 changed files with 621 additions and 0 deletions

View file

@ -0,0 +1,26 @@
package org.springframework.samples.petclinic.model;
@Entity
@Table(name = "appointments")
public class Appointment {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@ManyToOne
@JoinColumn(name = "pet_id", nullable = false)
private Pet pet;
@ManyToOne
@JoinColumn(name = "vet_id", nullable = false)
private Vet vet;
@Column(name = "date", nullable = false)
private LocalDate date;
@Column(name = "description")
private String description;
// Геттеры и сеттеры
}

View file

@ -0,0 +1,235 @@
### 🔍 Разбираем архитектуру Spring PetClinic
**Spring PetClinic** — это демонстрационное приложение, которое показывает лучшие практики разработки на **Spring Boot**. Оно представляет собой веб-приложение для ветеринарной клиники, где можно управлять владельцами, питомцами и ветеринарами.
Проект использует **Spring Boot, Spring MVC, Spring Data JPA, Hibernate и Thymeleaf** (шаблонизатор), а в качестве базы данных — **H2 или MySQL/PostgreSQL**.
---
## 📂 1. Общая структура проекта
Когда ты скачиваешь репозиторий [Spring PetClinic](https://github.com/spring-projects/spring-petclinic.git) и открываешь его в IDE (например, IntelliJ IDEA), файловая структура выглядит так:
```plaintext
spring-petclinic/
│── src/
│ ├── main/
│ │ ├── java/org/springframework/samples/petclinic/
│ │ │ ├── model/ # Сущности (Entity)
│ │ │ ├── repository/ # Репозитории (DAO)
│ │ │ ├── service/ # Логика (Сервисы)
│ │ │ ├── web/ # Контроллеры (REST API + MVC)
│ │ │ ├── PetClinicApplication.java # Точка входа в приложение
│ ├── resources/
│ │ ├── application.properties # Конфигурация Spring Boot
│ │ ├── db/ # SQL-скрипты для инициализации БД
│ │ ├── templates/ # Шаблоны Thymeleaf для UI
│── pom.xml # Файл зависимостей Maven
```
---
## ⚙ 2. Основные компоненты проекта
Spring PetClinic построен по классической **трёхслойной архитектуре**:
1. **Model (Модель)** — хранит сущности и их взаимосвязи.
2. **Repository (Репозиторий/DAO)** — отвечает за работу с базой данных.
3. **Service (Сервис)** — содержит бизнес-логику.
4. **Web (Контроллер)** — обработка HTTP-запросов и взаимодействие с UI.
Разберём каждый слой подробно.
---
## 📌 3. Модель (Model)
Этот слой отвечает за **представление данных** и использует **аннотации JPA** для работы с базой.
Пример: **сущность `Owner` (владелец питомца)**
Файл: `model/Owner.java`
```java
@Entity
@Table(name = "owners")
public class Owner extends Person {
@Column(name = "address")
private String address;
@Column(name = "city")
private String city;
@Column(name = "telephone")
private String telephone;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
private Set<Pet> pets = new HashSet<>();
// Геттеры и сеттеры
}
```
### 🔹 Разбор кода:
- `@Entity` — указывает, что это сущность для базы данных.
- `@Table(name = "owners")` — связывает с таблицей `owners` в БД.
- `@Column(name = "city")` — отображает поле в столбец `city`.
- `@OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")` — указывает, что один владелец может иметь **много питомцев** (связь **"один ко многим"**).
Пример другой сущности: **Pet (питомец)**
```java
@Entity
@Table(name = "pets")
public class Pet {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "name")
private String name;
@ManyToOne
@JoinColumn(name = "owner_id")
private Owner owner;
// Геттеры и сеттеры
}
```
### 🔹 Здесь:
- `@ManyToOne` — питомец связан **с одним владельцем**.
- `@JoinColumn(name = "owner_id")` — связывает `Pet` с `Owner` по `owner_id`.
---
## 📌 4. Репозиторий (Repository)
Этот слой отвечает за взаимодействие с базой данных.
Пример: **репозиторий для владельцев**
Файл: `repository/OwnerRepository.java`
```java
public interface OwnerRepository extends JpaRepository<Owner, Integer> {
@Query("SELECT o FROM Owner o WHERE o.lastName LIKE :lastName%")
Collection<Owner> findByLastName(@Param("lastName") String lastName);
}
```
### 🔹 Разбор кода:
- `extends JpaRepository<Owner, Integer>` — позволяет использовать готовые методы (`findById()`, `save()`, `deleteById()`).
- `@Query("SELECT o FROM Owner o WHERE o.lastName LIKE :lastName%")` — кастомный запрос для поиска владельцев **по фамилии**.
PetClinic использует **Spring Data JPA**, поэтому многие методы создаются **автоматически**.
---
## 📌 5. Сервис (Service)
Этот слой реализует **бизнес-логику**, вызывая методы репозитория.
Пример: **сервис для владельцев**
Файл: `service/OwnerService.java`
```java
@Service
public class OwnerService {
private final OwnerRepository ownerRepository;
@Autowired
public OwnerService(OwnerRepository ownerRepository) {
this.ownerRepository = ownerRepository;
}
public Owner findOwnerById(int id) {
return ownerRepository.findById(id).orElse(null);
}
public void saveOwner(Owner owner) {
ownerRepository.save(owner);
}
}
```
### 🔹 Разбор кода:
- `@Service` — аннотация, указывающая, что этот класс — **сервис**.
- `findOwnerById(int id)` — возвращает владельца по ID.
- `saveOwner(Owner owner)` — сохраняет владельца в БД.
---
## 📌 6. Контроллер (Web)
Контроллеры принимают **HTTP-запросы** и передают их в сервис.
Пример: **контроллер для владельцев**
Файл: `web/OwnerController.java`
```java
@RestController
@RequestMapping("/owners")
public class OwnerController {
private final OwnerService ownerService;
@Autowired
public OwnerController(OwnerService ownerService) {
this.ownerService = ownerService;
}
@GetMapping("/{ownerId}")
public ResponseEntity<Owner> getOwner(@PathVariable int ownerId) {
Owner owner = ownerService.findOwnerById(ownerId);
return owner != null ? ResponseEntity.ok(owner) : ResponseEntity.notFound().build();
}
@PostMapping("/")
public ResponseEntity<Owner> createOwner(@RequestBody Owner owner) {
ownerService.saveOwner(owner);
return ResponseEntity.status(HttpStatus.CREATED).body(owner);
}
}
```
### 🔹 Разбор кода:
- `@RestController` — этот класс **обрабатывает HTTP-запросы**.
- `@GetMapping("/{ownerId}")`**возвращает владельца** по ID.
- `@PostMapping("/")`**создаёт нового владельца**.
---
## 🚀 7. Точка входа в приложение
Файл: `PetClinicApplication.java`
```java
@SpringBootApplication
public class PetClinicApplication {
public static void main(String[] args) {
SpringApplication.run(PetClinicApplication.class, args);
}
}
```
Здесь **Spring Boot автоматически запускает приложение**.
---
## 🔥 Итог
Архитектура Spring PetClinic:
1. **Модель (Model)** — сущности (Owner, Pet, Vet).
2. **Репозиторий (Repository)** — доступ к данным через `Spring Data JPA`.
3. **Сервис (Service)** — бизнес-логика.
4. **Контроллер (Web)** — обработка REST-запросов.
5. **Точка входа (Main Class)** — запуск приложения.

View file

@ -0,0 +1,3 @@
На примере архитектуры проекта https://github.com/spring-projects/spring-petclinic.git
подробно опиши все его модели с описанием что делает код в каждой модели и зачем
Благодарю

View file

@ -0,0 +1,167 @@
В проекте **Spring PetClinic** пакет `owner` содержит классы, связанные с управлением владельцами питомцев и их питомцами. Рассмотрим подробно каждый файл из этого пакета, описывая его назначение и основные элементы кода.
### 1. Owner.java
Класс `Owner` представляет владельца питомца и наследует свойства от класса `Person`. Он содержит информацию о владельце и список его питомцев.
**Код класса:**
```java
@Entity
@Table(name = "owners")
public class Owner extends Person {
@Column(name = "address")
@NotEmpty
private String address;
@Column(name = "city")
@NotEmpty
private String city;
@Column(name = "telephone")
@NotEmpty
@Digits(fraction = 0, integer = 10)
private String telephone;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
private Set<Pet> pets = new HashSet<>();
// Геттеры и сеттеры
}
```
**Назначение кода:**
- Аннотации `@Entity` и `@Table(name = "owners")` указывают, что класс является сущностью JPA и сопоставляется с таблицей `owners` в базе данных.
- Поля `address`, `city` и `telephone` хранят контактную информацию владельца. Аннотации `@NotEmpty` и `@Digits` обеспечивают валидацию данных.
- Поле `pets` представляет собой коллекцию питомцев, принадлежащих владельцу, с каскадным типом `ALL`, что означает, что все операции (сохранение, обновление, удаление) над владельцем будут применяться и к его питомцам.
**Зачем это нужно:**
Этот класс позволяет хранить и управлять информацией о владельцах и их питомцах, обеспечивая связь между ними.
### 2. Pet.java
Класс `Pet` представляет питомца и содержит информацию о нем, включая тип, дату рождения и историю посещений.
**Код класса:**
```java
@Entity
@Table(name = "pets")
public class Pet extends NamedEntity {
@Column(name = "birth_date")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate birthDate;
@ManyToOne
@JoinColumn(name = "type_id")
private PetType type;
@ManyToOne
@JoinColumn(name = "owner_id")
private Owner owner;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "pet")
private Set<Visit> visits = new LinkedHashSet<>();
// Геттеры и сеттеры
}
```
**Назначение кода:**
- Аннотации `@Entity` и `@Table(name = "pets")` указывают, что класс является сущностью JPA и сопоставляется с таблицей `pets`.
- Поле `birthDate` хранит дату рождения питомца с форматом `yyyy-MM-dd`.
- Поле `type` с аннотацией `@ManyToOne` устанавливает связь с типом питомца (`PetType`).
- Поле `owner` с аннотацией `@ManyToOne` устанавливает связь с владельцем (`Owner`).
- Поле `visits` представляет коллекцию посещений питомца, с каскадным типом `ALL`.
**Зачем это нужно:**
Этот класс позволяет хранить детальную информацию о каждом питомце, включая его тип, владельца и историю посещений, что важно для ведения медицинских записей.
### 3. PetType.java
Класс `PetType` определяет тип питомца, например, собака или кошка.
**Код класса:**
```java
@Entity
@Table(name = "types")
public class PetType extends NamedEntity {
// Дополнительные поля и методы могут быть добавлены при необходимости
}
```
**Назначение кода:**
- Аннотации `@Entity` и `@Table(name = "types")` указывают на соответствие таблице `types`.
- Наследование от `NamedEntity` предполагает наличие поля `name` для хранения названия типа питомца.
**Зачем это нужно:**
Класс используется для классификации питомцев по видам, что упрощает управление и фильтрацию данных.
### 4. Visit.java
Класс `Visit` представляет посещение питомцем ветеринарной клиники.
**Код класса:**
```java
@Entity
@Table(name = "visits")
public class Visit extends BaseEntity {
@Column(name = "visit_date")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate date;
@Column(name = "description")
@NotEmpty
private String description;
@ManyToOne
@JoinColumn(name = "pet_id")
private Pet pet;
// Геттеры и сеттеры
}
```
**Назначение кода:**
- Аннотации `@Entity` и `@Table(name = "visits")` указывают на соответствие таблице `visits`.
- Поле `date` хранит дату визита.
- Поле `description` содержит описание причины визита.
- Поле `pet` с аннотацией `@ManyToOne` устанавливает связь с питомцем (`Pet`).
**Зачем это нужно:**
Класс позволяет отслеживать историю медицинских посещений каждого питомца, что важно для ведения медицинских записей и планирования последующего ухода.
### 5. OwnerController.java
Класс `OwnerController` отвечает за обработку HTTP-запросов, связанных с владельцами питомцев.
**Код класса:**
```java
@Controller
@RequestMapping("/owners")
class OwnerController {
private static final String VIEWS_OWNER_CREATE_OR_UPDATE_FORM = "owners/createOr

View file

@ -0,0 +1,190 @@
Проект **Spring PetClinic** — это образец веб-приложения, демонстрирующий использование Spring Framework для создания информационной системы ветеринарной клиники. В этом проекте определены следующие основные модели:
1. **Owner** (Владелец)
2. **Pet** (Питомец)
3. **PetType** (Тип питомца)
4. **Visit** (Визит)
5. **Vet** (Ветеринар)
6. **Specialty** (Специализация)
Рассмотрим каждую из этих моделей более подробно.
### 1. Owner (Владелец)
Класс `Owner` представляет владельца одного или нескольких питомцев. Он наследует свойства от класса `Person` и добавляет специфичные для владельца атрибуты.
**Код класса:**
```java
@Entity
@Table(name = "owners")
public class Owner extends Person {
@Column(name = "address")
private String address;
@Column(name = "city")
private String city;
@Column(name = "telephone")
private String telephone;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
private Set<Pet> pets = new HashSet<>();
// Геттеры и сеттеры
}
```
**Описание полей:**
- `address`: Адрес владельца.
- `city`: Город проживания владельца.
- `telephone`: Контактный телефон владельца.
- `pets`: Набор питомцев, принадлежащих владельцу. Связь `OneToMany` с сущностью `Pet` означает, что один владелец может иметь несколько питомцев.
**Зачем это нужно:**
Модель `Owner` позволяет хранить и управлять информацией о клиентах ветеринарной клиники, включая их контактные данные и список питомцев.
### 2. Pet (Питомец)
Класс `Pet` представляет животное, принадлежащее владельцу.
**Код класса:**
```java
@Entity
@Table(name = "pets")
public class Pet extends NamedEntity {
@Column(name = "birth_date")
private LocalDate birthDate;
@ManyToOne
@JoinColumn(name = "type_id")
private PetType type;
@ManyToOne
@JoinColumn(name = "owner_id")
private Owner owner;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "pet")
private Set<Visit> visits = new HashSet<>();
// Геттеры и сеттеры
}
```
**Описание полей:**
- `birthDate`: Дата рождения питомца.
- `type`: Тип питомца (например, собака, кошка). Связь `ManyToOne` с сущностью `PetType`.
- `owner`: Владелец питомца. Связь `ManyToOne` с сущностью `Owner`.
- `visits`: Список визитов питомца к ветеринару. Связь `OneToMany` с сущностью `Visit`.
**Зачем это нужно:**
Модель `Pet` позволяет хранить информацию о животных, включая их тип, дату рождения, владельца и историю посещений клиники.
### 3. PetType (Тип питомца)
Класс `PetType` определяет вид питомца, например, собака или кошка.
**Код класса:**
```java
@Entity
@Table(name = "types")
public class PetType extends NamedEntity {
// Дополнительные поля и методы могут быть добавлены при необходимости
}
```
**Зачем это нужно:**
Модель `PetType` используется для классификации питомцев по видам, что упрощает управление и фильтрацию данных.
### 4. Visit (Визит)
Класс `Visit` представляет посещение питомцем ветеринарной клиники.
**Код класса:**
```java
@Entity
@Table(name = "visits")
public class Visit extends BaseEntity {
@Column(name = "visit_date")
private LocalDate date;
@Column(name = "description")
private String description;
@ManyToOne
@JoinColumn(name = "pet_id")
private Pet pet;
// Геттеры и сеттеры
}
```
**Описание полей:**
- `date`: Дата визита.
- `description`: Описание или причина визита.
- `pet`: Питомец, который посетил клинику. Связь `ManyToOne` с сущностью `Pet`.
**Зачем это нужно:**
Модель `Visit` позволяет отслеживать историю медицинских посещений каждого питомца, что важно для ведения медицинских записей и планирования последующего ухода.
### 5. Vet (Ветеринар)
Класс `Vet` представляет ветеринарного врача, работающего в клинике.
**Код класса:**
```java
@Entity
@Table(name = "vets")
public class Vet extends Person {
@ManyToMany
@JoinTable(name = "vet_specialties", joinColumns = @JoinColumn(name = "vet_id"),
inverseJoinColumns = @JoinColumn(name = "specialty_id"))
private Set<Specialty> specialties = new HashSet<>();
// Геттеры и сеттеры
}
```
**Описание полей:**
- `specialties`: Набор специализаций ветеринара. Связь `ManyToMany` с сущностью `Specialty`.
**Зачем это нужно:**
Модель `Vet` хранит информацию о врачах и их специализациях, что помогает в назначении подходящего специалиста для каждого случая.
### 6. Specialty (Специализация)
Класс `Specialty` определяет область специализации ветеринара, например, кардиология или дерматология.
**Код класса:**
```java
@Entity
@Table(name =