Story:hibernate(或SQL或HQL)查找擁有另一個集合的子集的對象
我擁有此用戶 - >角色 - >特權機制。每個用戶都有一些角色。每個角色都有一些特權。
CREATE TABLE user (id int);
INSERT INTO user VALUES (1);
INSERT INTO user VALUES (2);
INSERT INTO user VALUES (3);
CREATE TABLE role (id int);
INSERT INTO role VALUES (100);
INSERT INTO role VALUES (200);
CREATE TABLE user__role (user_id int, role_id int);
INSERT INTO user__role VALUES (1, 100);
INSERT INTO user__role VALUES (2, 200);
CREATE TABLE privilege (id int);
INSERT INTO privilege VALUES (1000);
INSERT INTO privilege VALUES (2000);
INSERT INTO privilege VALUES (3000);
INSERT INTO privilege VALUES (4000);
CREATE TABLE role__privilege (role_id int, privilege_id int);
INSERT INTO role__privilege VALUES (100, 1000);
INSERT INTO role__privilege VALUES (100, 3000);
INSERT INTO role__privilege VALUES (200, 2000);
(用戶,角色和權限都有名字和一些其他的東西。但我忽略他們保持例子簡單)
然後我有一些房間。您需要某些特權才能進入房間。
CREATE TABLE room (id int);
INSERT INTO room VALUES (11);
INSERT INTO room VALUES (22);
INSERT INTO room VALUES (33);
INSERT INTO room VALUES (44);
INSERT INTO room VALUES (55);
CREATE TABLE room__privilege (room_id int, privilege_id int);
INSERT INTO room__privilege VALUES (11, 1000);
INSERT INTO room__privilege VALUES (11, 3000);
INSERT INTO room__privilege VALUES (22, 2000);
INSERT INTO room__privilege VALUES (33, 3000);
INSERT INTO room__privilege VALUES (55, 1000);
INSERT INTO room__privilege VALUES (55, 2000);
INSERT INTO room__privilege VALUES (55, 3000);
這是處理:如果用戶具有房間所需的所有權限,則用戶可以進入房間。如果一個房間不需要特權,那麼任何人都可以進入。
在對象方面,我有一些像
class User {
int id;
Set<Role> roles;
}
class Role {
int id;
Set<Privilege> privileges;
}
class Room {
int id;
Set<Privilege> requirements;
}
現在我有一個用戶,我想知道這個用戶可以輸入艙的說ID = 1。我如何用hibernate標準或SQL實現這一點?
我想我可以使用一些查詢來查找用戶擁有的所有權限(並將它們存儲在一個集合中)。然後我發現那些需求是這個集合的子集的房間。但我找不到適合的標準/限制。此外,在閱讀了一些在stackoverflow中的帖子後,我感覺整個事情可以用一個SQL/HQL查詢來完成。
任何人都可以給我一些幫助,請。提前致謝!
更新1
我一直在做這個了整整一夜。我設法得到一些結果
SELECT requirements.room_id
FROM (
SELECT room.id AS room_id, room__privilege.privilege_id FROM room
JOIN room__privilege ON room__privilege.room_id = room.id
) requirements
INNER JOIN (
SELECT room__privilege.room_id, COUNT(*) as count FROM room__privilege
GROUP BY room__privilege.room_id
) hits ON requirements.room_id = hits.room_id
INNER JOIN (
SELECT user.id AS user_id, rp.privilege_id FROM user
JOIN user__role ur ON user.id = ur.user_id
JOIN role__privilege rp ON ur.role_id = rp.role_id
) up ON requirements.privilege_id = up.privilege_id
WHERE up.user_id = 1
GROUP BY requirements.room_id, up.user_id, hits.count HAVING COUNT(*) = hits.count
UNION
SELECT room.id FROM room
WHERE room.id NOT IN (
SELECT room_id FROM room__privilege
);
這似乎給我什麼,我想要的。我似乎相當複雜,我不確定我是否可以將其包裝到標準或HQL中。
我檢查了@Rajesh和@Erik Hart的答案。他們的疑問似乎也適用於這個例子。我要做一個分析,看哪一個表現更好。
非常感謝您的幫助。對此,我真的非常感激。如果有人知道如何通過標準或HQL來實現,請不要猶豫,回覆。乾杯!!!
在這個例子中用戶id = 1只能進入房間11,44吧?如果是的話,將嘗試SQL – radar 2014-09-23 17:37:46
用戶1應該能夠輸入11(需要1000和3000),33(需要3000),44(不需要) – user2375809 2014-09-23 18:36:46