Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Где используешь WHERE
WHERE — это ключевое слово SQL для фильтрации данных в запросах. Используется с SELECT, UPDATE и DELETE операциями.
SELECT с WHERE
Основное применение — фильтрация результатов запроса.
// SQL
SELECT * FROM users WHERE age > 18 AND status = 'ACTIVE';
// JPA Repository
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
List<User> findByAgeGreaterThanAndStatus(int age, String status);
}
// Использование
List<User> adults = repository.findByAgeGreaterThanAndStatus(18, "ACTIVE");
Условия WHERE
Сравнение (=, !=, <, >, <=, >=)
// SQL: WHERE salary >= 50000
List<Employee> highPaid = repository.findBySalaryGreaterThanEqual(50000);
LIKE для текстового поиска
// SQL: WHERE name LIKE '%John%'
List<User> found = repository.findByNameContaining("John");
// SQL: WHERE email LIKE 'user@%.com'
List<User> gmail = repository.findByEmailEndingWith("@gmail.com");
IN для множественных значений
// SQL: WHERE status IN ('ACTIVE', 'PENDING')
List<Order> orders = repository.findByStatusIn(Arrays.asList("ACTIVE", "PENDING"));
NULL проверка
// SQL: WHERE deleted_at IS NULL
List<User> active = repository.findByDeletedAtIsNull();
// SQL: WHERE deleted_at IS NOT NULL
List<User> deleted = repository.findByDeletedAtIsNotNull();
WHERE с @Query
@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {
// Простой WHERE
@Query("SELECT p FROM Product p WHERE p.price > :minPrice")
List<Product> findExpensive(@Param("minPrice") double minPrice);
// Сложные условия
@Query("SELECT p FROM Product p WHERE p.category = :cat AND p.inStock = true")
List<Product> findByCategory(@Param("cat") String category);
// WHERE с JOIN
@Query("SELECT p FROM Product p JOIN p.reviews r WHERE r.rating >= :minRating")
List<Product> findHighRated(@Param("minRating") int rating);
}
UPDATE с WHERE
Обновление данных с условиями.
// SQL: UPDATE users SET status = 'INACTIVE' WHERE age > 65
update users set status = 'INACTIVE' where age > 65;
// JPA
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
@Modifying
@Transactional
@Query("UPDATE User u SET u.status = 'INACTIVE' WHERE u.age > :age")
int deactivateOldUsers(@Param("age") int age);
}
// Использование
@Service
public class UserService {
@Autowired
private UserRepository repository;
public void archiveOldUsers() {
int updated = repository.deactivateOldUsers(65);
System.out.println("Обновлено: " + updated);
}
}
DELETE с WHERE
Удаление данных с условиями.
// SQL: DELETE FROM orders WHERE status = 'CANCELLED' AND created_at < '2023-01-01'
delete from orders where status = 'CANCELLED' and created_at < '2023-01-01';
// JPA
@Repository
public interface OrderRepository extends JpaRepository<Order, Long> {
@Modifying
@Transactional
@Query("DELETE FROM Order o WHERE o.status = 'CANCELLED' AND o.createdAt < :date")
int deleteOldCancelled(@Param("date") LocalDateTime date);
}
// Использование
@Service
public class OrderService {
@Autowired
private OrderRepository repository;
public void cleanup() {
LocalDateTime cutoff = LocalDateTime.now().minusMonths(6);
int deleted = repository.deleteOldCancelled(cutoff);
}
}
WHERE с OR условиями
// SQL: WHERE status = 'ACTIVE' OR status = 'PENDING'
@Query("SELECT u FROM User u WHERE u.status = :status1 OR u.status = :status2")
List<User> findActiveOrPending(
@Param("status1") String status1,
@Param("status2") String status2
);
// Или используй IN
@Query("SELECT u FROM User u WHERE u.status IN (:statuses)")
List<User> findByStatuses(@Param("statuses") List<String> statuses);
WHERE с агрегацией
// SQL: SELECT COUNT(*) FROM orders WHERE status = 'COMPLETED'
long completed = repository.countByStatus("COMPLETED");
// SQL: SELECT SUM(amount) FROM orders WHERE user_id = :userId
@Query("SELECT SUM(o.amount) FROM Order o WHERE o.user.id = :userId")
BigDecimal getTotalByUser(@Param("userId") Long userId);
WHERE с BETWEEN
// SQL: WHERE price BETWEEN 100 AND 1000
List<Product> products = repository.findByPriceBetween(100.0, 1000.0);
// Дата диапазон
@Query("SELECT o FROM Order o WHERE o.createdAt BETWEEN :start AND :end")
List<Order> findByDateRange(
@Param("start") LocalDateTime start,
@Param("end") LocalDateTime end
);
WHERE с подзапросом
// SQL: WHERE user_id IN (SELECT id FROM users WHERE age > 30)
@Query("SELECT o FROM Order o WHERE o.user.id IN " +
"(SELECT u.id FROM User u WHERE u.age > :age)")
List<Order> findOrdersByAdultUsers(@Param("age") int age);
// EXISTS подзапрос
@Query("SELECT u FROM User u WHERE EXISTS " +
"(SELECT 1 FROM Order o WHERE o.user.id = u.id AND o.amount > :minAmount)")
List<User> findUsersWithLargeOrders(@Param("minAmount") BigDecimal amount);
WHERE с использованием CASE
@Query("SELECT CASE WHEN COUNT(o) > 0 THEN 1 ELSE 0 END " +
"FROM Order o WHERE o.user.id = :userId AND o.status = 'COMPLETED'")
int hasCompletedOrders(@Param("userId") Long userId);
Оптимизация WHERE запросов
1. Используй индексы
CREATE INDEX idx_users_status ON users(status);
CREATE INDEX idx_orders_date ON orders(created_at);
2. Избегай функций в WHERE (замедляют индексы)
// ПЛОХО: функция блокирует индекс
@Query("SELECT u FROM User u WHERE UPPER(u.name) = :name")
// ХОРОШО: используй LIKE с правильным регистром
@Query("SELECT u FROM User u WHERE u.name = :name")
3. Порядок условий важен
// Выполняй самые селективные условия первыми
// ХОРОШО: сначала редкое условие, потом частое
WHERE status = 'CANCELLED' AND age > 18
// ПЛОХО: сначала частое, потом редкое
WHERE age > 18 AND status = 'CANCELLED'
Практический пример
@Service
public class OrderSearchService {
@Autowired
private OrderRepository repository;
public List<Order> searchOrders(OrderFilter filter) {
// Комплексный WHERE с множественными условиями
return repository.findOrders(
filter.getUserId(),
filter.getMinAmount(),
filter.getStatus(),
filter.getStartDate(),
filter.getEndDate()
);
}
}
@Repository
public interface OrderRepository extends JpaRepository<Order, Long> {
@Query("SELECT o FROM Order o WHERE " +
"(:userId IS NULL OR o.user.id = :userId) AND " +
"(:minAmount IS NULL OR o.amount >= :minAmount) AND " +
"(:status IS NULL OR o.status = :status) AND " +
"(:startDate IS NULL OR o.createdAt >= :startDate) AND " +
"(:endDate IS NULL OR o.createdAt <= :endDate)")
List<Order> findOrders(
@Param("userId") Long userId,
@Param("minAmount") BigDecimal minAmount,
@Param("status") String status,
@Param("startDate") LocalDateTime startDate,
@Param("endDate") LocalDateTime endDate
);
}
Заключение
WHERE используется:
- SELECT — для фильтрации результатов запроса
- UPDATE — для выбора записей для обновления
- DELETE — для выбора записей для удаления
Это одна из самых важных частей SQL запросов в Java приложениях. Правильное использование WHERE определяет производительность и правильность получаемых данных.