Methods to interact with Database
flowchart LR
SDJPA["Spring Data JPA"]
Methods --> JPA
Methods --> Hibernate
Methods --> SDJPA
JPA --> JPQL
JPA --> EntityManager
JPA --> Criteria
Hibernate --> HQL
Hibernate --> Session
SDJPA --> Repository
SDJPA --> Specification
SDJPA --> QueryDsl
JPA
- Jakarta Persistence API (formerly Java Persistence API)
- In 2019 renamed to Jakarta Persistence
- Refer Java History
EntityManager
jakarta.persistence.EntityManager
public interface EntityManager extends AutoCloseable {}
- JPA interface used to interact with the persistence context
- Low-level, versatile, but verbose and less type-safe
- provides methods to create and execute queries using”
List<User> users = entityManager.createNativeQuery("SELECT * FROM User", User.class).getResultList();
JPQL
org.springframework.data.jpa.repository.Query
- Java Persistence Query Language
- We use
@Query
- For native queries we use
@Query("...", native=true)
- Can be executed using:
- EntityManager
@NamedQuery
- Spring Data JPA Repository
@Query
Criteria
jakarta.persistence.criteria.CriteriaQuery
- Part of JPA
- nice clean object oriented API
- Can detect errors in compile time
- JPQL and Criteria have same efficiency and performance
- Criteria is more flexible and provide better support for writing dynamic queries as compared to HQL and JPQL
- Disadvantage: Criteria does not support native queries
CriteriaBuilder is used to build CriteriaQuery objects
Predicate is used to construct clauses which can be used in CriteriaQuery#where
Hibernate
Session
public interface Session extends SharedSessionContract, EntityManager {}
- It is specific to Hibernate
- It extends
EntityManager
- EntityManager will invoke Session behind the hood if implementation is hibernate
HQL
org.hibernate.annotations.NamedQuery
- Hibernate Query Language
- We use
@NamedQuery
- For native queries we use
@NamedNativeQuery
- Disadvantage:
- Hibernate specific
- code’s unreadability
- Can be executed using:
- Session.createQuery or EntityManager
@NamedQuery
Spring Data JPA
Repository
- https://docs.spring.io/spring-data/jpa/reference/repositories/definition.html
- Interfaces:
JpaRepositry — CRUD + pagination + sorting + flush persistence/delete record in batch etc., returns List<>
PagingAndSortingRepository — CRUD + pagination + sorting
CrudRepository — Supports only CRUD, returns Iterable<>
ListCrudRepository — returns List<>
ReactiveCrudRepository — Flux Mono
RxJava3CrudRepository — RxJava
Specification
public interface Specification<T> extends Serializable {}
- It is an Interface which is part of Spring Data JPA
- while Criteria is part of JPA
- It is based on Domain Driven Design book by Eric Evans
- It is developed to define reusable Predicate and use Criteria API in type-safe way
- Disadvantage: Specification does not support native queries
- You need to have
JpaSpecificationExecutor on your repository
interface CustomerRepository extends JpaRepository<Customer>, JpaSpecificationExecutor {
// Your query methods here
}
public CustomerSpecifications {
public static Specification<Customer> customerHasBirthday() {
return new Specification<Customer> {
public Predicate toPredicate(Root<T> root, CriteriaQuery query, CriteriaBuilder cb) {
return cb.equal(root.get(Customer_.birthday), today);
}
};
}
}
customerRepository.findAll(hasBirthday());
Querydsl
interface CustomerRepository extends JpaRepository<Customer>, QueryDslPredicateExecutor {
// Your query methods here
}
BooleanExpression customerHasBirthday = customer.birthday.eq(today);
BooleanExpression isLongTermCustomer = customer.createdAt.lt(today.minusYears(2));
customerRepository.findAll(customerHasBirthday.and(isLongTermCustomer));