当前位置: 首页 > 知识库问答 >
问题:

Spring数据JPA分页-从方法名称创建查询

牛华皓
2023-03-14

我在用户和电话号码之间有一种“一对一”的关系。因此,一个用户可以有多个电话号码。

在前端,我必须只提取登录用户的电话号码,或者如果用户是管理员,我必须显示所有用户的电话号码。我已经设法实现了这一部分,但我遇到的问题如下:在前端,用户还有一个“电话号码”搜索框。因此,如果用户或管理员搜索987(比如前3位数字),则应显示包含“987”且与其个人资料相关联的任何电话号码。如果用户是管理员,我应该显示包含“987”的所有用户的所有号码。

出于分页目的,我使用Spring分页和排序存储库。到目前为止,我已经尝试了类似SQL的通配符。

    public interface UserRepository extends JpaRepository<User, Integer> {
            //this is used for fetching phone numbers by userName, if user is admin I call findAll()
            Page<User> findByUserName(String userName, Pageable pageable);

            //this is used for fetching phone numbers by username by phoneNo LIKE
            Page<User> findByUserNameAndPhoneNumbersPhoneNoLike(String userName,String phoneNo, Pageable pageable);
    }

Doe的任何人都知道我如何查询这个,但作为得到Spring可分页对象的回报?我认为从方法名称创建查询的功能还不够强大,无法满足需要,但我仍然需要可分页对象,因为前端的所有其他实现都是基于此的,服务层就是基于此。工作中有人建议我应该使用JPA标准,但我不知道怎么做,所以作为回报,我可以获得可分页对象

用户类

@Entity
    @Table(name="USER")
    public class User implements Serializable{

        @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
        private Integer id;

        @NotEmpty
        @Column(name="USER_ID", unique=true, nullable=false)
        private String userName;

        @OneToMany(fetch = FetchType.EAGER)
        @JoinColumn(name="USER_ID")
        private Set<PhoneNumer> phoneNumbers;

        @NotEmpty
        @JsonIgnore
        @ManyToMany(fetch = FetchType.LAZY)
        @JoinTable(name = "USER_USER_PROFILE",
                joinColumns = { @JoinColumn(name = "USER_ID") },
                inverseJoinColumns = { @JoinColumn(name = "USER_PROFILE_ID") })
        private Set<UserProfile> userProfiles = new HashSet<UserProfile>();
        //Getters and Setters

PhoneNumber类

@Entity
@Table(name = "PHONE_NUMBER")
public class PhoneNumber {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID")
    private long id;

    @Column(name = "PHONE_NUMBER")
    private String phoneNo;
    //Getters and Setters

共有2个答案

程景胜
2023-03-14

首先,不应允许客户端过滤数据。数据过滤逻辑应在服务器端实现。因此,应覆盖默认findAll()以合并此行为,如下所示:

@Override
@Query(
        "select p from User u join u.phoneNumbers p where "
        + "u.userId = ?#{@userService.getUserId()} or "
        + "?#{@userService.isAdmin()}"
)
Page findAll(Pageable pageable);

userService将具有以下通用结构-使用适当的逻辑填写函数:

@Service("userService")
@Transactional
public class UserServiceJPA {

    public Integer getUserId(){
        /**
         * This function should return current logged in user's id from db
         */
    }
    
    public boolean isAdmin(){
        /**
         * This function should return true or false based on current logged in user
         */
    }
}

这就完成了问题的第一部分。
要通过部分电话号码定义进行搜索,请使用以下代码。

@Query(
            "select p from PhoneNumber p where "
            + "("
            + "     p.user.userId = ?#{@userService.getUserId()} or "
            + "     ?#{@userService.isAdmin()} "
            + ") "
            + "and "
            + "p.phoneNo like :#{#partialPhone}%"
    )
    @RestResource(path="partialPhone")
    Page findMatchingPhoneNumbers(
            @Param("partialPhone")String partialPhone,
            Pageable pageable);
米裕
2023-03-14

尝试包含关键字:

Containing
findByFirstnameContaining
… where x.firstname like ?1 (parameter bound wrapped in %)

Page<User> findByUserNameAndPhoneNumbersPhoneNoContaining(String userName,String phoneNo, Pageable pageable);

文档:https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repository-查询关键字

 类似资料:
  • 问题内容: 我正在使用Spring Data JPA,当我用来定义一个 WITHOUT 的查询时,它可以工作: 但是,如果我添加第二个参数,则将无法正常工作,Spring将解析该方法的名称,然后抛出 异常 。这是错误吗? 问题答案: 在Spring论坛上提出了一个类似的问题,指出要应用分页,必须派生第二个子查询。因为子查询引用的是相同的字段,所以您需要确保查询对引用的实体/表使用别名。这意味着您在

  • 错误: unsatisfiedDependencyException:创建名为“app controller”的bean时出错:通过字段“service”表示的未满足的依赖关系;嵌套异常为org.springframework.beans.factory.unsatisfieddependencyexception:创建名为“jenkins service”的bean时出错:通过字段“repo”表

  • 我想使用Spring数据投影技术,以便仅从表中提取一些字段(而不是表中的所有字段)。 如留档(https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections)中所述,我创建了一个简单的界面,例如: 但我在使用它时遇到了一些问题。 问题1: 首先,我想使用名称findAll()创建一个查询,查找只有两个字

  • 我想列一份订单,比如 这是我的密码 我使用的是Java Spring Boot和Spring Data JPA,我遇到了如下错误 你们能帮帮我吗!我想我在《findAllOrderBycreateDateDesc》中错了。谢谢对不起我的英语。这是我第一次发布我的问题。除息的

  • 我想知道是否可以不需要@Query注释,让Spring Data根据我的方法名称和下面实体关系的方法参数构造JPA查询。我想检索与特定Item相关的ItemLocations列表。我尝试了下面的签名,但没有@Query它不起作用。传入Item.id而不是Item对象本身是否更合适(高效/有效)? Spring数据版本:1.3.4。发布 工作Spring数据存储库API: 所需的Spring数据存储