Hibernate3 fournit une nouvelle approche innovatrice pour gérer des données avec des règles de "visibilité". Un filtre Hibernate est un filtre global, nommé, paramétré qui peut être activé ou désactivé pour une session Hibernate particulière.
Hibernate3 ajoute la capacité de prédéfinir des critères de filtre et d'attacher ces filtres à une classe ou à une collection. Un critère de filtre est la faculté de définir une clause de restriction très similaire à l'attribut "where" existant disponible sur une classe et divers éléments d'une collection. Mis à part que ces conditions de filtre peuvent être paramétrées. L'application peut alors prendre la décision à l'exécution si des filtres donnés devraient être activés et quels devraient être leurs paramètres. Des filtres peuvent être utilisés comme des vues de base de données, mais paramétrées dans l'application.
Afin d'utiliser des filtres, ils doivent d'abord être définis, puis attachés aux éléments de mapping appropriés. Pour définir
un filtre, utilisez l'élément <filter-def/>
dans un élément <hibernate-mapping/>
:
<filter-def name="myFilter"> <filter-param name="myFilterParam" type="string"/> </filter-def>
Puis, ce filtre peut être attaché à une classe :
<class name="myClass" ...> ... <filter name="myFilter" condition=":myFilterParam = MY_FILTERED_COLUMN"/> </class>
ou à une collection :
<set ...> <filter name="myFilter" condition=":myFilterParam = MY_FILTERED_COLUMN"/> </set>
ou même aux deux (ou à plusieurs de chaque) en même temps.
The methods on Session
are: enableFilter(String filterName)
, getEnabledFilter(String filterName)
, and disableFilter(String filterName)
. By default, filters are not enabled for a given session; they must be explcitly enabled through use of the Session.enableFilter()
method, which returns an instance of the Filter
interface. Using the simple filter defined above, this would look like:
session.enableFilter("myFilter").setParameter("myFilterParam", "some-value");
Notez que des méthodes sur l'interface org.hibernate.Filter autorisent le chaînage de beaucoup de méthodes communes d'Hibernate.
Un exemple complet, utilisant des données temporelles avec une structure de date d'enregistrement effectif :
<filter-def name="effectiveDate"> <filter-param name="asOfDate" type="date"/> </filter-def> <class name="Employee" ...> ... <many-to-one name="department" column="dept_id" class="Department"/> <property name="effectiveStartDate" type="date" column="eff_start_dt"/> <property name="effectiveEndDate" type="date" column="eff_end_dt"/> ... <!-- Note that this assumes non-terminal records have an eff_end_dt set to a max db date for simplicity-sake --> <filter name="effectiveDate" condition=":asOfDate BETWEEN eff_start_dt and eff_end_dt"/> </class> <class name="Department" ...> ... <set name="employees" lazy="true"> <key column="dept_id"/> <one-to-many class="Employee"/> <filter name="effectiveDate" condition=":asOfDate BETWEEN eff_start_dt and eff_end_dt"/> </set> </class>
Puis, afin de s'assurer que vous pouvez toujours récupérer les enregistrements actuellement effectifs, activez simplement le filtre sur la session avant de récupérer des données des employés :
Session session = ...; session.enableFilter("effectiveDate").setParameter("asOfDate", new Date()); List results = session.createQuery("from Employee as e where e.salary > :targetSalary") .setLong("targetSalary", new Long(1000000)) .list();
Dans le HQL ci-dessus, bien que nous ayons seulement mentionné une contrainte de salaire sur les resultats, à cause du filtre activé, la requête retournera seulement les employés actuellement actifs qui ont un salaire supérieur à un million de dollars.
A noter : si vous prévoyez d'utiliser des filtres avec des jointures externes (soit à travers HQL, soit par le chargement) faites attention à la direction de l'expression de condition. Il est plus sûr de la positionner pour les jointures externes à gauche ; en général, placez le paramètre d'abord, suivi du(des) nom(s) de colonne après l'opérateur.
translator-credits
<filter-def name="myFilter" condition="abc > xyz">...</filter-def> <filter-def name="myOtherFilter">abc=xyz</filter-def>
This default condition will then be used whenever the filter is attached to something without specifying a condition. Note that this means you can give a specific condition as part of the attachment of the filter which overrides the default condition in that particular case.