最近在hibernate下,两张表多对多关联,使用HQL语句进行增删改查时遇到很多问题,现在小结一下:
有两张表格,角色表(role)和权限表(right),中间表是(base_role_right)
(1)删除某个角色,由于role与right表已经相关联,如果直接删除角色的话,会将right表中的记录同时删除
解决思路:通过获取前台传递的参数roleId找到要删除的对象,然后先将此对象中与right相关联的属性rights先移除,然后再删除对象,
这样right表中信息便不会被同步删除
代码:domain层,Role.java里面声明rights
<span style="font-size:12px;"><span style="background-color: rgb(255, 255, 255);"> //角色与权限多对多关系,中间表是base_role_right
@ManyToMany(cascade = { CascadeType.MERGE, CascadeType.REMOVE },fetch = FetchType.LAZY)
@JoinTable(name = "base_role_right", joinColumns = { @JoinColumn(name = "roleId", referencedColumnName = "roleId") }, inverseJoinColumns = { @JoinColumn(name = "rightId", referencedColumnName = "rightId") })
<span style="color:#FF6666;">private List<Right> rights = new ArrayList<Right>();</span>// 对应权限的集合
BizImpl层:
</span></span><pre name="code" class="java"><span style="background-color: rgb(255, 255, 255);"> public void deleteRoles(String roleIds) {
//将传递的字符串参数去掉分隔符“,”
String[] id_array = roleIds.split(",");
int[] ids = new int[id_array.length];
for(int i=0 ;i < id_array.length; i++){//遍历所有的roleId
ids[i]=Integer.parseInt(id_array[i]);//将字符串转化为整型数
Role role = roleDao.get(ids[i]);
List<Right> rightList = role.getRights();
//先将role里面的所有right移除,再删除角色,确保权限表里面的记录不被同时删除
<span style="color:#FF6666;"> for (Iterator<Right> iter = rightList.iterator(); iter.hasNext();) {
iter.next();
iter.remove();
} </span>
roleDao.delete(ids[i]);
}</span>
}
(2)查询时需要两张表里面的数据,此时要采用连接(这里采用右连接查询某个用户角色还没添加的权限)
public JSONData<Right> queryNoAddPermission(Integer roleId,Integer start,Integer limit){
StringBuffer hql = new StringBuffer();
Map<String, Object> map = new HashMap<String, Object>();
<span style="color:#FF6666;">hql.append("SELECT NEW com.eaglec.wx.base.view.NoAddPermissionParam(r.rightId,r.text,r.idxtype) FROM Right r WHERE 1=1 AND"
+ " r.rightId NOT IN (select rt.rightId FROM Role re right join re.rights rt WHERE 1=1 AND re.roleId=:roleId)");</span>
if(roleId != null){
map.put("roleId",roleId);//使用HQL语句中含有参数的话,必须为此参数赋值,否知运行时报错
}
return rightDao.outJSONData(hql.toString(), map,start, limit);
}