jparepository - spring data jpa example mkyong
ignore el caso en el generador de criterios en JPA (1)
¿Cómo podemos hacer un ignorecase en el generador de criterios?
1. Force Ignorecase en el programa JPA - ¿El trabajo responde la Q directamente?
- Para una operación de una arg (es decir, ORDER BY), convierta el argumento a minúsculas (o mayúsculas).
- Para una operación de dos arg (p. Ej. = O LIKE u ORDER BY), convierta ambos args a LC (o UC).
ORDEN JPA POR DOS COLUMNAS, Ignorando el caso:
Order lcSurnameOrder = criteriaBuilder.order(
criteriaBuilder.lower(Person_.surname));
Order lcFirstnameOrder = criteriaBuilder.order(
criteriaBuilder.lower(Person_.firstname));
criteriaQuery.orderBy(lcSurnameOrder, lcFirstnameOrder);
JPA LIKE, ignorando el caso:
Predicate lcSurnameLikeSearchPattern = criteriaBuilder.like(
criteriaBuilder.lower(Person_.surname),
searchPattern.toLowerCase());
criteriaQuery.where(lcSurnameLikeSearchPattern);
Asume que Person_ canonical metamodel class se generó a partir de la entidad Person, para dar un uso fuerte de la API de criterios JPA.
CONSEJO: Para obtener el mejor rendimiento y control, considere la posibilidad de convertir columnas de cadenas en LOWER case o INITCAP case una sola vez, cuando INSERT / UPDATE en la base de datos. Haga la misma conversión para los patrones de búsqueda ingresados por el usuario.
2. ALTERNATIVA: aplique colación en la base de datos: mejor práctica, más simple, más eficiente
El estándar SQL-99 tiene un modificador incorporado para comparar caracteres en cadenas según las reglas:
COLLATE <collation name>
Puede usarse cuando se comparan, clasifican y agrupan cadenas. Un ejemplo común que ignora el caso:
COLLATE SQL_Latin1_General_CP1_CI_AS
O
COLLATE latin1_general_cs
Incluso puede crear su propia clasificación personalizada:
CREATE COLLATION <collation name> FOR <character set specification> FROM <existing collation name> [ <pad characteristic> ]
La intercalación se aplica en la base de datos mediante una de las siguientes alternativas (desde el efecto localizado hasta el global):
WHERE Cláusula (=, LIKE, HAVING,>,> =, etc.)
WHERE <expression> = <expression> [COLLATE <collation name>] WHERE <expression> LIKE <expression> [COLLATE <collation name>]
Cláusula SELECT DISTINCT
SELECT DISTINCT <expression> [COLLATE <collation name>], ...
ORDEN BY Cláusula
ORDER BY <expression> [COLLATE <collation name>]
Cláusula GROUP BY
GROUP BY <expression> [COLLATE <collation name>]
Definición de columna
CREATE TABLE <table name> ( <column name> <type name> [DEFAULT...] [NOT NULL|UNIQUE|PRIMARY KEY|REFERENCES...] [COLLATE <collation name>], ... )
Definición del dominio
CREATE DOMAIN <domain name> [ AS ] <data type> [ DEFAULT ... ] [ CHECK ... ] [ COLLATE <collation name> ]
Definición del conjunto de caracteres
CREATE CHARACTER SET <character set name> [ AS ] GET <character set name> [ COLLATE <collation name> ]
Los primeros 4 casos no se pueden usar con JPA, porque estos comandos SQL son generados por JPA, y el estándar JPA no admite la intercalación.
- Los últimos 3 casos se pueden usar con JPA.
- Por lo tanto, cree TABLAS con COLUMNAS que tengan la intercalación "activada" y, posteriormente, ORDER BY, =, LIKE, etc. ignorará el caso automáticamente. Entonces no se requiere trabajo en JPA: no es necesario realizar ninguna conversión ni solicitar ignorar el caso.
3. ALTERNATIVO (PROPIETARIO) Oracle también proporciona configuraciones NLS para ignorar mayúsculas y minúsculas en toda la instancia de DB (se puede establecer en archivos de configuración):
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'';
Funciones adicionales para ignorar el caso como una excepción
ORDER BY NLSSORT(supplier_name,''NLS_SORT=BINARY_CI'') ;
Puedes llamar esto a través de
criteriaBuilder.function("nlssort", String.class, dept_.suppler_name, "NLS_SORT=BINARY_CI");
y luego llame a criteriaQuery.orderyBy
o select
, etc.
¿Cómo podemos hacer un ignorecase en el generador de criterios? Si tengo
private final CriteriaBuilder cb
entonces solo puedo usar cb.asc
o cb.desc
, pero sin ignorar el caso.