Repository 24.00
Het Repository
-patroon in webforJ biedt een gestandaardiseerde manier om collecties van entiteiten te beheren en te raadplegen. Het fungeert als een abstractielaag tussen je UI-componenten en gegevens, waardoor het eenvoudig is om met verschillende gegevensbronnen te werken terwijl je een consistente gedraging behoudt.
Waarom een repository gebruiken
Repository
voorkomt handmatige updates en behoudt je originele gegevens intact:
// Zonder Repository - handmatige updates
List<Customer> customers = loadCustomers();
Table<Customer> table = new Table<>();
table.setItems(customers);
// Toevoegen vereist volledige herlaad
customers.add(newCustomer);
table.setItems(customers); // Alles moet opnieuw worden geladen
// Met Repository - automatische synchronisatie
List<Customer> customers = loadCustomers();
CollectionRepository<Customer> repository = new CollectionRepository<>(customers);
Table<Customer> table = new Table<>();
table.setRepository(repository);
// Toevoegen synchroniseert automatisch
customers.add(newCustomer);
repository.commit(newCustomer); // Alleen wat is veranderd wordt bijgewerkt
Collectie repository
De CollectionRepository
is de meest voorkomende implementatie en wikkelt elke Java-collectie:
// Van ArrayList
List<Customer> customers = new ArrayList<>();
CollectionRepository<Customer> customerRepo = new CollectionRepository<>(customers);
// Van HashSet
Set<String> tags = new HashSet<>();
CollectionRepository<String> tagRepo = new CollectionRepository<>(tags);
// Van elke collectie
Collection<Employee> employees = getEmployeesFromHR();
CollectionRepository<Employee> employeeRepo = new CollectionRepository<>(employees);
Gegevenssynchronisatie
De Repository
fungeert als een brug tussen je gegevens en UI-componenten. Wanneer gegevens veranderen, meld je dit aan de repository via de commit()
-methode:
List<Product> products = new ArrayList<>();
CollectionRepository<Product> repository = new CollectionRepository<>(products);
// Nieuwe product toevoegen
Product newProduct = new Product("P4", "Gizmo", 79.99, 15);
products.add(newProduct);
repository.commit(); // Alle verbonden componenten worden bijgewerkt
// Bestaand product bijwerken
products.get(0).setPrice(89.99);
repository.commit(products.get(0)); // Alleen deze specifieke rij wordt bijgewerkt
// Product verwijderen
products.remove(2);
repository.commit(); // Vernieuwt de weergave
De commit-methode heeft twee handtekeningen:
commit()
- Geeft de repository opdracht om alles te vernieuwen. Het activeert eenRepositoryCommitEvent
met alle huidige gegevenscommit(entity)
- Richt zich op een specifieke entiteit. De repository vindt deze entiteit op basis van zijn sleutel en werkt alleen de aangetaste UI-elementen bij
Dit onderscheid is belangrijk voor de prestaties. Wanneer je één veld bijwerkt in een tabel met 1000 rijen, werkt commit(entity)
alleen die cel bij, terwijl commit()
alle rijen vernieuwt.
Gegevens filteren
De filter van de repository controleert welke gegevens naar verbonden componenten stromen. Je onderliggende collectie blijft onveranderd omdat de filter als een lens fungeert:
// Filteren op voorraadbeschikbaarheid
repository.setBaseFilter(product -> product.getStock() > 0);
// Filteren op categorie
repository.setBaseFilter(product -> "Electronics".equals(product.getCategory()));
// Meerdere voorwaarden combineren
repository.setBaseFilter(product ->
product.getCategory().equals("Electronics") &&
product.getStock() > 0 &&
product.getPrice() < 100.0
);
// Filter wissen
repository.setBaseFilter(null);
Wanneer je een filter instelt, doet de Repository
:
- Past de predicate toe op elk item in je collectie
- Maakt een gefilterde stroom van bijpassende items
- Meldt verbonden componenten om hun weergave bij te werken
De filter blijft bestaan totdat je deze verandert. Nieuwe items die aan de collectie worden toegevoegd, worden automatisch getest tegen de huidige filter.
Werken met entiteitssleutels
Wanneer je entiteiten HasEntityKey
implementeren, kan de repository specifieke items vinden en bijwerken op basis van hun ID:
public class Customer implements HasEntityKey {
private String customerId;
private String name;
private String email;
@Override
public Object getEntityKey() {
return customerId;
}
// Constructor en getters/setters...
}
// Vinden op sleutel
Optional<Customer> customer = repository.find("C001");
// Specifieke klant bijwerken
customer.ifPresent(c -> {
c.setEmail("newemail@example.com");
repository.commit(c); // Alleen deze klant rij wordt bijgewerkt
});
Zonder HasEntityKey
:
repository.find("C001")
vindt je klant niet omdat het zoekt naar een object dat gelijk is aan "C001"repository.commit(entity)
werkt nog steeds, maar is afhankelijk van objectgelijkheid- UI-componenten kunnen items niet selecteren op ID, alleen op objectreferentie
UI-integratie
Repository
integreert met gegevensbewuste componenten:
// Repository en tabel maken
List<Customer> customers = new ArrayList<>();
CollectionRepository<Customer> repository = new CollectionRepository<>(customers);
Table<Customer> table = new Table<>();
table.setRepository(repository);
table.addColumn("ID", Customer::getId);
table.addColumn("Naam", Customer::getName);
table.addColumn("Email", Customer::getEmail);
// Gegevens toevoegen - tabel wordt automatisch bijgewerkt
customers.add(new Customer("C001", "Alice Johnson", "alice@example.com"));
repository.commit();
Volgende stappen
📄️ Querying data
De QueryableRepository interface breidt Repository uit met geavanceerd opvragen via RepositoryCriteria. In tegenstelling tot basisrepositories die alleen eenvoudige filtering ondersteunen, bieden opvraagbare repositories gestructureerd opvragen met aangepaste filtertypes, sorteren en paginering.
📄️ Custom data sources
Wanneer je gegevens buiten je app worden opgeslagen - in een REST API, database of externe service - moet je een aangepaste repository-implementatie maken. De DelegatingRepository klasse maakt dit eenvoudig door je in staat te stellen functies aan te bieden in plaats van een volledige klasse te implementeren.
📄️ Events and updates
Repository-evenementen stellen je in staat om te reageren op gegevenswijzigingen. Buiten de automatische UI-updates kun je luisteren naar wijzigingen om aangepaste logica te triggeren.