Je pense que le moyen le plus simple de le faire est d'utiliser ce qu'on appelle la projection. Il peut mapper les résultats de la requête aux interfaces. L'utilisation SqlResultSetMapping
est peu pratique et rend votre code moche :).
Un exemple tiré du code source JPA de Spring Data:
public interface UserRepository extends JpaRepository<User, Integer> {
@Query(value = "SELECT firstname, lastname FROM SD_User WHERE id = ?1", nativeQuery = true)
NameOnly findByNativeQuery(Integer id);
public static interface NameOnly {
String getFirstname();
String getLastname();
}
}
Vous pouvez également utiliser cette méthode pour obtenir une liste de projections.
Consultez cette entrée de documentation JPA Spring Data pour plus d'informations sur les projections.
Note 1:
N'oubliez pas que votre User
entité est définie comme normale - les champs de l'interface projetée doivent correspondre aux champs de cette entité. Sinon, le mappage de champ peut être interrompu ( getFirstname()
peut renvoyer la valeur du nom de famille et cetera).
Note 2:
Si vous utilisez la SELECT table.column ...
notation, définissez toujours des alias correspondant aux noms de l'entité. Par exemple, ce code ne fonctionnera pas correctement (la projection renverra des valeurs nulles pour chaque getter):
@Query(value = "SELECT user.firstname, user.lastname FROM SD_User user WHERE id = ?1", nativeQuery = true)
NameOnly findByNativeQuery(Integer id);
Mais cela fonctionne bien:
@Query(value = "SELECT user.firstname AS firstname, user.lastname AS lastname FROM SD_User user WHERE id = ?1", nativeQuery = true)
NameOnly findByNativeQuery(Integer id);
En cas de requêtes plus complexes, je préfère utiliser JdbcTemplate
un référentiel personnalisé à la place.