Инструкция CF9 HQL для "многие ко многим" и множественных критериев

StackOverflow https://stackoverflow.com/questions/2521016

Вопрос

У меня есть следующая настройка:

Листинг.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";    
} 

Особенность.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";*/

} 

Я могу выбрать все объявления, которые имеют определенную функцию, используя:

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

Это нормально, однако я хотел бы иметь возможность выбирать все объявления, которые имеют несколько функций (например, список, в котором есть как "Посудомоечная машина", так и "Гараж").

После пары часов поиска в Google и просмотра документации hibernate я не смог найти решение, которое не выдаст мне ошибку.Я предполагаю, что решение довольно простое, и я просто переоцениваю его ... У кого-нибудь есть какие-либо предложения?

Это было полезно?

Решение

Я не считаю, что это самый эффективный способ сделать это, однако он дает желаемый результат

<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") />

Это даст мне только списки, в которых есть все функции, которые я ищу, но это требует БОЛЬШОГО объединения и просмотра журнала hibernate SQL, который создает:

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

Просто кажется, что должен быть более эффективный способ сделать это в HQL


Джон Мессер из списка рассылки cf-orm-dev дал мне то, что я считаю наиболее правильным решением этого вопроса, разместив его здесь для всех:

"Насколько я знаю, ORMExecuteQuery не обрабатывает параметры списка, поэтому, если вы хотите настроить их и вернуть объекты, вам нужно будет сделать что-то вроде

<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() />

"

Спасибо, Джон!

Другие советы

Это должно сработать:

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

Если вы хотите использовать связанные параметры, вам придется проделать некоторую дополнительную работу, потому что на этот раз hibernate не использует списки ColdFusion и / или массивы в качестве связанных параметров.Вы можете найти некоторую дополнительную информацию здесь

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top