2017-09-08 1 views
0

User와 PhoneNumber 사이에 OneToMany 관계가 있습니다. 따라서 한 명의 사용자가 여러 개의 전화 번호를 가질 수 있습니다.스프링 데이터 JPA 페이지 매김 - 메서드 이름에서 쿼리 생성

프런트 엔드에서 로그인 한 사용자의 전화 번호 만 가져 오거나 사용자가 관리자 인 경우 모든 사용자 전화 번호를 표시해야합니다. 이 부분을 구현할 수 있었지만 문제는 다음과 같습니다. 프론트 엔드에서 사용자는 "전화 번호"로 검색 상자를 갖습니다. 따라서 사용자 나 관리자가 987을 검색하면 (처음 3 자리), '987'을 포함하고 그의 프로필과 연결된 전화 번호가 표시되어야합니다. 사용자가 관리자 인 경우 '987'이 포함 된 모든 사용자 수를 표시해야합니다.

페이지 매김을 위해 스프링 페이징 및 정렬 리포지토리를 사용하고 있습니다. 지금까지 나는 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 %"를 전달할 것을 무시할 것입니다. 따라서 사용자 X와 연결된 2 개의 전화 번호 (987123 및 321432)가있는 경우 "987123"대신 둘 다 반환됩니다.

Doe의 누구나 내가 이것을 쿼리 할 수있는 방법을 알고 있지만 대신 페이지 가능 객체 인 Spring을 얻으려고합니다. 메서드 이름의 쿼리 작성은 목적에 맞을 정도로 강력하지 않지만 프론트 엔드의 모든 나머지 구현으로 페이징 가능한 객체가 필요하다고 생각합니다. 서비스 계층은이를 기반으로합니다. 일에 누군가가

사용자 클래스

@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 클래스

을 내가 JPA 기준을 사용해야하지만 내가 페이징 객체를 얻을 수있는 대가로 그렇게 그것을 수행하는 방법 아무 생각도 없어 제안
@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 
+0

키워드가 포함 되었습니까? – Barath

답변

0

우선 클라이언트는 데이터를 필터링해서는 안됩니다. 데이터 필터링 로직은 서버 측에서 구현되어야합니다. 적절한 로직 기능을 작성 follows-로

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

userService는 일반적인 구조를 가질 것이다 : 따라서 다음과 같이 findall은()이 동작을 통합하기를 오버라이드 (override) 할 필요가 기본

@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); 
관련 문제