Overslaan naar hoofdinhoud

Repository 24.00

Openen in ChatGPT

Het Repository-patroon in webforJ biedt een gestandaardiseerde manier om collecties van entiteiten te beheren en op te vragen. Het fungeert als een abstractielaag tussen je UI-componenten en gegevens, waardoor het eenvoudig is om met verschillende gegevensbronnen te werken terwijl je consistent gedrag behoudt.

Waarom een repository gebruiken

Repository elimineert handmatige updates terwijl je originele gegevens intact blijven:

// 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); // Moet alles opnieuw laden
// 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); // Update alleen wat veranderd is

Collectie repository

De CollectionRepository is de meest gebruikelijke implementatie en omhult elke Java Collection:

// 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 Collection
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, stel je de repository op de hoogte 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

// Bestaande product bijwerken
products.get(0).setPrice(89.99);
repository.commit(products.get(0)); // Update alleen deze specifieke rij

// Product verwijderen
products.remove(2);
repository.commit(); // Vernieuwt de weergave

De commit-methode heeft twee handtekeningen:

  • commit() - vertelt de repository om alles te vernieuwen. Het activeert een RepositoryCommitEvent met alle huidige gegevens
  • commit(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
Enkelvoudige entiteiten committen

Deze onderscheiding is belangrijk voor de prestaties. Wanneer je één veld bijwerkt in een tabel met 1000 rijen, werkt commit(entity) alleen dat vakje bij, terwijl commit() alle rijen zou vernieuwen.

Gegevens filteren

De filter van de repository bepaalt welke gegevens naar verbonden componenten stromen. Je onderliggende collectie blijft ongewijzigd omdat de filter als een lens fungeert:

// Filter op voorraadbeschikbaarheid
repository.setBaseFilter(product -> product.getStock() > 0);

// Filter 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:

  1. Past de predicate toe op elk item in je collectie
  2. Maakt een gefilterde stroom van overeenkomende items
  3. Stelt verbonden componenten in kennis 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 entiteit-sleutels

De repository moet entiteiten uniek kunnen identificeren om bewerkingen zoals find() en commit(entity) te ondersteunen. Er zijn twee manieren om te definiëren hoe entiteiten worden geïdentificeerd:

Gebruik van het HasEntityKey-interface

Implementeer HasEntityKey in je entiteitsklasse:

public class Customer implements HasEntityKey {
private String customerId;
private String name;
private String email;

@Override
public Object getEntityKey() {
return customerId;
}

// Constructor en getters/setters...
}

// Vind 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's rij wordt bijgewerkt
});

Gebruik van aangepaste sleutelprovider 25.10

Voor entiteiten waarbij je HasEntityKey niet kunt of wilt implementeren (zoals JPA-entiteiten), gebruik setKeyProvider():

@Entity
public class Product {
@Id
private Long id;
private String name;
private double price;

// JPA-beheerde entiteit
}

// Configureer repository om de getId() methode te gebruiken
CollectionRepository<Product> repository = new CollectionRepository<>(products);
repository.setKeyProvider(Product::getId);

// Nu werkt vinden met de ID
Optional<Product> product = repository.find(123L);

Een aanpak kiezen

Beide benaderingen werken, maar setKeyProvider() heeft de voorkeur wanneer:

  • Je werkt met JPA-entiteiten die @Id velden hebben
  • Je de entiteitsklasse niet kunt aanpassen
  • Je verschillende sleutelstrategieën nodig hebt voor verschillende repositories

Gebruik HasEntityKey wanneer:

  • Je de entiteitsklasse beheert
  • De logica voor sleutelextractie complex is
  • Je wilt dat de entiteit zijn eigen identiteit definieert

UI-integratie

Repository integreert met gegevensbewuste componenten:

// Maak repository en tabel
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("E-mail", Customer::getEmail);

// Voeg gegevens toe - tabel wordt automatisch bijgewerkt
customers.add(new Customer("C001", "Alice Johnson", "alice@example.com"));
repository.commit();

Volgende stappen