Mois : février 2009

Hibernate : mapping d’une colonne en Set

Le mapping avec Hibernate

L’utilisation d’une relation many-to many avec hibernate permet de rendre transparent la table d’association.

Dans l’exemple suivant, la table EDITION_LIVRE sera mappée de manière transparente :
Livre Many Many Hibernate
La mapping de la table LIVRE sera le suivant :

‹set name="editions" table="EDITION_LIVRE"›
‹key column="LIVRE_ID" /›
‹many-to-many column="EDITION_ID" /›
‹/set›

Et Livre contiendra un Set<Edition>, mais l’objet EditionLivre n’existera pas…

A la vue de ce type de mapping, on peut être intéressé de faire la même chose pour un mapping many to one.
En effet, plutôt que de me retrouver avec un Set d’objet dont nous n’avons besoin que pour de l’affichage, nous préférerions avoir un Set de String. Par exemple, si on prend une relation de ce type :

Livre Set Hibernate
Et qu’on ne veut pas avoir à mapper l’objet LivreMotcle, il suffit de définir dans le fichier de mapping Livre le Set suivant :

‹set name=”mots" table="LIVRE_MOTCLE"›
‹key column="LIVRE_ID" /›
‹element column="MOT" type="string"/›
‹/set›

On obtient alors un Set<String> mots dans l’objet Livre.

Comparaison de chaines grâce à un Collator

Utiliser un Collator pour la comparaison de chaines

Lors de la manipulation de données, il est souvent nécessaire de comparer des chaines de caractère, pour réaliser des tris par exemple. Cependant, plusieurs problèmes peuvent se poser, comme la différence de casse et la présence de lettres diacritées (possédant un accent ou une cédille, par exemple).

Si pour les problèmes de casse, il est possible de s’en sortir avec les méthodes equalsIgnoreCase() et compareToIgnoreCase() de la classe String, il n’en va pas de même pour les problèmes de diacritiques. En effet, non seulement il est très difficile de prévoir tous les cas, mais en plus ce problème est dépendant de la langue utilisée (alors qu’il y a moins de 20 mots comportant des diacritiques en anglais, la quasi-totalité des mots vietnamiens en comportent).

Heureusement, Java propose un outil nommé Collator (du verbe anglais « to collate », ordonner, ranger, vérifier l’ordre) permettant de gérer ce problème de façon simple. En effet, le Collator permet de faire une comparaison intelligente en tenant compte de la locale, mais aussi des diacritiques et de la casse.

Voici un petit exemple pour illustrer son fonctionnement :

package com.viaxoft.test.collator;import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;public class TestCollator {
public static void main (String [] args) {
final List pays = new ArrayList ();
pays.add("zimbabwe");
pays.add("angola");
pays.add("Australie");
pays.add("Zambie");
pays.add("éthiopie");
pays.add("États-Unis");
pays.add("Égypte");
pays.add("Sénégal");
pays.add("Serbie");Collections.sort(pays);
printTitle("Tri par défaut");
printList(pays);
Collections.sort(pays, new Comparator () {
public int compare(String o1, String o2) {
return o1.compareToIgnoreCase(o2);
}
});
printTitle("Tri en ignorant la casse");
printList(pays);

final Collator frCollator = Collator.getInstance(Locale.FRENCH);
Collections.sort(pays, new Comparator () {
public int compare(String o1, String o2) {
return frCollator.compare(o1, o2);
}
});
printTitle("Tri avec un Collator");
printList(pays);

frCollator.setStrength(Collator.TERTIARY);
printTitle("Comparaison avec un Collator "TERTIARY"");
compareWithCollator ("egypte", "egypte", frCollator);
compareWithCollator ("Egypte", "egypte", frCollator);
compareWithCollator ("égypte", "egypte", frCollator);
compareWithCollator ("Égypte", "egypte", frCollator);
compareWithCollator ("Égypte", "Sénégal", frCollator);

frCollator.setStrength(Collator.SECONDARY);
printTitle("Comparaison avec un Collator "SECONDARY"");
compareWithCollator ("egypte", "egypte", frCollator);
compareWithCollator ("Egypte", "egypte", frCollator);
compareWithCollator ("égypte", "egypte", frCollator);
compareWithCollator ("Égypte", "egypte", frCollator);
compareWithCollator ("Égypte", "Sénégal", frCollator);

frCollator.setStrength(Collator.PRIMARY);
printTitle("Comparaison avec un Collator "PRIMARY"");
compareWithCollator ("egypte", "egypte", frCollator);
compareWithCollator ("Egypte", "egypte", frCollator);
compareWithCollator ("égypte", "egypte", frCollator);
compareWithCollator ("Égypte", "egypte", frCollator);
compareWithCollator ("Égypte", "Sénégal", frCollator);
}

private static void printTitle (final String title) {
System.out.println("");
System.out.println(title);
System.out.println(title.replaceAll(".", "-"));
}

private static void printList (final List list) {
int i=1;
for (String str : list) {
System.out.println(i+". "+str);
i++;
}
}

private static void compareWithCollator (final String str1, final String str2, final Collator collator) {
if (collator.equals(str1, str2))
System.out.println(str1+"=="+str2);
else
System.out.println(str1+"!="+str2);
}
}

 

Et le résultat de l’exécution de ce programme :

Tri par défaut

  1. Australie
  2. Serbie
  3. Sénégal
  4. Zambie
  5. angola
  6. zimbabwe
  7. Égypte
  8. États-Unis
  9. éthiopie

Tri en ignorant la casse

  1. angola
  2. Australie
  3. Serbie
  4. Sénégal
  5. Zambie
  6. zimbabwe
  7. Égypte
  8. États-Unis
  9. éthiopie

Tri avec un Collator

  1. angola
  2. Australie
  3. Égypte
  4. États-Unis
  5. éthiopie
  6. Sénégal
  7. Serbie
  8. Zambie
  9. zimbabwe

Comparaison avec un Collator « TERTIARY »
egypte==egypte
Egypte!=egypte
égypte!=egypte
Égypte!=egypte
Égypte!=Sénégal

Comparaison avec un Collator « SECONDARY »
egypte==egypte
Egypte==egypte
égypte!=egypte
Égypte!=egypte
Égypte!=Sénégal

Comparaison avec un Collator « PRIMARY »
egypte==egypte
Egypte==egypte
égypte==egypte
Égypte==egypte
Égypte!=Sénégal

Comme on s’y attendait, la liste des pays n’est pas triée correctement avec les comparateurs de base de la classe String, mais l’est avec le Collator.
Cet exemple montre également l’influence de la propriété « strength » (force, puissance en anglais) sur le test d’égalité du collator : en « TERTIARY », on tient compte de la casse et des diacritiques, en « SECONDARY » seulement des diacritiques, et en « PRIMARY » ni de l’un ni de l’autre. Il faudra donc également prendre en compte ce paramètre lors de l’utilisation d’un Collator, et le choisir en fonction du besoin.

L’Esprit Agile

ViaXoft, en partenariat avec Centrale Marseille et Marseille Innovation, vous invite à découvrir « L’Esprit Agile« , le mardi 17 Mars à partir de 17h30, à l’Ecole Centrale de Marseille.

Appréhendez les méthodologies Agiles (Scrum, XP, …), leurs spécificités, leurs apports et leurs différences par rapport aux méthodologies traditionnelles autour des Présentations et des retours d’expérience de :

Claude Aubry, Consultant, Professeur à l’Université Paul Sabatier

Thierry Cros, Fondateur de l’association XP France en 2000, Coach et formateur XP

Loading...
X