Spring Data JPA
Spring Data JPA is de facto standaard voor gegevens toegang in Spring-applicaties, met repository-abtracties, query-methoden en specificaties voor complexe query's. De webforJ SpringDataRepository adapter verbindt Spring Data repositories met de UI-componenten van webforJ, waardoor je JPA-entiteiten direct aan UI-componenten kunt binden, dynamische filtering met JPA-specificaties kunt implementeren en paginering kunt afhandelen.
De adapter detecteert welke Spring Data interfaces jouw repository implementeert - of het nu CrudRepository, PagingAndSortingRepository of JpaSpecificationExecutor is - en biedt automatisch de bijbehorende functies in jouw UI. Dit betekent dat jouw bestaande Spring Data repositories werken met webforJ-componenten zonder modificatie, terwijl typeveiligheid behouden blijft en jouw bestaande domeinmodel wordt gebruikt.
Voor een uitgebreide uitleg over de functies en querymethoden van Spring Data JPA, zie Spring Data JPA documentatie.
Gebruik van SpringDataRepository
De SpringDataRepository klasse verbindt Spring Data JPA repositories met de Repository-interface van webforJ, waardoor ze compatibel zijn met UI-componenten zoals Table terwijl alle Spring Data-functies behouden blijven.
// Jouw Spring Data repository
@Autowired
private PersonRepository personRepository;
// Verpak het met SpringDataRepository
SpringDataRepository<Person, Long> adapter = new SpringDataRepository<>(personRepository);
// Gebruik met webforJ Table
Table<Person> table = new Table<>();
table.setRepository(adapter);
Interface-detectie
Spring Data repositories gebruiken interface-erfelijkheid om mogelijkheden toe te voegen. Je begint met basis CRUD-operaties en voegt interfaces toe voor functies zoals paginering of specificaties:
// Basis CRUD alleen
public interface CustomerRepository extends CrudRepository<Customer, Long> {}
// CRUD + Paginering + Sorteren
public interface CustomerRepository extends PagingAndSortingRepository<Customer, Long> {}
// Volledig uitgeruste repository
public interface CustomerRepository extends JpaRepository<Customer, Long>, JpaSpecificationExecutor<Customer> {}
SpringDataRepository onderzoekt welke interfaces jouw repository implementeert en past zijn gedrag dienovereenkomstig aan. Als jouw repository paginering ondersteunt, stelt de adapter gepagineerde query's in. Als het JpaSpecificationExecutor implementeert, kun je dynamische filtering gebruiken met specificaties.
Repository-capaciteiten
Elke Spring Data interface voegt specifieke mogelijkheden toe die SpringDataRepository kan gebruiken:
- CrudRepository - Basisoperaties:
save,delete,findById,findAll - PagingAndSortingRepository - Voegt gepagineerde query's en sorteren toe
- JpaRepository - Combineert CRUD en paging/sorteren met batchoperaties
- JpaSpecificationExecutor - Dynamische query's met behulp van JPA-specificaties
Een Spring Data repository maken
Voor maximale compatibiliteit met webforJ-componenten, maak repositories die zowel JpaRepository als JpaSpecificationExecutor implementeren:
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
@Repository
public interface PersonRepository
extends JpaRepository<Person, Long>,
JpaSpecificationExecutor<Person> {
// Aangepaste query methoden kunnen hier komen
}
Deze combinatie biedt:
- Vind-berichten per ID
- Paginering met optimale prestaties
- Sorteermogelijkheden
- Java Persistence API Specificatie filtering
- Telt operaties met en zonder filters
Werken met Table
Het volgende voorbeeld gebruikt een PersonRepository die JpaRepository en JpaSpecificationExecutor uitbreidt. Deze combinatie maakt sorteren door kolomkoppen en dynamische filtering met specificaties mogelijk.
@Route
public class TableView extends Composite<Div> {
private SpringDataRepository<Person, Long> repository;
private Table<Person> table = new Table<>();
public TableView(PersonRepository personRepository) {
// Verpak Spring Data repository voor webforJ
repository = new SpringDataRepository<>(personRepository);
// Verbinding maken met de tabel
table.setRepository(repository);
// Definieer kolommen
table.addColumn("name", Person::getFullName)
.setPropertyName("firstName"); // Sorteer op actuele JPA-eigenschap
table.addColumn("email", Person::getEmail);
table.addColumn("age", person ->
person.getAge() != null ? person.getAge().toString() : "");
table.addColumn("city", Person::getCity);
table.addColumn("profession", Person::getProfession);
// Sorteermogelijkheden inschakelen
table.getColumns().forEach(column -> column.setSortable(true));
}
}
De setPropertyName() methode is belangrijk voor sorteren - het vertelt de adapter welke JPA-eigenschap te gebruiken in de ORDER BY clausule bij het sorteren op die kolom. Zonder deze zal sorteren niet werken voor berekende eigenschappen zoals getFullName().
Filteren met JPA-specificaties
SpringDataRepository maakt gebruik van JPA-specificaties voor dynamische query's en deze worden toegepast op de repository findBy en count operaties.
Om te begrijpen hoe filteren werkt met webforJ repositories, inclusief basisfilters en filtercompositie, zie de Repository documentatie.
// Filteren op stad
Specification<Person> cityFilter = (root, query, cb) ->
cb.equal(root.get("city"), "New York");
repository.setFilter(cityFilter);
// Meerdere voorwaarden
Specification<Person> complexFilter = (root, query, cb) ->
cb.and(
cb.equal(root.get("profession"), "Engineer"),
cb.greaterThanOrEqualTo(root.get("age"), 25)
);
repository.setFilter(complexFilter);
// Filter wissen
repository.setFilter(null);