Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to use column name as a parameter in a query using Spring Data JPA?

I'm writing an application for data visualization of NBA stats. I'm using Spring Boot + MySql database. I'm trying to find smallest and largest value from each column with the condition that a player had to play at least 10 games. In order to do that I can write methods like this:

@Repository
public interface PerGameStatsRepository extends JpaRepository<PerGameStats, PerGameStatsId> {

@Query(value = "SELECT MAX(stats.pts) FROM PerGameStats stats WHERE stats.gamesPlayed >= 10")
        BigDecimal findMaxAmountOfPoints();

@Query(value = "SELECT MIN(stats.pts) FROM PerGameStats stats WHERE stats.gamesPlayed >= 10")
        BigDecimal findMinAmountOfPoints();
}

However, the table has about 15 columns like Points, Rebounds, Assists, Blocks etc.(and possibly I'll add more). In order to get the min and max values for each of them I'd have to write 2 methods for each column: 2x15 = 30 total. Is there a way to avoid this repetition and write a method that takes the column name as parameter and based on that executes the proper query? Something like:

// this obviously doesn't work
@Query(value = "SELECT MAX(stats.:#{#fieldName}) FROM PerGameStats stats WHERE stats.gamesPlayed >= 10")
BigDecimal findMaxAmountOfField(String fieldName);
like image 789
Domin0 Avatar asked Dec 18 '25 20:12

Domin0


1 Answers

For this case you'll have to create a custom repository implementation. Something like this should work:

interface CustomizedPerGameStatsRepository {
  BigDecimal findMaxAmountOfField(String fieldName);
}

With the following implementation:

class CustomizedPerGameStatsRepositoryImpl implements CustomizedPerGameStatsRepository { // name has to be ...Impl

  private final EntityManager em;

  @Autowired
  public CustomizedPerGameStatsRepositoryImpl(JpaContext context) {
    this.em = context.getEntityManagerByManagedType(PerGameStats.class);
  }

  public BigDecimal findMaxAmountOfField(String fieldName) {
    return (BigDecimal) em.createQuery("SELECT MAX(" + fieldName + ") FROM PerGameStats stats WHERE stats.gamesPlayed >= 10")
      .getSingleResult();
  }
}

And the change in your repository:

@Repository
public interface PerGameStatsRepository extends JpaRepository<PerGameStats, PerGameStatsId>, CustomizedPerGameStatsRepository {
}
like image 78
derkoe Avatar answered Dec 20 '25 11:12

derkoe



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!