I'd like to create customizable query that output aggregate values. I know three ways to get and execute a query, but none of them seem to suffice. The queries I want to build look something like this:
Select max(category), min(price) as minprice from mytable where k='v' group by category
tldr: skip 1 & 2.
- SQL as String
private NamedParameterJdbcTemplate template; template.query("select ..." , new MapSqlParameterSource("...", "...") , rs -> {...rs.getString("minprice")...
- Pro: we can access the result from the query
- Con: It is not using a query builder: we have to build the "select..." string ourselves.
- Using repositories
public interface MytableRepository extends CrudRepository<Mytable, Integer> { @Query("Select ...") public List<Object[]> findMinMaxPrice(@Param("myParam") String myParam);
- Pro: We can access the result from the query.
- Con: The query is hardcoded
- Using the query builder
Specification<MyTable> spec = Specifications.<>where((mytable, query, cb) -> { Predicate sql = cb.equal(mytable.get("k"), "v"; return sql; } List<Mytable> result = myJpaSpecificationExecutor.findall(spec);
- Pro: It is using the query builder
- Con: The query is not using the groupBy. Since our groupBy query is not returning records of class
Mytable
but aggregate values, I don't see how I can make this work. I start selecting fromMytable
so I think I need to use it as type parameter toSpecification
, but that immediately implies that the result should also be of typeMyTable
, doesn't it?
How can I use a query builder with a flexible result type?