在使用 Spring Data JPA 的时候,通常我们只需要继承 JpaRepository 就能获得大部分常用的增删改查的方法。
有时候我们需要自定义一些查询方法,可以写自定义 HQL 语句 像这样
- /**
- * 根据关注者id查找所有记录(查找关注的人的id)
- *
- * @param fromUserId
- * @return
- */
- @Query("select toUserId from Relationship where fromUserId =:fromUserId")
- List<Long> findByFromUserId(@Param("fromUserId") Long fromUserId);
但是,有时候一些查询比较复杂,当我们把 SQL 语句写好了,却不知道如何转成 HQL 语句,怎么办?
很简单,Spring Data JPA 其实也支持自定义 SQL 语句查询。 比如,我们这里写了一条稍微复杂一些的 SQL 语句。
- SELECT DISTINCT t1.from_user_id FROM
- (SELECT * FROM relationship WHERE to_user_id = 1) AS t1
- INNER JOIN relationship t2 ON t1.from_user_id = t2.to_user_id
这段 SQL 语句的作用是 查询id=1的用户的互相关注的用户的id。
如何让 JPA 帮我们查询呢? 我们查看文档:点此直达
发现,只需要在后面加一个 nativeQuery = true 就行,哇,是不是很简单! 赶紧试试。
- @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)
- List<Long> findFriendsByUserId(Long userId);
写个测试方法
- package com.liuyanzhao.forum.repository;
- import com.liuyanzhao.forum.entity.Relationship;
- import org.junit.Before;
- import org.junit.Test;
- import org.junit.runner.RunWith;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.boot.test.context.SpringBootTest;
- import org.springframework.test.context.junit4.SpringRunner;
- import java.util.List;
- /**
- * @author 言曌
- * @date 2018/4/24 下午9:56
- */
- @SpringBootTest
- @RunWith(SpringRunner.class)
- public class RelationshipRepositoryTest {
- @Autowired
- private RelationshipRepository relationshipRepository;
- @Before
- public void save() {
- relationshipRepository.save(new Relationship(1L,2L));
- relationshipRepository.save(new Relationship(1L,3L));
- relationshipRepository.save(new Relationship(1L,4L));
- relationshipRepository.save(new Relationship(2L,1L));
- relationshipRepository.save(new Relationship(2L,4L));
- relationshipRepository.save(new Relationship(3L,1L));
- }
- @Test
- public void findFriendsByUserId() throws Exception {
- List<Long> ids = relationshipRepository.findFriendsByUserId(1L);
- System.out.println(ids);
- }
- }
最终查得结果 [2,3],答案正确 有坑 我们上面查到是[2,3],这两个数都是 bigint 类型的,如果我们将这两个数传参到其他方法里,比如
- /**
- * 根据id集合查询用户
- *
- * @param ids
- * @return
- */
- List<User> findByIdIn(List<Long> ids);
会出现参数类型不匹配。
所以,这里我们可以把 id 的 Long 类型改成 Integer 类型,数据表里的 bigint 改成int
文档直达:
2018年04月25日 15:40:55
赞,有用