Labs ICT
Pro Login

Query Methods

Custom queries with method names.

Query Methods

One of the coolest things about Spring Data JPA is query derivation. You write a method name, and Spring figures out the query. No SQL, no JPQL, just English-like method names.

The method name acts as a blueprint. Spring breaks it down piece by piece and builds the query. It's like speaking English to the database and having it understand you.

Method Name Conventions

The pattern is simple. Start with findBy, then add the field name and the condition. For example, findByEmail means "find where email equals the parameter." You can chain conditions too.

Here are some common patterns. findByNameAndEmail finds where both conditions match. findByNameOrEmail finds where either matches. findByAgeLessThan finds records below a value. findByEmailIsNull finds null values. The possibilities are nearly endless.

public interface UserRepository extends JpaRepository<User, Long> {
    User findByEmail(String email);
    List<User> findByNameAndAge(String name, int age);
    List<User> findByEmailContaining(String keyword);
    List<User> findByAgeBetween(int min, int max);
    List<User> findTop5ByOrderByNameAsc();
}

@Query Annotation

Sometimes method names get too long or you need more control. That's where @Query comes in. You write your own JPQL query directly on the method. JPQL looks like SQL but uses entity names instead of table names.

Think of JPQL as a higher-level SQL. You reference Java class names and field names, not database columns. It's portable across different databases because it's not tied to any specific SQL dialect.

public interface UserRepository extends JpaRepository<User, Long> {
    @Query("SELECT u FROM User u WHERE u.email = :email")
    User findByEmail(@Param("email") String email);

    @Query("SELECT u FROM User u WHERE u.name LIKE %:keyword%")
    List<User> searchByName(@Param("keyword") String keyword);
}

Native SQL Queries

When JPQL isn't enough, you can drop down to native SQL. Just set nativeQuery = true in the @Query annotation. Now you're writing raw SQL that the database executes directly.

Use native queries when you need database-specific features or complex joins that JPQL can't handle. They're less portable but give you full control over the SQL.

public interface UserRepository extends JpaRepository<User, Long> {
    @Query(value = "SELECT * FROM users WHERE email = :email", nativeQuery = true)
    User findByEmailNative(@Param("email") String email);
}
Try it Yourself →