关于Spring Data Jpa的分页、跨表查询

分页

jqa的query使用原生sql查询(nativeQuery = true)的时候不支持排序的,需要在sql里面加上:ORDER BY ?#{#pageable}
Spring Data Jpa本地查询(带分页方式)

Example

@Query(value = "select u.* from user u INNER JOIN project_user pu " +
        "ON pu.project_id=?1 AND pu.user_id=u.user_id ORDER BY ?#{#pageable}",
        countQuery = "select count(*) from user u INNER JOIN project_user pu " +
                "ON pu.project_id=?1 AND pu.user_id=u.user_id",
        nativeQuery = true)
Page<User> findByProjectId(String projectId, Pageable pageable);

注意:
countQuery中不要写成:

“select count(u.*) from user u INNER JOIN project_user pu ON pu.project_id=?1 AND pu.user_id=u.user_id”

count(u.*)会报错,应该写为count(*)

About other

ORDER BY ?#{#pageable}用于 Pageable. countQuery 用于Page<>。
Dmitry Stolbov回答

如果不写countQuery,那么jpa会默认在select的参数上加count,例如上面例子就会成为 select (u.*) …
这样就会报错。所以应该写出自定义的countQuery


跨表查询

难点

JpaRepository中的接口方法返回类型只能是实体类或者Object[](值作为字符串列表返回,没有key),如果这时想要通过跨表连接查询,返回一个非实体类的DTO,就会报错。

Solution

利用HQL可以轻松解决。例如:

@Query(
 value = "select new com.test.dto.GetProjectUserDto(u.userId, u.name, u.displayName, r.name, pu.description) from User u, ProjectUser pu, Role r " +
         "where pu.projectId=?1 AND pu.userId=u.userId AND pu.roleId=r.id",
 countQuery = "select count(*) from User u, ProjectUser pu, Role r " +
         "where pu.projectId=?1 AND pu.userId=u.userId AND pu.roleId=r.id")
    Page<GetProjectUserDto> findByProjectId(String projectId, Pageable pageable);

注意:

  • @Query内写的是HQL;SQL中的inner joinon在这里改为,where
  • HQL内的写的是实体类的类名、字段名(不是数据库中的表名、字段名)
  • DTO必须有对应的constructor,否则会报错找不到。推荐用lombok的注解@AllArgsConstructor,简单高效。
  • 不必再像上面在HQL中加入ORDER BY ?#{#pageable}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值