CF9 HQL Déclaration pour beaucoup à de nombreux et critères multiples
-
22-09-2019 - |
Question
J'ai la configuration suivante:
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 listes 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 en regardant à travers la documentation de mise en veille prolongée n'ont pas été en mesure de trouver une solution qui ne me donne pas une erreur. Je pense que la solution est assez simple et je suis un peu plus-pensant ... Quelqu'un at-il des suggestions?
La solution
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 des listes qui ont toutes les caractéristiques que je suis à la recherche mais il fait beaucoup de se joindre et en regardant le journal de SQL Mise en veille prolongée est la production:
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 la solution la plus correcte à cette question ici l'affichage pour tout le monde:
"Pour autant que je sais ORMExecuteQuery ne gère pas les paramètres de la liste, donc si vous vouliez les objets et retourner param que vous auriez à 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!
Autres conseils
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