Spring Data JPA là abstraction trên JPA — chỉ cần khai báo interface, Spring sinh implementation tự động.
@Entity
class User { @Id Long id; String email; }
public interface UserRepository extends JpaRepository<User, Long> {
// Có sẵn: save, findById, findAll, delete, count, exists...
// Query Methods — Spring derive từ tên method
Optional<User> findByEmail(String email);
List<User> findByAgeGreaterThan(int age);
long countByActiveTrue();
// @Query — JPQL hoặc native SQL
@Query("SELECT u FROM User u WHERE u.email = :email")
Optional<User> lookup(@Param("email") String email);
@Modifying
@Query("UPDATE User u SET u.active = false WHERE u.id = :id")
int deactivate(@Param("id") Long id);
}@Repository annotation:
- Đánh dấu data access component.
- Tự translate exception DB (SQLException) → Spring DataAccessException (unchecked, consistent across DB).
- JpaRepository đã có sẵn @Repository ngầm — không cần thêm.
Pagination/Sorting:
Page<User> findByActive(boolean active, Pageable page);
// Caller: userRepo.findByActive(true, PageRequest.of(0, 20, Sort.by("name")));Lợi ích: minimal code, type-safe query, transaction tự động qua @Transactional.
Spring Data JPA is an abstraction over JPA — just declare an interface and Spring generates the implementation.
@Entity
class User { @Id Long id; String email; }
public interface UserRepository extends JpaRepository<User, Long> {
// Provided: save, findById, findAll, delete, count, exists...
// Query methods — Spring derives queries from method names
Optional<User> findByEmail(String email);
List<User> findByAgeGreaterThan(int age);
long countByActiveTrue();
// @Query — JPQL or native SQL
@Query("SELECT u FROM User u WHERE u.email = :email")
Optional<User> lookup(@Param("email") String email);
@Modifying
@Query("UPDATE User u SET u.active = false WHERE u.id = :id")
int deactivate(@Param("id") Long id);
}@Repository annotation:
- Marks the data-access component.
- Auto translates DB exceptions (SQLException) → Spring DataAccessException (unchecked, consistent across DBs).
- JpaRepository already includes @Repository implicitly — no need to add it.
Pagination/Sorting:
Page<User> findByActive(boolean active, Pageable page);
// Caller: userRepo.findByActive(true, PageRequest.of(0, 20, Sort.by("name")));Benefits: minimal code, type-safe queries, transactions handled automatically via @Transactional.