Overview

Spring Data JPA can automatically generate database queries based solely on the method names you define in your repository interface.

  • Based on specific naming conventions, a JPQL query is automatically created and executed. This feature is extremely useful for most CRUD operations and simple retrieval queries.
  • But..집계를 하는데 join을 매우 많이 하면…그렇게 복잡한건 그냥 개발자가 논리적으로 하는게 더 나음
  • Spring docs
  • 2 ways
    • By method name
    • By @Query annotation

By Method Name

Rules

KeywordMeaning
findByFind / Retrieve
countByCount
deleteByDelete
existsByCheck for existence
TopNTop N results
FirstThe first result

Example

Method NameExample of Generated JPQL
findByUsernameSELECT m FROM Member m WHERE m.username = ?1
findByEmailAndAgeSELECT m FROM Member m WHERE m.email = ?1 AND m.age = ?2
findTop3ByOrderByAgeDescSELECT m FROM Member m ORDER BY m.age DESC LIMIT 3
List<Member> findByUsername(String username);
List<Member> findByAgeGreaterThan(int age);
List<Member> findByUsernameAndAge(String username, int age);
List<Member> findTop3ByOrderByAgeDesc();
  • This approach is well-suited for simple searches, pagination, and sorting.
  • If the query involves many complex conditions, you should consider using QueryDSL or @Query instead.

@Query annotation

For writing complex queries, you can use the @Query annotation to directly provide either a JPQL or a Native SQL query. This approach uses parameter binding (with @Param) to prevent SQL Injection and ensure type safety.

JPQL

@Query("SELECT m FROM Member m WHERE m.username = :username")
List<Member> findByUsername(@Param("username") String username);

Native Query

@Query(value = "SELECT * FROM member WHERE username = :username", nativeQuery = true)
List<Member> findByNativeUsername(@Param("username") String username);

JPQL vs. Native Query

FeatureJPQL (Java Persistence Query Language)Native Query (Standard SQL)
Query TargetEntities and their fieldsDatabase tables and columns
Database Dependency✅ Database-independent❌ Database-dependent
Best Use CaseGeneral purpose, object-oriented queriesComplex queries, performance tuning, specific DB features
PortabilityHigh (easy to switch databases)Low (may require changes if the DB is switched
visual example:

Tip

  • Use a Native Query when your query is highly complex or requires performance optimization.
  • For most situations, JPQL is sufficient.
  • Use @Query judiciously where needed to improve readability and maintainability.

스프링 입문을 위한 자바 (개구리 책) rfc editor