← Назад к вопросам

Для чего нужен JpaRepository?

1.0 Junior🔥 231 комментариев
#Spring Boot и Spring Data

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# JpaRepository в Spring Data

JpaRepository — это интерфейс для работы с БД, который предоставляет готовые методы CRUD операций без необходимости писать SQL.

Назначение

  1. CRUD операции — Create, Read, Update, Delete без написания SQL
  2. Автоматическая реализация — Spring сгенерирует реализацию в runtime
  3. Query методы — поиск по полям через названия методов
  4. Пагинация и сортировка — встроенная поддержка
  5. Батч операции — сохранение/удаление списков

Иерархия интерфейсов

Repository (маркер)
    ↓
CrudRepository<T, ID> (CRUD: save, delete, findById)
    ↓
PagingAndSortingRepository<T, ID> (Pageable, Sort)
    ↓
JpaRepository<T, ID> (flush, saveAndFlush, deleteInBatch)

Создание репозитория

// 1. Создаём JPA сущность
@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String name;
    private String email;
    // getters, setters
}

// 2. Создаём репозиторий (одна строка!)
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    // Spring автоматически реализует все методы
}

// 3. Используем в сервисе
@Service
public class UserService {
    private final UserRepository repo;
    
    public UserService(UserRepository repo) {
        this.repo = repo;
    }
    
    public User saveUser(User user) {
        return repo.save(user); // автоматически INSERT или UPDATE
    }
}

Встроенные CRUD методы

UserRepository repo = /* ... */;

// CREATE
User user = new User("John", "john@example.com");
User saved = repo.save(user); // INSERT

// READ
User found = repo.findById(1L).orElse(null); // SELECT by ID
List<User> all = repo.findAll(); // SELECT all

// UPDATE
user.setEmail("newemail@example.com");
repo.save(user); // UPDATE

// DELETE
repo.deleteById(1L); // DELETE by ID
repo.delete(user);   // DELETE one
repo.deleteAll();    // DELETE all

Query методы (явные запросы)

Spring сгенерирует SQL автоматически по названию метода:

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    // Поиск по одному полю
    User findByEmail(String email);
    List<User> findByName(String name);
    
    // Поиск по нескольким полям (AND)
    User findByEmailAndName(String email, String name);
    
    // OR
    List<User> findByEmailOrName(String email, String name);
    
    // Like (содержит)
    List<User> findByNameContaining(String substring);
    List<User> findByNameLike(String pattern); // % needed
    
    // Сравнение
    List<User> findByIdGreaterThan(Long id);
    List<User> findByIdLessThan(Long id);
    List<User> findByIdBetween(Long min, Long max);
    
    // In список
    List<User> findByIdIn(List<Long> ids);
    
    // Not
    List<User> findByNameNot(String name);
    
    // Is null / Not null
    List<User> findByEmailIsNull();
    List<User> findByEmailIsNotNull();
    
    // Сортировка в названии
    List<User> findByNameOrderByIdDesc(String name);
    List<User> findByNameOrderByIdAscEmailDesc(String name);
}

Пагинация и сортировка

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    Page<User> findByNameContaining(String name, Pageable pageable);
    List<User> findAll(Sort sort);
}

// Использование
UserRepository repo = /* ... */;

// Пагинация: страница 0, 10 элементов
Pageable pageable = PageRequest.of(0, 10);
Page<User> page = repo.findByNameContaining("John", pageable);
List<User> content = page.getContent();
int totalPages = page.getTotalPages();
int totalElements = page.getTotalElements();

// С сортировкой
Pageable sorted = PageRequest.of(0, 10, Sort.by("email").descending());
Page<User> page2 = repo.findByNameContaining("John", sorted);

// Только сортировка
Sort sort = Sort.by("name").ascending().and(Sort.by("email").descending());
List<User> all = repo.findAll(sort);

Кастомные JPQL запросы

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    
    // @Query с JPQL
    @Query("SELECT u FROM User u WHERE u.email = :email")
    User findUserByEmail(@Param("email") String email);
    
    // Более сложный запрос
    @Query("SELECT u FROM User u WHERE u.name LIKE %:name% AND u.id > :minId")
    List<User> searchUsers(@Param("name") String name, @Param("minId") Long minId);
    
    // Native SQL
    @Query(value = "SELECT * FROM users WHERE email = :email", nativeQuery = true)
    User findByEmailNative(@Param("email") String email);
}

Батч операции

UserRepository repo = /* ... */;

// Сохранение списка
List<User> users = Arrays.asList(
    new User("Alice", "alice@example.com"),
    new User("Bob", "bob@example.com"),
    new User("Charlie", "charlie@example.com")
);
repo.saveAll(users);

// Удаление списка
repo.deleteAll(users);

// Удаление по ID
repo.deleteAllById(Arrays.asList(1L, 2L, 3L));

Практический пример

@Entity
@Table(name = "products")
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private Double price;
    private Integer quantity;
}

@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {
    List<Product> findByName(String name);
    List<Product> findByPriceLessThan(Double price);
    List<Product> findByQuantityGreaterThan(Integer qty);
    Page<Product> findAll(Pageable pageable);
}

@Service
public class ProductService {
    private final ProductRepository repo;
    
    public ProductService(ProductRepository repo) {
        this.repo = repo;
    }
    
    public Product createProduct(String name, Double price) {
        return repo.save(new Product(name, price));
    }
    
    public List<Product> searchByName(String name) {
        return repo.findByName(name);
    }
    
    public Page<Product> getPaginatedProducts(int page) {
        return repo.findAll(PageRequest.of(page, 20));
    }
    
    public void deleteProduct(Long id) {
        repo.deleteById(id);
    }
}

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

  1. Меньше кода — не пишем SQL вручную
  2. Безопасность — защита от SQL injection
  3. Гибкость — поддержка сложных запросов через JPQL
  4. Производительность — оптимизация работы с БД
  5. Портативность — перейти на другую БД просто (PostgreSQL, MySQL и т.д.)

Когда использовать

  • Стандартные CRUD — JpaRepository достаточно
  • Сложные запросы — используй @Query
  • Критическая производительность — рассмотри native SQL
  • Специальная логика — имплементируй кастомный интерфейс

JpaRepository — это самый быстрый способ получить доступ к БД в Spring приложении.