日常踩坑_JPA聚合查询
背景提要
需求是要进行分组并统计每组的数量,本来以为JPA有GroupBy的语法的,看了一圈才发现原来没有这个语法,只能通过自己写sql的方式
这其中又分为写原生sql(即nativeQuery = true
)和写JPA规范中的 JPQL(即nativeQuery = false
)
推荐使用JPA规范中的 JPQL,因为原生sql,最终的结果集只能用不带类型的List承接,不能用自定义的实体类的List来承接
解决
准备承接结果的实体类,注意一定要加构造函数,否则赋值的时候找不到会报错
package com.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class GroupCountVO {
//分组名称
private String groupName;
//每组数量
private Long count;
}
Dao层SQL查询(这里还有个时间的坑)
@Repository
public interface ImportantCaseDao extends BaseJpaRepository<ImportantCase> {
@Query("select new com.vo.GroupCountVO(date_format(z.riqi, '%Y-%m'),count(z.id)) from ImportantCase z" +
" where DATE_FORMAT(z.riqi,'%Y-%m')>=:startMonth and DATE_FORMAT(z.riqi,'%Y-%m')<= :endMonth " +
" group by date_format(z.riqi, '%Y-%m')")
List<GroupCountVO> countAllByMonth(@Param("startMonth") String startMonth, @Param("endMonth") String endMonth);
@Query("select new com.vo.GroupCountVO(date_format(z.riqi, '%Y-%m-%d'),count(z.id)) from ImportantCase z" +
" where z.riqi>= :start and z.riqi<= :end " +
" group by date_format(z.riqi, '%Y-%m-%d') ")
List<GroupCountVO> countAllByDay(@Param("start") Date start, @Param("end") Date end);
}
看到了吗?本来如果是原生的SQL的话,countAllByDay中可以直接使用String来传时间的,但在这里,必须使用Date类型,否则会报类型无法转换的错
对了,还有,如果使用这种方式来自定义SQL的话,@Where还是生效的,会自动添加@Where注解添加的SQL语句
踩坑结束,祝你快乐!