[英]Spring Data JPA Pagination - Query creation from method names
我在 User 和 PhoneNumber 之間有一個 OneToMany 關系。 因此一個用戶可以有多個電話號碼。
在前端,我只需要提取登錄用戶的電話號碼,或者如果用戶是管理員,我必須顯示所有用戶的電話號碼。 我已經設法實現了這部分,但我遇到的問題如下:在前端,用戶還有一個“電話號碼”搜索框。 因此,如果用戶或管理員搜索 987(假設是前 3 位數字),則應顯示包含“987”並與其個人資料相關聯的任何電話號碼。 如果用戶是管理員,我應該顯示包含“987”的所有用戶的所有數字。
出於分頁目的,我使用 Spring Paging and 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”。
有沒有人知道我如何查詢這個但作為回報來獲取 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
嘗試包含關鍵字:
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-query-keywords
首先,不應該允許客戶端過濾數據。 數據過濾邏輯應該在服務器端實現。 因此,默認 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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.