Pageable 没有给出与@ManyToMany 关系的预期结果
Pageable not giving expected results with @ManyToMany relationship
我们正在处理 @ManyToMany
与用户和角色的关系,并希望通过使用 Pageable 接口进行分页以获取具有关联角色的所有用户。它仅考虑用户 Table 上分页的记录数,不考虑角色 table 记录。但理想情况下,在 RDBMS 中,实际记录计数将在扁平化用户和角色之间的连接结果之后 table。
在 findAll
方法中使用 Pageable
并按如下方式传递页面配置时:
pageno: 0 and pageSize:1
Pageable paging = PageRequest.of(0, 1);
userRepository.findAll(paging);
它给出的结果如下
从技术上讲,当我们展平结果时有 3 条记录,但分页将其视为 1 条记录,这是不正确的。这是有意为之的行为吗?
有没有什么方法可以把查询的结果集展平后分页?
是的。这是有意的。数据作为嵌套对象映射到 Java 个对象。因此,5 个用户记录的分页将 return 5 个用户,无论每个用户拥有的角色数量如何。
要通过用户和角色的组合限制基于记录计数的分页,您必须在存储库方法中的查询中添加用户和角色之间的连接,并从用户和角色中获取列(就像我们在 SQL).
下面的代码适合我
用户实体
public class User
{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long userId;
@NonNull
@Column(unique = true, name= "user_name")
private String userName;
@NonNull
private String password;
@NonNull
private boolean status;
@NonNull
private boolean passwordExpired;
@ManyToMany(fetch=FetchType.EAGER,cascade = CascadeType.ALL)
@JoinTable(name = "user_role", joinColumns = {
@JoinColumn(name = "userId", referencedColumnName = "userId") }, inverseJoinColumns = {
@JoinColumn(name = "role_name", referencedColumnName = "name") })
@BatchSize(size = 20)
private Set<Role> roles = new HashSet<>();
//Get and set
}
角色实体
public class Role {
private static final long serialVersionUID = 1L;
@NotNull
@Size(max = 50)
@Id
@Column(length = 50,unique=true)
private String name;
//get and set
}
存储库
@Repository
public interface UserRepo extends JpaRepository<User, Long>
{
@Query(value="SELECT u.userName,r.name FROM User u left join u.roles r")
public ArrayList<User> findByrole(Pageable paging);
}
服务方式
public ArrayList<User> findByrole()
{
// TODO Auto-generated method stub
Pageable paging = PageRequest.of(0, 4);
return uRepo.findByrole(paging);
}
我们正在处理 @ManyToMany
与用户和角色的关系,并希望通过使用 Pageable 接口进行分页以获取具有关联角色的所有用户。它仅考虑用户 Table 上分页的记录数,不考虑角色 table 记录。但理想情况下,在 RDBMS 中,实际记录计数将在扁平化用户和角色之间的连接结果之后 table。
在 findAll
方法中使用 Pageable
并按如下方式传递页面配置时:
pageno: 0 and pageSize:1
Pageable paging = PageRequest.of(0, 1);
userRepository.findAll(paging);
它给出的结果如下
从技术上讲,当我们展平结果时有 3 条记录,但分页将其视为 1 条记录,这是不正确的。这是有意为之的行为吗?
有没有什么方法可以把查询的结果集展平后分页?
是的。这是有意的。数据作为嵌套对象映射到 Java 个对象。因此,5 个用户记录的分页将 return 5 个用户,无论每个用户拥有的角色数量如何。
要通过用户和角色的组合限制基于记录计数的分页,您必须在存储库方法中的查询中添加用户和角色之间的连接,并从用户和角色中获取列(就像我们在 SQL).
下面的代码适合我
用户实体
public class User
{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long userId;
@NonNull
@Column(unique = true, name= "user_name")
private String userName;
@NonNull
private String password;
@NonNull
private boolean status;
@NonNull
private boolean passwordExpired;
@ManyToMany(fetch=FetchType.EAGER,cascade = CascadeType.ALL)
@JoinTable(name = "user_role", joinColumns = {
@JoinColumn(name = "userId", referencedColumnName = "userId") }, inverseJoinColumns = {
@JoinColumn(name = "role_name", referencedColumnName = "name") })
@BatchSize(size = 20)
private Set<Role> roles = new HashSet<>();
//Get and set
}
角色实体
public class Role {
private static final long serialVersionUID = 1L;
@NotNull
@Size(max = 50)
@Id
@Column(length = 50,unique=true)
private String name;
//get and set
}
存储库
@Repository
public interface UserRepo extends JpaRepository<User, Long>
{
@Query(value="SELECT u.userName,r.name FROM User u left join u.roles r")
public ArrayList<User> findByrole(Pageable paging);
}
服务方式
public ArrayList<User> findByrole()
{
// TODO Auto-generated method stub
Pageable paging = PageRequest.of(0, 4);
return uRepo.findByrole(paging);
}