2010-03-26 5 views
2

je la configuration suivante:CF9 HQL Déclaration des critères nombreux à plusieurs et plusieurs

Listing.cfc

component persistent="true" 
{ 
    property name="ListingId" column="ListingId" type="numeric" ormtype="int" fieldtype="id" generator="identity"; 
     ... 
    property name="Features" type="array" hint="Array of features" singularname="Feature" fieldtype="many-to-many" cfc="Feature" linktable="Listing_Feature" FKColumn="ListingId" inversejoincolumn="FeatureId";  
} 

Feature.cfc

component persistent="true" table="Feature" schema="dbo" output="false" 
{ 
    property name="FeatureId" column="FeatureId" type="numeric" ormtype="int" fieldtype="id" generator="identity"; 
    property name="FeatureDescription" column="FeatureDescription" type="string" ormtype="string"; 
    ...  
    /*property name="Listings" fieldtype="many-to-many" cfc="Listing" linktable="Listing_Feature" fkcolumn="FeatureId" inversejoincolumn="ListingId" lazy="true" cascade="all" orderby="GroupOrder";*/ 

} 

Je peux sélectionner toutes les annonces qui ont une caractéristique particulière en utilisant:

<cfset matchingListings = ormExecuteQuery("from Listing l left join l.Features as feature where feature.FeatureId = :feature",{feature = 110}) /> 

Ce qui est bien, mais je voudrais être en mesure de sélectionner toutes les annonces qui ont plusieurs caractéristiques (par exemple une liste qui a à la fois « Lave-vaisselle » et « Garage »)

Après quelques heures de googler et regardant à travers la documentation hibernate n'ont pas été en mesure de trouver une solution qui ne me donnera pas une erreur. Je suppose que la solution est assez simple et je suis juste trop penser ... quelqu'un a des suggestions?

Répondre

4

Je ne crois pas que ce soit cependant, la façon la plus efficace de le faire, il produit le résultat que je veux

<cfset matchingListings = ormExecuteQuery("Select l.ListingId from Listing l 
    left join l.Features as featureone left join l.Features as featuretwo 
    left join l.Features as featurethree 
    where featureone.FeatureId = 108 
    and featuretwo.FeatureId = 110 
    and featurethree.FeatureId = 113") /> 

Cela me donnera seulement que les annonces ont toutes les caractéristiques que je recherche, mais il fait beaucoup de se joindre et en regardant le journal de SQL Mise en veille prolongée est produit:

select listing0_.ListingId as col_0_0_ 
from dbo.Listing listing0_ 
left outer join Listing_Feature features1_ on listing0_.ListingId=features1_.ListingId 
left outer join dbo.Feature feature2_ on features1_.FeatureId=feature2_.FeatureId 
left outer join Listing_Feature features3_ on listing0_.ListingId=features3_.ListingId 
left outer join dbo.Feature feature4_ on features3_.FeatureId=feature4_.FeatureId 
left outer join Listing_Feature features5_ on listing0_.ListingId=features5_.ListingId 
left outer join dbo.Feature feature6_ on features5_.FeatureId=feature6_.FeatureId 
where 1=1 
and feature2_.FeatureId=108 
and feature4_.FeatureId=110 
and feature6_.FeatureId=113 

il semble tout comme il doit y avoir un moyen plus efficace de le faire dans HQL


Jon Messer sur la liste de diffusion cf-ORM-dev m'a donné ce que je crois est l'affichage de la solution la plus correcte à cette question ici pour tout le monde:

« Pour autant que je sais ORMExecuteQuery ne le fait pas gérer les paramètres de la liste, donc si vous vouliez les retourner et vous param auriez des objets à faire quelque chose comme

<cfset featureIds = [javaCast('int',108), javaCast('int',110), javaCast('int',113)] > 

<cfset q = ormGetSession().createQuery(" 
    select l.ListingId 
    from Listing l 
     join l.features as f 
    where f.FeatureId in (:features) 
    group by l.ListingId 
    having count(*) = #arrayLen(featureIds)# 
") /> 

<cfset q.setParameterList('features', featureIds) /> 

<cfset matchingListings = q.list() /> 

"

Merci Jon!

+1

au moins c'est correct, je le ferais de cette façon si je dois rester en HQL (ne pas écrire personnalisé, SQL plus efficace) – Henry

+0

J'ai ajouté la solution la plus correcte au fond de cette réponse. –

0

Cela devrait fonctionner:

<cfset featurelist = "110,113,125"/> 
<cfset matchingListings = ormExecuteQuery("from Listing l left join l.Features as feature where feature.FeatureId IN (#featurelist#)")/> 

Si vous voulez aller avec des paramètres liés, vous aurez à faire un peu de travail supplémentaire, car veille prolongée n'aime pas les listes de ColdFusion et/ou des tableaux comme paramètres liés cette fois-ci. Vous pouvez trouver quelques informations supplémentaires here

+0

Cela ne me donnera pas réellement le résultat que je veux bien. Cela me donnera n'importe quelle liste avec un featureid de 110, 113, ou 125, non seulement des listes avec toutes les 3 caractéristiques. –

+1

Ok. Je vois. Désolé pour la confusion. Ensuite, vous devrez regrouper le résultat et utiliser la clause HAVING pour vérifier si votre objet Listing correspond à * TOUS * les critères. Vu que vous, Henry et. Al. déjà posté une solution au groupe Google cf-orm-dev. –

Questions connexes