Spring Boot Repository Pattern
A repository is the layer between your application and the database. Spring Data JPA generates the implementation automatically — you define an interface, and Spring provides all the database methods.
Without a Repository (Old Way)
// Writing raw SQL manually — tedious and error-prone
String sql = "SELECT * FROM users WHERE id = ?";
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setLong(1, id);
ResultSet rs = stmt.executeQuery();
User user = new User();
user.setId(rs.getLong("id"));
user.setName(rs.getString("name"));
// ...and 20 more lines
With Spring Data JPA Repository
public interface UserRepository extends JpaRepository<User, Long> {
// That's it. Spring generates all CRUD methods automatically.
}
Spring reads this interface and creates a full working implementation at startup. No SQL required.
Built-in Methods from JpaRepository
Method What It Does ──────────────────────────── ────────────────────────────────────── save(entity) Insert or update a record findById(id) Get one record by primary key findAll() Get all records deleteById(id) Delete a record by primary key count() Count total records existsById(id) Check if a record exists findAll(Pageable pageable) Get records with pagination
Repository Hierarchy
Repository
│ (extends)
CrudRepository ← Basic CRUD: save, find, delete
│ (extends)
PagingAndSortingRepository ← Adds pagination and sorting
│ (extends)
JpaRepository ← Adds batch ops, flush, JPA-specific features
Use JpaRepository — it gives you everything.
Derived Query Methods
Spring Data generates SQL from the method name you write in the interface. The method name is the query:
public interface UserRepository extends JpaRepository<User, Long> {
// SELECT * FROM users WHERE email = ?
User findByEmail(String email);
// SELECT * FROM users WHERE name = ? AND age > ?
List<User> findByNameAndAgeGreaterThan(String name, int age);
// SELECT * FROM users WHERE name LIKE '%keyword%'
List<User> findByNameContaining(String keyword);
// SELECT * FROM users WHERE active = true ORDER BY name ASC
List<User> findByActiveTrueOrderByNameAsc();
// SELECT COUNT(*) FROM users WHERE role = ?
long countByRole(String role);
// DELETE FROM users WHERE email = ?
void deleteByEmail(String email);
}
Derived Query Keyword Reference
Keyword SQL Equivalent Example ────────────── ───────────────── ────────────────────────────── findBy WHERE findByName And AND findByNameAndAge Or OR findByNameOrEmail Like LIKE findByNameLike Containing LIKE '%x%' findByNameContaining StartingWith LIKE 'x%' findByNameStartingWith GreaterThan > findByAgeGreaterThan LessThan < findByAgeLessThan Between BETWEEN findByAgeBetween OrderBy ORDER BY findByRoleOrderByNameAsc IsNull IS NULL findByDeletedAtIsNull True / False = true / = false findByActiveTrue
Custom Queries with @Query
When derived method names get too long or the query is complex, write JPQL (Java-style SQL) directly:
@Query("SELECT u FROM User u WHERE u.email = :email AND u.active = true")
Optional<User> findActiveUserByEmail(@Param("email") String email);
// Native SQL (use sparingly — ties you to a specific database)
@Query(value = "SELECT * FROM users WHERE created_at > :date",
nativeQuery = true)
List<User> findUsersCreatedAfter(@Param("date") LocalDate date);
Using the Repository in a Service
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public User findById(Long id) {
return userRepository.findById(id)
.orElseThrow(() -> new UserNotFoundException(id));
}
public User save(User user) {
return userRepository.save(user);
}
public List<User> search(String name) {
return userRepository.findByNameContaining(name);
}
}
Summary
- Extend
JpaRepository<Entity, ID>to get all CRUD methods for free - Spring generates the implementation — you only write the interface
- Derived query methods turn method names into SQL automatically
- Use
@Queryfor complex queries that derived names cannot express - Always inject and use the repository through a service class
