Disons que j'ai deux tables.
select u.ID,max(p.points) from user u, points p where u.id=p.user_id
Comment puis-je utiliser spring-boot jpa pour demander des points utilisateur et maximum comme ceci?
CREATE TABLE user (ID int AUTO_INCREMENT,PRIMARY KEY (ID)); CREATE TABLE points (ID int AUTO_INCREMENT, user_id int, points int,PRIMARY KEY (ID));
Ou des alternatives pour résoudre ce genre de problèmes?
4 Réponses :
En supposant que vous ayez un Référentiel
de User
:
User findFirstByIdOrderByPointPointsDesc(int userId)
Avec une relation avec l'objet Points
:
public class Point { private int id; private User User; private int points; ... }
Je n'ai pas testé, mais vous devriez pouvoir faire:
public class User { private int id; private List<Point> points; ... }
Similaire à exemple 18 dans la documentation .
Le seul problème que vous rencontrez, quelle que soit la requête ou les données Spring, est si vous avez deux utilisateurs avec les mêmes valeurs en points. Si vous avez besoin de plus de logique autour du bris d'égalité, il peut être plus intéressant d'écrire une @Query
(avec votre requête, plus la logique de départage supplémentaire) ou une @NativeQuery code>.
Je crée généralement une classe pour contenir un résultat tel que
@Query(value = "SELECT new com.package.Result (u, MAX (p.points) ) FROM user u JOIN points p ON u.id = p.user_id GROUP BY u") List<Result> getPointsPerUser();
Et j'écris une requête personnalisée dans le référentiel pour récupérer les données
public class Result { private User user; private int votes; // getters and setters }
Remplacez com.package.Result par le chemin approprié vers la classe Result.
Merci pour votre réponse. Mais que faire si j'ai besoin d'autres informations pour enregistrer les points? Par exemple, si j'ai besoin d'un maximum de points et quand l'utilisateur a obtenu ces points?
Si vous avez besoin de plus de colonnes de la table points
, vous pouvez récupérer l'objet points
plutôt que d'utiliser la fonction d'agrégation. Vous pouvez remplacer la sélection par u, p
et supprimer la clause GROUP BY
. Modifiez également la classe Result
pour accepter les points
. De cette façon, vous avez toutes les données dans le tableau. L'inconvénient est que vous devez maintenant trouver le maximum dans la Liste
.
créez un modèle de données.
@Query(select packagename.Data(u.ID,max(p.points) ) from user u, points p where u.id=p.user_id) Data findUserWithMaxVots();
Et écrivez votre requête comme ceci pour obtenir un modèle de données.
public class Data { private int id; private int maxPoints; // getters and setters method }
Merci pour votre réponse. Mais que faire si j'ai besoin d'autres informations pour enregistrer les points? Par exemple, si j'ai besoin d'un maximum de points et quand l'utilisateur a obtenu ces points?
La méthode ci-dessous peut être écrite dans Repo et utilisée comme Transaction comme dans la couche dao, qui sera accessible à partir de la couche de service.
@Query (value = "SELECT max (transactionId) FROM TransactionPayloadInfo") int getMaxTransactionId ();
Oui, vous pouvez utiliser Spring Data JPA