В Java, особено в Spring Boot приложения, има няколко основни слоя и концепции, които разделят логиката на различни отговорности. Нека разгледаме DTOs, Entities, Mappers, Repositories и Services / Controllers и как те работят заедно.
1. DTO (Data Transfer Object)
DTO (Обект за трансфер на данни) е клас, който служи за прехвърляне на данни между различни слоеве в приложението (например между контролер и клиент).
Използва се, за да се избегне директното излагане на ентититата към външния свят.
Пример за DTO
public class UserDTO {
private String name;
private String email;
public UserDTO(String name, String email) {
this.name = name;
this.email = email;
}
// Getters & Setters
}
Защо използваме DTO?
Предпазваме ентитито от промени.
Контролираме какви данни да се връщат.
По-малки и по-ефективни обекти при работа с API.
2. Entity
Entity е клас, който представлява обект в базата данни.
В Spring Boot обикновено се маркира с @Entity
и се използва в JPA (Hibernate).
Пример за Entity
import jakarta.persistence.*;
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
// Constructors, Getters & Setters
}
Каква е разликата между DTO и Entity?
Entity е директно свързано с базата данни.
DTO е просто обект за прехвърляне на данни и не е свързан с базата.
3. Mapper
Мапърите се използват за преобразуване между DTO и Entity.
Това може да стане ръчно или с библиотека като MapStruct.
Ръчен Mapper
public class UserMapper {
public static UserDTO toDTO(User user) {
return new UserDTO(user.getName(), user.getEmail());
}
public static User toEntity(UserDTO dto) {
User user = new User();
user.setName(dto.getName());
user.setEmail(dto.getEmail());
return user;
}
}
Защо използваме мапъри?
Изолираме логиката на трансформацията.
Намаляваме дублирането на код.
4. Repository
Репозиторитата са слоят за достъп до базата данни.
В Spring Boot използваме Spring Data JPA и @Repository
, за да работим с базата чрез интерфейси.
Пример за Repository
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
User findByEmail(String email);
}
Какво прави Repository?
Позволява работа с базата чрез методи като save()
, findById()
, delete()
.
Не пишем SQL – Spring Data JPA генерира заявките автоматично.
5. Service
Сървис слоят съдържа бизнес логиката на приложението.
Той комуникира с репозиторитата, обработва данните и ги връща като DTO.
Пример за Service
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public List<UserDTO> getAllUsers() {
return userRepository.findAll().stream()
.map(UserMapper::toDTO)
.collect(Collectors.toList());
}
public void saveUser(UserDTO userDTO) {
User user = UserMapper.toEntity(userDTO);
userRepository.save(user);
}
}
Какво прави Service?
Обработва данни преди да ги запише или върне.
Работи с репозиторито и използва мапърите.
Изолира бизнес логиката, така че контролерът остава чист.
Как работят заедно? (Цялостен Flow)
Контролерът получава заявка (GET /users
).
Service слоят вика репозиторито и взима всички потребители.
Mapper преобразува User
entity към UserDTO
.
Service връща списъка с DTOs на контролера.
Контролерът връща JSON към клиента.
Пример за Controller
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping
public List<UserDTO> getUsers() {
return userService.getAllUsers();
}
@PostMapping
public void createUser(@RequestBody UserDTO userDTO) {
userService.saveUser(userDTO);
}
}
Заключение
Компонент | Какво прави? |
---|---|
DTO | Обект за прехвърляне на данни (без логика). |
Entity | Представлява таблица в базата. |
Mapper | Преобразува Entity ↔ DTO . |
Repository | Работи с базата данни. |
Service | Съдържа бизнес логика. |
Това разделение помага за:
- По-чист код (Separation of Concerns).
- Лесно поддържане и разширяване на проекта.
- По-добро тестване и изолация на логиката.
Spring Boot използва този модел, за да направи Java уеб приложения бързи и ефективни!