Spring Data JPA Pagination - 从方法名称创建查询

时间:2017-09-08 17:37:52

标签: java spring jpa pagination spring-data-jpa

我在User和PhoneNumber之间有一个OneToMany关系。因此,一个用户可以拥有多个电话号码。

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

出于分页的目的,我正在使用Spring Paging和Sorting Repository。到目前为止,我已经尝试过像这样的SQL LIKE通配符。

    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);
    }

问题是LIKE似乎不起作用。无论如何,它返回与用户相关的所有电话号码,它将忽略我传入的任何内容,因此“%987%”。因此,如果我有2个与用户X关联的电话号码(987123和321432),它将返回两者而不是仅返回“987123”。

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

电话号码类

@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 个答案:

答案 0 :(得分:0)

尝试包含关键字:

    [ProvideAutoLoad(UIContexts.LoadContext)]
    [ProvideUIContextRule(UIContexts.LoadContext,
        "RightFileTypeOpen",
        "(CSharpFileOpen | VBFileOpen)",
        new[] { "CSharpFileOpen", "VBFileOpen" },
new[] { "ActiveEditorContentType:CSharp", "ActiveEditorContentType:Basic" })]

文档:https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repository-query-keywords

答案 1 :(得分:0)

首先,不应允许客户过滤数据。数据过滤逻辑应该在服务器端实现。因此,应该重写默认的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
         */
    }
}

这完成了你的第一部分

ur question.

For searching by partial phone number define following

@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);
相关问题