web-dev-qa-db-fra.com

Ignorecase dans le constructeur de critères en JPA

Comment pouvons-nous faire une ignorale dans le constructeur de critères? Si j'ai

private final CriteriaBuilder cb

ensuite, je ne peux utiliser que cb.asc ou cb.desc, mais ne pas ignorer l'affaire.

17
ronan

Comment pouvons-nous faire une ignorale dans le constructeur de critères

1. Force Ignorecase dans le programme JPA - Est-ce que le travail, répond au q directement

  • Pour une opération One-AG (c'est-à-dire l'ordre par), convertir l'argument en minuscules (ou en majuscule).
  • Pour une opération de deux-ARC (E.G. = ou comme ou commander par), convertissez les deux arguments à LC (ou UC).

Ordre JPA par deux colonnes, ignorant l'affaire:

 Order lcSurnameOrder = criteriaBuilder.order(
     criteriaBuilder.lower(Person_.surname));
 Order lcFirstnameOrder = criteriaBuilder.order(
     criteriaBuilder.lower(Person_.firstname));    
 criteriaQuery.orderBy(lcSurnameOrder, lcFirstnameOrder);

JPA Comme, ignorer l'affaire:

 Predicate lcSurnameLikeSearchPattern = criteriaBuilder.like(
     criteriaBuilder.lower(Person_.surname), 
     searchPattern.toLowerCase());
 criteriaQuery.where(lcSurnameLikeSearchPattern);

ASSEMBRE PERSONNE_ CANONICAL METAMODEL La classe a été générée à partir d'une personne responsable, afin de donner une utilisation forte de l'API de critères JPA.

CONSEIL: Pour la meilleure performance et le contrôle, envisagez de convertir des colonnes de chaîne en boîtes minuscules ou initcap, juste une fois - lorsque vous insérez/mettez à jour dans la base de données. Faites la même conversion pour les modèles de recherche saisis par l'utilisateur.

2. Alternative: appliquer une collation dans la base de données - Meilleure pratique, plus simple, plus performante

  • La norme SQL-99 comporte un motif intégré pour comparer les caractères dans les chaînes selon les règles:

    COLLATE <collation name>
    

    Peut utiliser lors de la comparaison, du tri et du regroupement sur les chaînes. Un exemple commun qui ignore l'affaire:

    COLLATE SQL_Latin1_General_CP1_CI_AS
    

    Ou

    COLLATE latin1_general_cs
    

    Vous pouvez même créer votre propre collation personnalisée:

    CREATE COLLATION <collation name> FOR <character set specification>
      FROM <existing collation name> [ <pad characteristic> ]
    
  • La classement est appliqué dans la DB via l'une des solutions de rechange suivantes (de la localisation à l'effet global):

    • où la clause (=, comme, avoir,>,> =, etc.)

      WHERE <expression> = <expression> [COLLATE <collation name>]
      
      WHERE <expression> LIKE <expression> [COLLATE <collation name>]
      
    • Sélectionnez la clause distincte

      SELECT DISTINCT <expression> [COLLATE <collation name>], ...
      
    • Commande par clause

      ORDER BY <expression> [COLLATE <collation name>]
      
    • Groupe par clause

      GROUP BY <expression> [COLLATE <collation name>]
      
    • Définition de la colonne

      CREATE TABLE <table name> (
        <column name> <type name> [DEFAULT...] 
                                  [NOT NULL|UNIQUE|PRIMARY KEY|REFERENCES...]
                                  [COLLATE <collation name>], 
        ...
      )
      
    • Définition du domaine

      CREATE DOMAIN <domain name> [ AS ] <data type>
        [ DEFAULT ... ] [ CHECK ... ] [ COLLATE <collation name> ]
      
    • Définition du jeu de caractères

      CREATE CHARACTER SET <character set name>
      [ AS ] GET <character set name> [ COLLATE <collation name> ]
      
  • Les 4 premiers cas ne peuvent pas être utilisés avec JPA, car ces commandes SQL sont générées par JPA et la norme JPA ne prend pas en charge la collation.

  • Les 3 derniers cas peuvent être utilisés avec JPA.
  • SO: Créez des tables avec des colonnes "allumées" et commander par la suite par, =, etc. Ignorera automatiquement le cas. Alors aucun travail n'est requis dans JPA - aucun besoin de conversion ou de demande d'ignorer l'affaire.

. Alternative (propriétaire) Oracle fournit également des paramètres NLS à ignorer l'affaire sur l'instance de DB totale (peut être définie dans les fichiers de configuration):

ALTER SESSION SET NLS_COMP='BINARY';    -- Case Sensitive
ALTER SESSION SET NLS_COMP='ANSI';      -- Ignore for LIKE but not =,<,etc
ALTER SESSION SET NLS_COMP='LINGUISTIC';-- Ignore for LIKE,=,<,etc (post 10gR2)

ALTER SESSION SET NLS_SORT='BINARY' ;   -- Case Sensitive
ALTER SESSION SET NLS_SORT='BINARY_CI'; -- Ignore
ALTER SESSION SET NLS_SORT='XSPANISH';  -- Ignore according to language rules
ALTER SESSION SET NLS_SORT='LATIN1_GENERAL_CS';  

Plus fonctions pour ignorer l'affaire comme un éteint

ORDER BY NLSSORT(supplier_name,'NLS_SORT=BINARY_CI') ;

Vous pouvez appeler cela via

criteriaBuilder.function("nlssort", String.class, dept_.suppler_name, "NLS_SORT=BINARY_CI");

puis appelez criteriaQuery.orderyBy ou select, etc.

47
Glen Best