我有 Hibernate 请求,它返回要显示的元素列表。我需要检查当前用户是否能够查看每个返回的元素。我可以这样做
for (Element e : elements) {
SecurityUtils.getSubject().hasPermission("element:view:" + e.id);
}
但是此代码将为每个元素生成 x 个对数据库的请求。所以检查的速度将是O(n)。
如何改进我的解决方案?是否有可能获得 O(1) 的速度?
有一个在 Subject 上调用的方法,如果 Subject 拥有所有权限isPermittedAll(String ...)
,它将返回。true
虽然,老实说,我不知道它在数据库查询方面效率多少(如果有的话)。
shiro 支持缓存,如果你这个列表构造很多,你可以使用这种类型的动作。 http://shiro.apache.org/caching.html
鉴于您的示例,您可能想要执行以下操作:
String[] permissions = new String[elements.size()];
for (int i = 0; i < elements.size(); i++) {
permissions[i] = "element:view:" + e.id;
}
boolean[] allowed = SecurityUtils.getSubject().isPermitted(permissions);
List<Element> allowedElements = new ArrayList<Element>();
for (int i = 0; i < elements.size(); i++) {
//1:1 match on entries in allowed to elements
if (allowed[i]) {
allowedElements.add(elements[i]);
}
}
//allowedElements now contains the set of elements the user is permitted to access
return allowedElements;
我使用的 Subject API 方法在这里:boolean[] isPermitted(String... permissions)
这种方法的缺点是您实际上最终会迭代您的元素列表两次。但是,由于您不必为每个元素进行数据库调用,因此您最终会保存。
需要注意的一点是,您的运行时间可能会根据您的安全领域的实现方式而改变。