Spring Data JPA 写SQL语句也可以如此简单

在使用 Spring Data JPA 的时候,通常我们只需要继承 JpaRepository 就能获得大部分常用的增删改查的方法。有时候我们需要自定义一些查询方法,可以写自定义 HQL 语句

像这样

  1. /**
  2.      * 根据关注者id查找所有记录(查找关注的人的id)
  3.      *
  4.      * @param fromUserId
  5.      * @return
  6.      */
  7.     @Query("select toUserId from Relationship where fromUserId =:fromUserId")
  8.     List<Long> findByFromUserId(@Param("fromUserId") Long fromUserId);

 

但是,有时候一些查询比较复杂,当我们把 SQL 语句写好了,却不知道如何转成 HQL 语句,怎么办?

很简单,Spring Data JPA 其实也支持自定义 SQL 语句查询。

比如,我们这里写了一条稍微复杂一些的 SQL 语句。

  1. SELECT DISTINCT t1.from_user_id FROM
  2. (SELECT * FROM relationship WHERE to_user_id = 1)  AS t1
  3. INNER JOIN relationship t2 ON t1.from_user_id = t2.to_user_id

这段 SQL 语句的作用是 查询id=1的用户的互相关注的用户的id。

 

如何让 JPA 帮我们查询呢?

我们查看文档:点此直达

Spring Data JPA 写SQL语句也可以如此简单

发现,只需要在后面加一个 nativeQuery = true 就行,哇,是不是很简单!

 

赶紧试试。

  1. @Query(value = "SELECT DISTINCT t1.to_user_id FROM (SELECT * FROM relationship WHERE from_user_id = ?1)  AS t1 INNER JOIN relationship t2 ON t1.to_user_id = t2.from_user_id ", nativeQuery = true)
  2. List<Long> findFriendsByUserId(Long userId);

 

写个测试方法

  1. package com.liuyanzhao.forum.repository;
  2. import com.liuyanzhao.forum.entity.Relationship;
  3. import org.junit.Before;
  4. import org.junit.Test;
  5. import org.junit.runner.RunWith;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.boot.test.context.SpringBootTest;
  8. import org.springframework.test.context.junit4.SpringRunner;
  9. import java.util.List;
  10. /**
  11.  * @author 言曌
  12.  * @date 2018/4/24 下午9:56
  13.  */
  14. @SpringBootTest
  15. @RunWith(SpringRunner.class)
  16. public class RelationshipRepositoryTest {
  17.     @Autowired
  18.     private RelationshipRepository relationshipRepository;
  19.     @Before
  20.     public void save() {
  21.         relationshipRepository.save(new Relationship(1L,2L));
  22.         relationshipRepository.save(new Relationship(1L,3L));
  23.         relationshipRepository.save(new Relationship(1L,4L));
  24.         relationshipRepository.save(new Relationship(2L,1L));
  25.         relationshipRepository.save(new Relationship(2L,4L));
  26.         relationshipRepository.save(new Relationship(3L,1L));
  27.     }
  28.     @Test
  29.     public void findFriendsByUserId() throws Exception {
  30.         List<Long> ids = relationshipRepository.findFriendsByUserId(1L);
  31.         System.out.println(ids);
  32.     }
  33. }

 

最终查得结果 [2,3],答案正确

 

 

有坑

我们上面查到是[2,3],这两个数都是 bigint 类型的,如果我们将这两个数传参到其他方法里,比如

  1. /**
  2.   * 根据id集合查询用户
  3.   *
  4.   * @param ids
  5.   * @return
  6.   */
  7.  List<User> findByIdIn(List<Long> ids);

会出现参数类型不匹配。

所以,这里我们可以把 id 的 Long 类型改成 Integer 类型,数据表里的 bigint 改成int

 

文档直达:https://docs.spring.io/spring-data/jpa/docs/1.10.2.RELEASE/reference/html/#jpa.query-methods.at-query

  • 微信
  • 交流学习,有偿服务
  • weinxin
  • 博客/Java交流群
  • 资源分享,问题解决,技术交流。群号:590480292
  • weinxin
言曌

发表评论

:?::razz::sad::evil::!::smile::oops::grin::eek::shock::???::cool::lol::mad::twisted::roll::wink::idea::arrow::neutral::cry::mrgreen:

目前评论:1   其中:访客  1   博主  0

    • avatar 毛毛

      赞,有用