Repository 24.00
Le modèle Repository
dans webforJ fournit un moyen standardisé de gérer et d'interroger des collections d'entités. Il agit comme une couche d'abstraction entre vos composants d'interface utilisateur et les données, facilitant ainsi le travail avec différentes sources de données tout en maintenant un comportement cohérent.
Pourquoi utiliser un repository
Repository
élimine les mises à jour manuelles tout en gardant vos données d'origine intactes :
// Sans Repository - mises à jour manuelles
List<Customer> customers = loadCustomers();
Table<Customer> table = new Table<>();
table.setItems(customers);
// L'ajout nécessite un rechargement complet
customers.add(newCustomer);
table.setItems(customers); // Doit tout recharger
// Avec Repository - synchronisation automatique
List<Customer> customers = loadCustomers();
CollectionRepository<Customer> repository = new CollectionRepository<>(customers);
Table<Customer> table = new Table<>();
table.setRepository(repository);
// L'ajout se synchronise automatiquement
customers.add(newCustomer);
repository.commit(newCustomer); // Ne met à jour que ce qui a changé
Repository de collection
Le CollectionRepository
est l'implémentation la plus courante et enveloppe n'importe quelle Collection Java :
// Depuis ArrayList
List<Customer> customers = new ArrayList<>();
CollectionRepository<Customer> customerRepo = new CollectionRepository<>(customers);
// Depuis HashSet
Set<String> tags = new HashSet<>();
CollectionRepository<String> tagRepo = new CollectionRepository<>(tags);
// Depuis n'importe quelle Collection
Collection<Employee> employees = getEmployeesFromHR();
CollectionRepository<Employee> employeeRepo = new CollectionRepository<>(employees);
Synchronisation des données
Le Repository
agit comme un pont entre vos données et les composants d'interface utilisateur. Lorsque les données changent, vous informez le repository par la méthode commit()
:
List<Product> products = new ArrayList<>();
CollectionRepository<Product> repository = new CollectionRepository<>(products);
// Ajouter un nouveau produit
Product newProduct = new Product("P4", "Gizmo", 79.99, 15);
products.add(newProduct);
repository.commit(); // Tous les composants connectés se mettent à jour
// Mettre à jour un produit existant
products.get(0).setPrice(89.99);
repository.commit(products.get(0)); // Ne met à jour que cette ligne spécifique
// Supprimer un produit
products.remove(2);
repository.commit(); // Actualise la vue
La méthode commit a deux signatures :
commit()
- Indique au repository de tout rafraîchir. Elle déclenche unRepositoryCommitEvent
avec toutes les données actuellescommit(entity)
- Cible une entité spécifique. Le repository trouve cette entité par sa clé et met à jour uniquement les éléments d'UI affectés
Cette distinction est importante pour les performances. Lorsque vous mettez à jour un champ dans un tableau de 1000 lignes, commit(entity)
met à jour juste cette cellule tandis que commit()
rafraîchirait toutes les lignes.
Filtrage des données
Le filtre du repository contrôle quelles données circulent vers les composants connectés. Votre collection sous-jacente reste inchangée car le filtre agit comme une lentille :
// Filtrer par disponibilité en stock
repository.setBaseFilter(product -> product.getStock() > 0);
// Filtrer par catégorie
repository.setBaseFilter(product -> "Électronique".equals(product.getCategory()));
// Combiner plusieurs conditions
repository.setBaseFilter(product ->
product.getCategory().equals("Électronique") &&
product.getStock() > 0 &&
product.getPrice() < 100.0
);
// Effacer le filtre
repository.setBaseFilter(null);
Lorsque vous définissez un filtre, le Repository
:
- Applique le prédicat à chaque élément de votre collection
- Crée un flux filtré d'éléments correspondants
- Notifie les composants connectés pour mettre à jour leur affichage
Le filtre persiste jusqu'à ce que vous le changiez. Les nouveaux éléments ajoutés à la collection sont automatiquement testés par rapport au filtre actuel.
Travail avec les clés d'entité
Lorsque vos entités implémentent HasEntityKey
, le repository peut trouver et mettre à jour des éléments spécifiques par leur ID :
public class Customer implements HasEntityKey {
private String customerId;
private String name;
private String email;
@Override
public Object getEntityKey() {
return customerId;
}
// Constructeur et getters/setters...
}
// Trouver par clé
Optional<Customer> customer = repository.find("C001");
// Mettre à jour un client spécifique
customer.ifPresent(c -> {
c.setEmail("newemail@example.com");
repository.commit(c); // Seule la ligne de ce client se met à jour
});
Sans HasEntityKey
:
repository.find("C001")
ne trouvera pas votre client car il recherche un objet qui est égal à "C001"repository.commit(entity)
fonctionne toujours, mais repose sur l'égalité des objets- Les composants d'UI ne peuvent pas sélectionner des éléments par ID, seulement par référence d'objet
Intégration UI
Repository
s'intègre avec des composants sensibles aux données :
// Créer le repository et la table
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("Nom", Customer::getName);
table.addColumn("Email", Customer::getEmail);
// Ajouter des données - la table se met à jour automatiquement
customers.add(new Customer("C001", "Alice Johnson", "alice@example.com"));
repository.commit();
Étapes suivantes
📄️ Querying data
L'interface QueryableRepository étend Repository avec des requêtes avancées via RepositoryCriteria. Contrairement aux dépôts de base qui ne prennent en charge que le filtrage simple, les dépôts interrogeables offrent une requête structurée avec des types de filtres personnalisés, un tri et une pagination.
📄️ Custom data sources
Lorsque vos données vivent en dehors de votre application - dans une API REST, une base de données ou un service externe - vous devez créer une implémentation de référentiel personnalisé. La classe DelegatingRepository simplifie cela en vous permettant de fournir des fonctions au lieu d'implémenter une classe complète.
📄️ Events and updates
Les événements du Repository vous permettent de réagir aux changements de données. Au-delà des mises à jour automatiques de l'interface utilisateur, vous pouvez écouter les changements pour déclencher une logique personnalisée.