Todos los métodos find
de repositorios y gestores aceptan opciones especiales que puedes usar para consultar los datos que necesites sin usar QueryBuilder
:
select
- indica qué propiedades del objeto principal deben seleccionarse1userRepository.find({ select: ["firstName", "lastName"] });
relations
- debe cargarse con la entidad principal. También se pueden cargar las subrelaciones (abreviatura de join y leftJoinAndSelect)1userRepository.find({ relations: ["profile", "photos", "videos"] }); 2userRepository.find({ relations: ["profile", "photos", "videos", "videos.video_attributes"] });
join
- necesita ser ejecutado por la entidad. Versión ampliada de "relations".1userRepository.find({ 2 join: { 3 alias: "user", 4 leftJoinAndSelect: { 5 profile: "user.profile", 6 photo: "user.photos", 7 video: "user.videos" 8 } 9 } 10});
where
- condiciones simples por las que debe consultarse la entidad.1userRepository.find({ where: { firstName: "Timber", lastName: "Saw" } });
La consulta de una columna de una entidad incrustada debe hacerse con respecto a la jerarquía en la que se definió. Ejemplo:
1userRepository.find({ where: { name: { first: "Timber", last: "Saw" } } });
Consulta con el operador OR:
1userRepository.find({ 2 where: [ 3 { firstName: "Timber", lastName: "Saw" }, 4 { firstName: "Stan", lastName: "Lee" } 5 ] 6});
ejecutará la siguiente consulta:
1SELECT * FROM "user" WHERE ("firstName" = 'Timber' AND "lastName" = 'Saw') OR ("firstName" = 'Stan' AND "lastName" = 'Lee')
order
- orden de selección.1userRepository.find({ 2 order: { 3 name: "ASC", 4 id: "DESC" 5 } 6});
withDeleted
- incluye entidades que han sido borradas suavemente con softDelete
o softRemove
, por ejemplo, que tienen su columna @DeleteDateColumn
configurada. Por defecto, las entidades borradas suavemente no se incluyen.1userRepository.find({ 2 withDeleted: true 3});
Los métodos find
que devuelven múltiples entidades (find
, findAndCount
, findByIds
) también aceptan las siguientes opciones:
skip
- Desplazamiento (paginado) desde donde deben tomarse las entidades.1userRepository.find({ 2 skip: 5 3});
take
- limit (paginado) - número máximo de entidades que deben tomarse.1userRepository.find({ 2 take: 10 3});
take
o limit
, deberá utilizar también order o recibirá el siguiente error: 'Invalid usage of the option NEXT in the FETCH statement.'
.1userRepository.find({ 2 order: { 3 columnName: 'ASC' 4 }, 5 skip: 0, 6 take: 10 7})
cache
- Activa o desactiva el almacenamiento en caché de los resultados de la consulta. 1userRepository.find({ 2 cache: true 3})
lock
- Activa el mecanismo de bloqueo de la consulta. Sólo se puede utilizar en el método findOne
. lock
es un objeto que puede ser definido como:1{ mode: "optimistic", version: number|Date }
o
1{ mode: "pessimistic_read"|"pessimistic_write"|"dirty_read"|"pessimistic_partial_write"|"pessimistic_write_or_fail"|"for_no_key_update" }
por ejemplo:
1userRepository.findOne(1, { 2 lock: { mode: "optimistic", version: 1 } 3})
El soporte de los modos de bloqueo, y las sentencias SQL a las que se traducen, se listan en la siguiente tabla (una celda en blanco denota no soportado). Cuando el modo de bloqueo especificado no está soportado, se lanzará un error LockNotSupportedOnGivenDriverError
.
1| | pessimistic_read | pessimistic_write | dirty_read | pessimistic_partial_write | pessimistic_write_or_fail | for_no_key_update | 2| --------------- | -------------------- | ----------------------- | ------------- | --------------------------- | --------------------------- | ------------------- | 3| MySQL | LOCK IN SHARE MODE | FOR UPDATE | (nothing) | FOR UPDATE SKIP LOCKED | FOR UPDATE NOWAIT | | 4| Postgres | FOR SHARE | FOR UPDATE | (nothing) | FOR UPDATE SKIP LOCKED | FOR UPDATE NOWAIT | FOR NO KEY UPDATE | 5| Oracle | FOR UPDATE | FOR UPDATE | (nothing) | | | | 6| SQL Server | WITH (HOLDLOCK, ROWLOCK) | WITH (UPDLOCK, ROWLOCK) | WITH (NOLOCK) | | | | 7| AuroraDataApi | LOCK IN SHARE MODE | FOR UPDATE | (nothing) | | | | 8
Ejemplo completo de opciones de búsqueda:
1userRepository.find({ 2 select: ["firstName", "lastName"], 3 relations: ["profile", "photos", "videos"], 4 where: { 5 firstName: "Timber", 6 lastName: "Saw" 7 }, 8 order: { 9 name: "ASC", 10 id: "DESC" 11 }, 12 skip: 5, 13 take: 10, 14 cache: true 15});
TypeORM proporciona muchos operadores incorporados que pueden utilizarse para crear comparaciones más complejas:
Not
1import {Not} from "typeorm"; 2 3const loadedPosts = await connection.getRepository(Post).find({ 4 title: Not("About #1") 5})
ejecutará la siguiente consulta:
1SELECT * FROM "post" WHERE "title" != 'About #1'
LessThan
1import {LessThan} from "typeorm"; 2 3const loadedPosts = await connection.getRepository(Post).find({ 4 likes: LessThan(10) 5});
ejecutará la siguiente consulta:
1SELECT * FROM "post" WHERE "likes" < 10
LessThanOrEqual
1import {LessThanOrEqual} from "typeorm"; 2 3const loadedPosts = await connection.getRepository(Post).find({ 4 likes: LessThanOrEqual(10) 5});
ejecutará la siguiente consulta:
1SELECT * FROM "post" WHERE "likes" <= 10
MoreThan
1import {MoreThan} from "typeorm"; 2 3const loadedPosts = await connection.getRepository(Post).find({ 4 likes: MoreThan(10) 5});
ejecutará la siguiente consulta:
1SELECT * FROM "post" WHERE "likes" > 10
MoreThanOrEqual
1import {MoreThanOrEqual} from "typeorm"; 2 3const loadedPosts = await connection.getRepository(Post).find({ 4 likes: MoreThanOrEqual(10) 5});
ejecutará la siguiente consulta:
1SELECT * FROM "post" WHERE "likes" >= 10
Equal
1import {Equal} from "typeorm"; 2 3const loadedPosts = await connection.getRepository(Post).find({ 4 title: Equal("About #2") 5});
ejecutará la siguiente consulta:
1SELECT * FROM "post" WHERE "title" = 'About #2'
Like
1import {Like} from "typeorm"; 2 3const loadedPosts = await connection.getRepository(Post).find({ 4 title: Like("%out #%") 5});
ejecutará la siguiente consulta:
1SELECT * FROM "post" WHERE "title" LIKE '%out #%'
ILike
1import {ILike} from "typeorm"; 2 3const loadedPosts = await connection.getRepository(Post).find({ 4 title: ILike("%out #%") 5});
ejecutará la siguiente consulta:
1SELECT * FROM "post" WHERE "title" ILIKE '%out #%'
Between
1import {Between} from "typeorm"; 2 3const loadedPosts = await connection.getRepository(Post).find({ 4 likes: Between(1, 10) 5});
ejecutará la siguiente consulta:
1SELECT * FROM "post" WHERE "likes" BETWEEN 1 AND 10
In
1import {In} from "typeorm"; 2 3const loadedPosts = await connection.getRepository(Post).find({ 4 title: In(["About #2", "About #3"]) 5});
ejecutará la siguiente consulta:
1SELECT * FROM "post" WHERE "title" IN ('About #2','About #3')
Any
1import {Any} from "typeorm"; 2 3const loadedPosts = await connection.getRepository(Post).find({ 4 title: Any(["About #2", "About #3"]) 5});
ejecutará la siguiente consulta: (Notación Postgres):
1SELECT * FROM "post" WHERE "title" = ANY(['About #2','About #3'])
IsNull
1import {IsNull} from "typeorm"; 2 3const loadedPosts = await connection.getRepository(Post).find({ 4 title: IsNull() 5});
ejecutará la siguiente consulta:
1SELECT * FROM "post" WHERE "title" IS NULL
Raw
1import {Raw} from "typeorm"; 2 3const loadedPosts = await connection.getRepository(Post).find({ 4 likes: Raw("dislikes - 4") 5});
ejecutará la siguiente consulta:
1SELECT * FROM "post" WHERE "likes" = "dislikes" - 4
En el caso más sencillo, se inserta una consulta sin procesar inmediatamente después del símbolo igual. Pero también se puede reescribir completamente la lógica de comparación utilizando la función.
1import {Raw} from "typeorm"; 2 3const loadedPosts = await connection.getRepository(Post).find({ 4 currentDate: Raw(alias =>`${alias} > NOW()`) 5});
ejecutará la siguiente consulta:
1SELECT * FROM "post" WHERE "currentDate" > NOW()
Si necesita introducir datos de usuario, no debe incluirlos directamente en la consulta, ya que podría crear una vulnerabilidad de inyección SQL. En su lugar, puede utilizar el segundo argumento de la función Raw
para proporcionar una lista de parámetros que vincular a la consulta.
1import {Raw} from "typeorm"; 2 3const loadedPosts = await connection.getRepository(Post).find({ 4 currentDate: Raw(alias =>`${alias} > ':date'`, { date: "2020-10-06" }) 5});
ejecutará la siguiente consulta:
1SELECT * FROM "post" WHERE "currentDate" > '2020-10-06'
Si necesita proporcionar una entrada de usuario que sea una matriz, puede enlazarla como una lista de valores en la sentencia SQL utilizando la sintaxis de expresión especial:
1import {Raw} from "typeorm"; 2 3const loadedPosts = await connection.getRepository(Post).find({ 4 title: Raw(alias =>`${alias} IN (:...titles)`, { titles: ["Go To Statement Considered Harmful", "Structured Programming"] }) 5});
ejecutará la siguiente consulta:
1SELECT * FROM "post" WHERE "titles" IN ('Go To Statement Considered Harmful', 'Structured Programming')
También puede combinar estos operadores con el operador Not
:
1import {Not, MoreThan, Equal} from "typeorm"; 2 3const loadedPosts = await connection.getRepository(Post).find({ 4 likes: Not(MoreThan(10)), 5 title: Not(Equal("About #2")) 6});
ejecutará la siguiente consulta:
1SELECT * FROM "post" WHERE NOT("likes" > 10) AND NOT("title" = 'About #2')