[英]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.