Zum Hauptinhalt wechseln

Repository 24.00

ChatGPT öffnen

Das Repository-Muster in webforJ bietet eine standardisierte Möglichkeit, Sammlungen von Entitäten zu verwalten und abzufragen. Es dient als Abstraktionsschicht zwischen Ihren UI-Komponenten und den Daten, wodurch es einfach wird, mit verschiedenen Datenquellen zu arbeiten, während ein konsistentes Verhalten aufrechterhalten wird.

Warum ein Repository verwenden

Repository beseitigt manuelle Aktualisierungen, während Ihre ursprünglichen Daten intakt bleiben:

// Ohne Repository - manuelle Updates
List<Customer> customers = loadCustomers();
Table<Customer> table = new Table<>();
table.setItems(customers);

// Hinzufügen erfordert vollständiges Neuladen
customers.add(newCustomer);
table.setItems(customers); // Muss alles neu laden
// Mit Repository - automatische Synchronisation
List<Customer> customers = loadCustomers();
CollectionRepository<Customer> repository = new CollectionRepository<>(customers);
Table<Customer> table = new Table<>();
table.setRepository(repository);

// Hinzufügen synchronisiert automatisch
customers.add(newCustomer);
repository.commit(newCustomer); // Aktualisiert nur, was sich geändert hat

Sammlung-Repository

Die CollectionRepository ist die häufigste Implementierung und umschließt jede Java-Sammlung:

// Von ArrayList
List<Customer> customers = new ArrayList<>();
CollectionRepository<Customer> customerRepo = new CollectionRepository<>(customers);

// Von HashSet
Set<String> tags = new HashSet<>();
CollectionRepository<String> tagRepo = new CollectionRepository<>(tags);

// Von jeder Sammlung
Collection<Employee> employees = getEmployeesFromHR();
CollectionRepository<Employee> employeeRepo = new CollectionRepository<>(employees);

Daten-Synchronisation

Das Repository fungiert als Brücke zwischen Ihren Daten und den UI-Komponenten. Wenn sich die Daten ändern, benachrichtigen Sie das Repository über die commit()-Methode:

List<Product> products = new ArrayList<>();
CollectionRepository<Product> repository = new CollectionRepository<>(products);

// Neues Produkt hinzufügen
Product newProduct = new Product("P4", "Gizmo", 79.99, 15);
products.add(newProduct);
repository.commit(); // Alle verbundenen Komponenten aktualisieren sich

// Vorhandenes Produkt aktualisieren
products.get(0).setPrice(89.99);
repository.commit(products.get(0)); // Aktualisiert nur diese spezielle Zeile

// Produkt entfernen
products.remove(2);
repository.commit(); // Aktualisiert die Ansicht

Die commit-Methode hat zwei Signaturen:

  • commit() - Sagt dem Repository, dass alles aktualisiert werden soll. Es löst ein RepositoryCommitEvent mit allen aktuellen Daten aus
  • commit(entity) - Zielt auf eine spezifische Entität ab. Das Repository findet diese Entität anhand ihres Schlüssels und aktualisiert nur die betroffenen UI-Elemente
Einzelne Entitäten committen

Dieser Unterschied ist wichtig für die Leistung. Wenn Sie ein Feld in einer 1000-Zeilen-Tabelle aktualisieren, aktualisiert commit(entity) nur diese Zelle, während commit() alle Zeilen neu laden würde.

Daten filtern

Der Filter des Repositories steuert, welche Daten an verbundene Komponenten fließen. Ihre zugrunde liegende Sammlung bleibt unverändert, da der Filter wie eine Linse fungiert:

// Nach Verfügbarkeit auf Lager filtern
repository.setBaseFilter(product -> product.getStock() > 0);

// Nach Kategorie filtern
repository.setBaseFilter(product -> "Electronics".equals(product.getCategory()));

// Mehrere Bedingungen kombinieren
repository.setBaseFilter(product ->
product.getCategory().equals("Electronics") &&
product.getStock() > 0 &&
product.getPrice() < 100.0
);

// Filter löschen
repository.setBaseFilter(null);

Wenn Sie einen Filter setzen, führt das Repository:

  1. Wendet das Prädikat auf jedes Element in Ihrer Sammlung an
  2. Erstellt einen gefilterten Stream übereinstimmender Elemente
  3. Benachrichtigt verbundene Komponenten, ihre Anzeige zu aktualisieren

Der Filter bleibt bestehen, bis Sie ihn ändern. Neue Elemente, die zur Sammlung hinzugefügt werden, werden automatisch gegen den aktuellen Filter getestet.

Arbeiten mit Entitätsschlüsseln

Wenn Ihre Entitäten HasEntityKey implementieren, kann das Repository spezifische Elemente anhand ihrer ID finden und aktualisieren:

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

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

// Konstruktor und Getter/Setter...
}

// Nach Schlüssel suchen
Optional<Customer> customer = repository.find("C001");

// Bestimmten Kunden aktualisieren
customer.ifPresent(c -> {
c.setEmail("newemail@example.com");
repository.commit(c); // Nur diese Zeile des Kunden wird aktualisiert
});

Ohne HasEntityKey:

  • repository.find("C001") findet Ihren Kunden nicht, da es nach einem Objekt sucht, das "C001" entspricht
  • repository.commit(entity) funktioniert weiterhin, basiert jedoch auf der Objektgleichheit
  • UI-Komponenten können Elemente nicht nach ID, sondern nur nach Objektreferenz auswählen

UI-Integration

Repository integriert sich mit datenbewussten Komponenten:

// Repository und Tabelle erstellen
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("Name", Customer::getName);
table.addColumn("Email", Customer::getEmail);

// Daten hinzufügen - Tabelle aktualisiert sich automatisch
customers.add(new Customer("C001", "Alice Johnson", "alice@example.com"));
repository.commit();

Nächste Schritte