J'ai une application Java qui utilise JPA.Comment gérer au mieux la liste <Entity>, la liste <Entity Id>, la liste <Entity name> efficacement?
Dire que j'ai une entité appelée Product
avec name
et price
attributs (toutes entités ont un attribut id
).
Naturellement je peux obtenir un List<Product>
assez facilement (d'une requête ou d'une autre entité), mais souvent je veux une List<String>
(liste des noms de produits) ou List<Long>
(liste des prix des produits ou liste des ids de produits).
Beaucoup de temps, il est tout aussi facile de passer toute Product
autour, mais il y a deux cas où je ne veux pas faire:
- Je passe la liste à une classe qui ne devrait pas dépendre de la classe
Product
. - Il est nettement plus facile/plus rapide d'obtenir une liste d'identifiants que des objets de produit complets (mais dans certains cas je les ai déjà).
La façon naïve de faire cela irait quelque chose comme:
List<Long> productIds = new ArrayList<Long>();
for(Product product: products) {
productIds.add(product.getId());
}
Mais je ne l'aime pas parce qu'il est désordonné et inefficace. En python je ferais quelque chose comme:
[ p.id for p in products ]
Le "meilleur" que je peux venir avec en Java est:
public class ProductIdList extends AbstractList<Long> {
private List<Product> data;
public ProductIdList(List<Product> data) {
this.data = data;
}
public Long get(int i) {
return data.get(i).getId();
}
public int size() {
return data.size();
}
public Long remove(int i) {
return data.remove(i).getId();
}
/* For better performance */
public void clear() {
data.clear();
}
/* Other operations unsupported */
}
Plus:
- Cette approche n'a pas besoin de copier les données
- Il s'agit d'une véritable "vue" sur les données - les modifications apportées à la liste sous-jacente sont reflétées.
Moins:
- On dirait que beaucoup de code
- Besoin d'une classe comme ceci pour chaque attribut Je veux accéder comme ça
Alors est-ce un bon idée ou pas? Devrais-je simplement créer des listes secondaires la plupart du temps? Y a-t-il une troisième option que je n'ai pas envisagée?
Mettre un commentaire non une réponse. Juste un petit conseil, vous pouvez toujours aller chercher les identifiants de produits seulement, pas tout le produit (en utilisant ce que j'ai entendu s'appeler une requête scalaire). Par exemple. SELECT prod.id FROM Product prod ... –
Exactement. Peut-être aurais-je dû être plus clair. Parfois, je peux faire exactement cela, et il n'y a pas de problème. Parfois, j'ai déjà une liste et je ne veux pas de requery. –
Draemon
Vous pouvez utiliser une classe qui a une méthode pour chaque attribut. Cela réduirait un CONS au moins. – StampedeXV