2010-07-27 6 views
1

Même question que this, seulement je voudrais le faire dans Hibernate (en utilisant des grails si cela compte).Comment trier une liste chaînée dans hql?

Ainsi, la classe de domaine ressemble à ce

class LinkedElement { 
    LinkedElement precedingElement 
    String someData 
} 

et je voudrais interroger tous les éléments dans leur ordre lié (où le premier a LinkedElement null comme precedingElement). Est-ce possible d'une manière efficace?

Répondre

2

Vous ne pouvez que facilement savoir qui est en première ligne (c'est-à-dire que l'élément précédent est nul). Malheureusement, cela signifie que vous êtes en territoire de requête N + 1 pour obtenir la liste complète.

Query 1 - who's in front 
Query 2 - who's behind 1 
Query 3 - who's behind 2 
.... 
Query n - who's behind n-1 
Query n+1 - who's behind n -> no one is behind n, I must be at the end 

En se référant à la question que vous avez mentionnée, ne confondez pas efficace pour syntaxiquement concis. Juste parce que certains SGBD vous donneront une syntaxe pratique, ils résolvent toujours le même problème soit par un.) Exécutant le même algorithme inefficace mais avec une syntaxe simplifiée ou b.) Indexant les choses à l'avance afin que le SGBD ait accès à vos données efficacement même si vous ne l'avez pas modélisé de cette façon. Donc, si vous devez absolument résoudre ce problème avec la structure de données spécifiée en utilisant hibernate, vous devriez utiliser Native SQL Query, en ajustant au niveau de la base de données, en profitant des fonctionnalités que votre SGBD peut vous offrir dans cette zone.

Si vous pensez à la structure de données que vous utilisez, c'est génial pour représenter une pile. Vous pouvez pousser, sauter et terminer avec seulement quelques opérations chacune. En général, c'est ce que les listes liées unidirectionnelles sont bonnes. Pour quelque chose comme une file d'attente, vous voudriez penser à utiliser une liste chaînée bidirectionnelle puisque vous pouvez déqueue, front, et enqueue avec seulement quelques opérations chacune. Pour ajouter dynamiquement des éléments dans une liste, LinkedLists est génial. Pour obtenir toute une liste de choses dans l'ordre, LinkedLists est assez inefficace par lui-même - vous regardez n + 1 ou n opérations selon single ou bidirectionnel. Au lieu de cela, un ArrayList est le chemin à parcourir. Voulez-vous savoir quel est le troisième élément? Cool, utilise son index. Par rapport à la liste liée où vous devez utiliser first.getNext.getNext, c'est beaucoup plus efficace! Mais si vous avez besoin d'ajouter des éléments à la liste ou de les utiliser pour une application de type queue ou pile, cela a certainement ses inconvénients - le redimensionnement des tableaux est coûteux comparé à l'ajout d'un nouveau lien dans une liste chaînée.

Je voudrais avoir une meilleure réponse pour vous, mais j'espère que c'est au moins un peu utile.

+0

Cela a été très utile et je suppose que vous avez raison concernant les frais généraux également en SQL. Mon incitation à utiliser ceci au lieu d'un index est que j'ai besoin de changer facilement la position d'un élément, par ex. de la 1000ème position à la 500ème, où l'ancienne 500ème devient la 501ème, la 501ème devient la 502ème et ainsi de suite. Alors que cela nécessiterait seulement quelques mises à jour en utilisant la liste chaînée, dans les grandes listes avec un index, il y aurait beaucoup de mises à jour de DB pour un changement, ou y a-t-il un autre moyen de les éviter? Je n'ai pas besoin de savoir quel est le n-ième élément, mais j'ai besoin d'interroger efficacement les éléments dans le bon ordre. –