1

我们正在处理与@ManyToMany用户和角色的关系,并希望通过使用 Pageable 接口进行分页以获取具有关联角色的所有用户。它只考虑用户表上的分页记录计数,不考虑角色表记录。但理想情况下,在 RDBMS 中,实际记录数将是在将用户和角色表之间的连接结果展平之后。

参考表关系

使用PageableinfindAll方法并传递页面配置时,如下所示:

pageno: 0 and pageSize:1

    Pageable paging = PageRequest.of(0, 1);
    userRepository.findAll(paging);

它给出的结果如下 

参考分页响应

从技术上讲,当我们展平结果时有 3 条记录,但 pageable 认为这是 1 条记录,这是不正确的。这是预期的行为吗?

有没有办法在展平查询结果集后获得分页?

4

1 回答 1

1

是的。这是有意的。数据作为嵌套对象映射到 Java 对象。因此,5 个用户记录的可分页将返回 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);
    }
于 2020-07-23T18:11:56.103 回答