Spring Data
Spring Data helps you access and manipulate data in databases without writing tons of code.
Key Features:
- Repository Abstraction: You define an interface, and Spring Data auto-generates the implementation.
- Query Methods: Write queries by just naming your methods (like findByUsername()).
- Support for Many Data Stores:
- Relational (JPA/Hibernate, JDBC)
- NoSQL (MongoDB, Neo4j, Redis, Cassandra, etc.)
- Pagination and Sorting
- Custom Queries using JPQL, native SQL, or annotations
Repository
Data Access Object level. Interface remains constant independent of the DB behind it.
Repository (Marker-Interface) -> CRUDRepository -> PagingAndSortingRepository
Derived Queries
Queries generated by Spring Data based on the signature.
Methods only need to be defined in the interface. No implementation is required.
Examples
- findByFirstNameAndLastName(String name, String lastname) -> And queries
- findByFirstNameOrderByCreated(String name) -> Ordering
- deleteByName(String name) -> Deletion
- findByAgeGreaterThan -> Less than, greater than, etc
- CountBy -> Results as long
- readBy
- getBy
- queryBy
- findFirst -> returns first entry
AND-OR
Any And, Or Keywords
findByFirstNameAndLastName
EQUALS-IS-NOT
List<Session> findBySessionLengthNot(Integer length);
LIKE- NOT LIKE
Placeholder: %
List<Session> findBySessionNameNotLike(String name);
STARTING/ENDING WITH – CONTAINING
List<Session> findBySessionNameStartingWith(String name);
LESS THAN – GREATER THAN
List<Session> findBySessionLengthLessThan(Integer length);
BEFORE – AFTER – BETWEEN
For Date/Time-Queries
TRUE – FALSE
For boolean fields
List<TicketType> findByIncludesWorkshopTrue();
NULL – NOT NULL
Null, isNull, notNull, isNotNull
List <Speaker> findBySpeakerPhotoNull();
IN – NOT IN
...in(Collection<Daten>)
List <Speaker> findByCompanyIn(List<String> companies);
IGNORE CASE
List<Speaker> findCompanyIgnoreCase(String company);
ORDER BY
List<Speaker> findByLastNameOrderByFirstNameAsc(String lastName);
FIRST – TOP – DISTINCT
findTop5ByFirstName
Paging and Sorting
Iterable<T> findAll(Sort sort);
Page<T> findAll(Pageable pageable);
Or add paging and sorting as parameters to the derived queries.
final Page<Flight> page=flightRepository.findByOrigin("London",PageRequest.of(0,5,Sort.by(Sort.Order.desc("destination"))));
or
@Query("select * from Session s where s.sessionName like %:name")
Page<Session> getSessionWithName(@Param("name") String name, Pageable page);
Custom Module
Extend the repository with custom implementation
- Create a new interface
- Implement the interface
- Existing interface now also extends the CustomRepository interface
public interface DeleteByOriginRepository {
void deleteByOrigin(String origin);
}
public class DeleteByOriginRepositoryImpl implements DeleteByOriginRepository{
private final EntityManager entityManager;
public DeleteByOriginRepositoryImpl(EntityManager entityManager){
this.entityManager=entityManager;
}
@Override
public void deleteByOrigin(String origin) {
entityManager.createNativeQuery("DELETE from flight where origin =?").setParameter(1, origin).executeUpdate();
}
}
Extend existing repository with new functionality
public interface FlightRepository extends PagingAndSortingRepository<Flight, Long>, DeleteByOriginRepository{
List<Flight> findByOrigin(String london);
List<Flight> findByOriginAndDestination(String london, String paris);
List<Flight> findByOriginIn(String ... origins);
List<Flight> findByOriginIgnoreCase(String origin);
Page<Flight> findByOrigin(String origin, Pageable pageRequest);
}
Transactions
@Transactional
– Annotation to work within a transaction. Reduces boilerplate code, more stable, DB independent…
Tests
Annotate with @SpringBootTest
Spring Data JPA
• Extends JPA • Simplifies the data layer • JpaRepositories • Query DSL • Data tier (sorting, paging, etc.) • Optional. Can easily be bypassed if necessary
Configuration
Pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- Dependency for Postgres JDBC driver -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
Application.properties
spring.datasource.url=jdbc:postgresql:conference_app
spring.datasource.username=
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=none
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
spring.jpa.show-sql=true
Repository
public interface SpeakerJpaRepository extends JpaRepository<Speaker,Long> {
}
Query-Annotation
For custom queries. Add method with @Query annotation to repository.
@Query("Select tp from TicketPrice tp where tp.basePrice < ?1 "+
"and tp.ticketType.includesWorkshop = true"
)
List<TicketPrice> getTicketsUnderPriceWithWorkshops(BigDecimal maxPrice);
?1 First parameter is replaced with parameter of the method.
Named Parameter
Instead of numbered parameters, parameter names can be used.
@Query("Select tp from TicketPrice tp where tp.basePrice < :maxprice "+
"and tp.ticketType.includesWorkshop = true"
)
List<TicketPrice> getTicketsUnderPriceWithWorkshops(@Param(“maxprice”) BigDecimal maxPrice);
Enhanced JPQL Syntax
“… where s.sessionName like %?1” Platzhalter ‘%’ kann hinzugefügt werden
Native SQL Query
@Query(value=“select \* from sessions s where s.session_name= ?0”, nativeQuery = true)
List<Session> getSessionsWithName(String name);
Modifiable Queries
@Modifying
@Query("update Session s set s.sessionName = ?1")
int updateSessionName(String name);
NamedQueries
Named Queries are predefined JPQL (Java Persistence Query Language) queries and are validated at the start of the app They are located on the entity, repository or as named attribute by the query annotation
@Entity
@NamedQuery(
name = "User.findByEmail",
query = "SELECT u FROM User u WHERE u.email = :email"
)
public class User
NamedNativeQuery
@Entity
@NamedNativeQuery(
name = "User.findByEmail",
query = "SELECT * FROM users WHERE email = ?",
resultClass = User.class
)
public class User
Query priority
- @Query-Annotation
- Named/NativeNamed-Queries
- Query-DSL Naming
Auditing
Annotation of entity properties
@CreatedBy
@LastModifiedBy
@CreatedDate
(automatically defined)@LastModifiedDate
(automatically defined)
Locking
@Version-Annotation in Entity
@Version
private int version
@Lock(LockModeType.PESSIMISIC_WRITE)
List<Model> findByAttributeName(String name)