Vai al contenuto principale

Repository personalizzati

Traduzione Beta Non Ufficiale

Questa pagina è stata tradotta da PageTurner AI (beta). Non ufficialmente approvata dal progetto. Hai trovato un errore? Segnala problema →

Puoi creare un repository personalizzato contenente metodi specifici per interagire con il database. Ad esempio, supponiamo di voler implementare un metodo findByName(firstName: string, lastName: string) che cerchi gli utenti in base a nome e cognome. La collocazione ideale per questo metodo è un Repository, così da poterlo richiamare come userRepository.findByName(...). Questo risultato si ottiene proprio attraverso i repository personalizzati.

Esistono diverse modalità per creare repository personalizzati.

Come creare un repository personalizzato?

È pratica comune assegnare un'istanza di repository a una variabile esportata globalmente, utilizzandola poi nell'intera applicazione, come nell'esempio:

// user.repository.ts
export const UserRepository = dataSource.getRepository(User)

// user.controller.ts
export class UserController {
users() {
return UserRepository.find()
}
}

Per estendere le funzionalità di UserRepository puoi utilizzare il metodo .extend della classe Repository:

// user.repository.ts
export const UserRepository = dataSource.getRepository(User).extend({
findByName(firstName: string, lastName: string) {
return this.createQueryBuilder("user")
.where("user.firstName = :firstName", { firstName })
.andWhere("user.lastName = :lastName", { lastName })
.getMany()
},
})

// user.controller.ts
export class UserController {
users() {
return UserRepository.findByName("Timber", "Saw")
}
}

Utilizzo dei repository personalizzati nelle transazioni

Le transazioni hanno un proprio ambito di esecuzione: possiedono un query runner dedicato, un entity manager e istanze di repository specifiche. Per questo motivo, l'utilizzo dell'entity manager globale (del data source) e dei repository standard non funziona nelle transazioni. Per eseguire correttamente le query nell'ambito transazionale è obbligatorio utilizzare l'entity manager fornito e il suo metodo getRepository. Per impiegare repository personalizzati all'interno di una transazione, devi utilizzare il metodo withRepository dell'istanza dell'entity manager fornita:

await connection.transaction(async (manager) => {
// in transactions you MUST use manager instance provided by a transaction,
// you cannot use global entity managers or repositories,
// because this manager is exclusive and transactional

const userRepository = manager.withRepository(UserRepository)
await userRepository.createAndSave("Timber", "Saw")
const timber = await userRepository.findByName("Timber", "Saw")
})