1
votes

Spring-Boot JPA Comment trouver une entité avec une valeur maximale

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?


1 commentaires

Oui, vous pouvez utiliser Spring Data JPA


4 Réponses :


2
votes

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>.


0 commentaires

2
votes

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.


2 commentaires

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 .



0
votes

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  
 }


1 commentaires

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?



0
votes

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 ();


0 commentaires