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

avatar 2018年04月25日10:00:18 7 28541 views
博主分享免费Java教学视频,B站账号:Java刘哥

在使用 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 帮我们查询呢? 我们查看文档:点此直达

发现,只需要在后面加一个 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.  
  3. import com.liuyanzhao.forum.entity.Relationship;
  4. import org.junit.Before;
  5. import org.junit.Test;
  6. import org.junit.runner.RunWith;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.boot.test.context.SpringBootTest;
  9. import org.springframework.test.context.junit4.SpringRunner;
  10.  
  11. import java.util.List;
  12.  
  13.  
  14. /**
  15.  * @author 言曌
  16.  * @date 2018/4/24 下午9:56
  17.  */
  18.  
  19. @SpringBootTest
  20. @RunWith(SpringRunner.class)
  21. public class RelationshipRepositoryTest {
  22.  
  23.  
  24.     @Autowired
  25.     private RelationshipRepository relationshipRepository;
  26.  
  27.  
  28.     @Before
  29.     public void save() {
  30.         relationshipRepository.save(new Relationship(1L,2L));
  31.         relationshipRepository.save(new Relationship(1L,3L));
  32.         relationshipRepository.save(new Relationship(1L,4L));
  33.         relationshipRepository.save(new Relationship(2L,1L));
  34.         relationshipRepository.save(new Relationship(2L,4L));
  35.         relationshipRepository.save(new Relationship(3L,1L));
  36.     }
  37.  
  38.  
  39.  
  40.     @Test
  41.     public void findFriendsByUserId() throws Exception {
  42.         List<Long> ids = relationshipRepository.findFriendsByUserId(1L);
  43.         System.out.println(ids);
  44.     }
  45.  
  46. }

  最终查得结果 [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
avatar

发表评论

avatar 登录者:匿名
匿名评论,评论回复后会有邮件通知

  

已通过评论:1   待审核评论数:0
  1. avatar 豆豆

    赞,有用