TypeOrm - Usando Vistas

PUBLICADO EL 12 Nov 2020, POR VICTOR CORNEJO

Todos nos hemos alegrado cuando descubrimos los ORM's por la facilidad con la que podemos acceder a la base de datos. Con el tiempo nuestras aplicaciones empiezan a volverse mas complejas y mas de alguna vez hemos llegado a la conclusión que debemos ejecutar una sentencia SQL en modo crudo ( Raw SQL Queries ).

TypeORM te permite crear una vista desde el código de programación y acceder a la misma sin necesidad de ejecutar de forma Raw la sentencia.

Beneficios

  • Control de los cambios, definitivamente si la vista se define desde el código de programación no nos tenemos que preocupar por saber cual es la ultima versión de esa vista.

  • No tenemos que manejar diferentes complementaciones para cada base de datos; si tuviéramos que hacerlo, basta con ajustar la generación del "Query" que describe la vista.

  • Fácil de implementar y comprensión para los programadores que le den soporte.

La forma de implementar es sencilla y semejante a la definición de las tablas o "entities".

Paso 1. Definición de la Vista.

Las @ViewEntity() son clases que permiten acceder a las vistas de nuestra base de datos.

// Definicion del query que invocara la vista. Ejemplo para POSTGRESQL
const query = `SELECT a.id, a.name, a.email from public.users a`

@ViewEntity({
    schema: 'public',
    name: 'vw_user_info',
    expression: query
})
export class UserInfoView {
    @ViewColumn( { name: 'id' })
    id: number;
    
    @ViewColumn( { name: 'name' })
    name: string;
    
    @ViewColumn( { name: 'email' })
    email: string;
}

Paso 2. Definición del Repositorio.

import { Connection } from 'typeorm';
import { UserInfoView } from '../views/user.info.view';

export const UserInfoViewRepository = [{
        provide: 'USER_INFO_VIEW_REPOSITORY',
        useFactory: (connection: Connection) => 
                        connection.getRepository(UserInfoView),
        inject: ['DATABASE_CONNECTION']
    }
]

Paso 3. Utilización del repositorio en un servicio.

import { Inject, Injectable } from '@nestjs/common';

@Injectable()
export class UserInfoService {

    constructor(
        @Inject('USER_INFO_VIEW_REPOSITORY')
        private userInfoRepository: Repository<UserInfoView>
    ) {}
    
    public findByEmail(email: string): Promise<UserInfoView) {
        const condition: {
            where: {
                email: email
            }
        };
        
        return this.userInfoRepository.findOne(condition);
    }
}

Última actualización