Imaginons que nous ayons un composant personnalisé similaire à un petit magasin, qui contient de nombreux produits. La base de données est très relationnelle. Nous souhaitons maintenant afficher la liste de tous les produits de notre boutique en utilisant la méthode du modèle écrasé getListQuery()
. Nous avons là une requête avec plusieurs jointures. Dans view.html.php
, Nous récupérons tous les éléments par $this->get('items')
et tout est prêt pour la présentation des données. C'est l'option n ° 1.
J'ai l'idée de le rendre plus orienté objet. Cela signifie que getListQuery()
n'utilise aucune relation pour obtenir des données supplémentaires décrivant le produit. Il n'obtient que les PK et les colonnes de la table products. Nous écrasons maintenant la fonction getItems()
du modèle.
public function getItems() {
$items = parent::getItems();
for($i=0;$i<count($items);++$i){
$Product = JTable::getInstance('Product');
$Product->bind($items[$i]);
$items[$i] = $Product;
}
return $items;
}
Désormais, chaque élément est une instance de OurComponentTableProduct. Cette table contient des getters pour obtenir les données de produit qui se trouvent dans une autre table. Directement en vue, nous utilisons des accesseurs pour certaines données, par exemple getName()
ou getCategory()
. Ceci est ma 2ème option.
Comme vous pouvez le constater, la deuxième option est similaire à Entity ou Java DAO (je pense que oui). Dans ce cas, notre entité est la classe Table. De plus, je la trouve plus élastique et élégante. Je vois Par exemple, les prix des produits sont situés dans une autre table que les données primaires des produits et ces relations ont une relation product_id-product_id. En utilisant la première option, nous pouvons simplement associer une table à des prix et sélectionner une colonne. nous écrivons la méthode getPrice
qui crée une requête et récupère le prix.
Bien sûr, nous avons vue avec les détails du produit. Ici, nous pouvons à nouveau écrire une énorme requête pour récupérer ce produit (règle DRY), mais nous pouvons également utiliser notre OurComponentTableProduct
. Il suffit de charger par PK et c'est tout.
Les performances sont très importantes pour moi, car je ne fais que développer de gros composants avec un grand nombre de lignes dans la base de données: des centaines de milliers dans chaque table relationnelle.
Selon vous, quelle est la meilleure solution et pourquoi?
Je vous suggère d'utiliser des versions mixtes des deux cas.
Les infrastructures Java DAO, telles que Hibernate et l'API de base de données Joomla, sont deux approches totalement différentes. Les requêtes de base de données Joomla (avec modèle) sont conçues pour fonctionner avec une requête unique. Si vous souhaitez utiliser plusieurs fonctions pour différentes tables, vous rencontrez peu de problèmes.
Joomla Model est conçu pour obtenir une requête unique et extraire le résultat. c'est-à-dire que la requête est liée à votre modèle. Si vous souhaitez utiliser deux méthodes différentes, telles que getProduct et getPrice, vous devez écrire votre propre implémentation de requête d'extraction pour les deux méthodes. Vous finirez donc par ajouter un modèle distinct pour chaque jeu de données.
Vous allez redéfinir JModelList pour extraire la liste des produits. Ainsi, vos autres objets tels que la pagination, les filtres, les données de formulaire sont tous liés à votre modèle. Encore une fois, vous devez effectuer des opérations manuelles pour tout au lieu d'utiliser simplement les méthodes parent définies dans JModelList.
Performances - Cela dépend de nombreux autres facteurs tels que vos index, la quantité de données présentes, etc. L'extraction d'un résultat simple à partir d'une table est toujours plus rapide qu'une jointure. Cependant, vous perdrez la flexibilité de la construction de requêtes complexes et de leurs requêtes en obtenant une liste affinée à l'aide de jointures. Quoi qu'il en soit, vous devez créer toutes les clauses where spécifiques à chaque requête si vous n'utilisez pas join. Une jointure sera exécutée dans la mémoire de la base de données et les requêtes individuelles nécessitent plusieurs appels à la base de données. Une base de données bien optimisée permettra d’obtenir les résultats plus rapidement en comparant la jonction à plusieurs résultats individuels. Ajoutez la surcharge réseau si votre base de données est sur un serveur différent, par exemple, à l'aide d'Amazon RDS.
Tous les résultats ne peuvent pas être dérivés en utilisant plusieurs requêtes uniques. Vous allez chercher des données inutiles pour filtrer l'ensemble de données requis. Par exemple,
une. Je veux une liste de produits vendus il y a 10 jours.
b. Produits dans une table et transactions dans d'autres
Comment obtenir uniquement des produits vendus il y a 10 jours sans utiliser de jointure?
De tous les points ci-dessus, je dirais que l'écriture de requêtes individuelles pour des jeux de données individuels n'a aucun avantage supplémentaire.