【发布时间】:2016-08-12 02:48:42
【问题描述】:
这是一个RBAC模块,有三个基本表user、role和permission以及中间映射表user_role和role_permission。
@Entity
@Table(name = "USER")
public class User implements Serializable {
@Id
private String userId;
...
}
@Entity
@Table(name = "ROLE")
public class Role implements Serializable {
@Id
private String roleId;
...
}
@Entity
@Table(name = "PERMISSION")
public class Permission implements Serializable {
@Id
private String permissionId;
...
}
@Entity
@Table(name = "USER_ROLE")
public class UserRole implements Serializable {
@Id
@GenericGenerator(name = "uuidGenerator", strategy = "uuid")
@GeneratedValue(generator = "uuidGenerator")
@Column(name = "ID")
private String id;
@ManyToOne
@JoinColumn(name = "USERID")
private User user;
@ManyToOne
@JoinColumn(name = "ROLEID")
private Role role;
...
}
@Entity
@Table(name = "ROLE_PERMISSION")
public class RolePermission implements Serializable {
@Id
private String id;
@ManyToOne
@JoinColumn(name = "PERMISSIONID")
private Permission permission;
@ManyToOne
@JoinColumn(name = "ROLEID")
private Role role;
...
}
现在我想通过 user.id 查找所有权限,SQL 表示如下:
select rp.* from Role_Permission rp,User_Role ur where ur.roleId = rp.roleId and ur.userId = :id
但通过 Criteria API:
public Predicate toPredicate(Root<RolePermission> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
List<Predicate> predicates = new ArrayList<Predicate>();
if (StringUtil.isNotEmpty(userId)) {
final Root<UserRole> userRoleRoot = criteriaQuery.from(UserRole.class);
Join<RolePermission,UserRole> join = root.join("role", JoinType.INNER);
Predicate predicate = criteriaBuilder.equal(join.get("roleId"), root.get("role").get("roleId"));
predicate = criteriaBuilder.and(predicate,criteriaBuilder.equal(userRoleRoot.<UserRole>get("user").get("id"), userId));
predicates.add(predicate);
}
return criteriaBuilder.and(predicates.toArray(new Predicate[]{}));
}
查询构建结果为:
select count(rolepermis0_.id) as col_0_0_ from role_permission rolepermis0_ inner join role role2_ on rolepermis0_.roleid=role2_.roleid cross join user_role userrole1_ where role2_.roleid=rolepermis0_.roleid and userrole1_.userid=?
但是为什么在这里role_permission 交叉加入user_role,role_permission 如何通过条件API 加入user_role 呢?
非常感谢。
【问题讨论】:
-
首先,您的 JPQL 无效。你在一个关系上做一个 JOIN,而不是一个类。所以从“select rp from RolePermission rp inner join rp.role r”开始。使用它来决定使用什么标准
-
JPQL 只是一个假代码。我真的只需要找到 RolePermission,SQL 表达如下:select rp.* from RolePermission rp,UserRole ur where ur.roleId = rp.roleId and ur.userId = :id
-
首先如果它是“假代码”然后不要发布它。其次,如果你想添加一个谓词(“criteriaBuilder.equal”),你应该使用“join”而不是“root.get().get()”。此外,如果您只有 RolePermission 中的关系,那么这需要成为您在 Criteria 中的“候选人”......是吗???
-
应该使用“加入”吗?你的意思是“谓词谓词 = criteriaBuilder.equal(join.get("roleId"), join);" ?
-
再次查看您的模型,然后您现在发布的 SQL ......您的 SQL 意味着 CROSS JOIN。此外,您无法在 JPA 中指定 INNER JOIN,因为 UserRole 和 RolePermission 之间没有关系(因为 JPQL 和 Criteria 从关系工作),所以这些类之间的连接也只能是 CROSS JOIN
标签: jpa criteria-api