我们直接来看看原型图,看看需求是怎么样的:
这里写图片描述 这里写图片描述我们看到上图,就会发现角色模块主要还是CRUD,唯一不同的就是它不再是单独的实体关系。角色与权限是存在关系的。
之前在Servlet+JSP+JavaBean的时候其实我们已经做过了用户-角色-权限之间的操作【权限管理系统】http://blog.csdn.net/hon_3y/article/details/61926175
角色与权限应该是多对多的关系的。
进一步分析
现在我的权限只有5个,有必要使用数据库表吗???没啥必要吧。权限基本就固定下来了。那多对多的关系怎么维护???之前我们使用数据库表就很好做了呀。设计两个实体,使用中间表来描述它们之间的关系就做出来了。
那现在怎么做呢??一个角色对应多个权限
这里写图片描述我们在数据库中的表就可以这样设计:即使没有权限表,但是我使用了中间表维护了它们的数据。一样可以做到一个角色对应多个权限这样的功能。
这里写图片描述 设计实体类设计权限常量类
我们权限是不需要表的,因此我们把各个权限写下来,使用一个集合装载着就行了。当然啦,他们都应该被设计成常量。我们保存在core模块中【被整个系统用到的】
package zhongfucheng.core.constant;import java.util.HashMap;import java.util.Map;/** * Created by ozc on 2017/5/26. */public class Constant { /*----------------------系统权限集合--------------------------*/ public static String PRIVILEGE_XZGL = "xzgl"; public static String PRIVILEGE_HQFW = "hqfw"; public static String PRIVILEGE_ZXXX = "zxxx"; public static String PRIVILEGE_NSFW = "nsfw"; public static String PRIVILEGE_SPACE = "spaces"; //使用一个Map集合来装载着这些权限。 public static Map<String, String> PRIVILEGE_MAP; static { PRIVILEGE_MAP = new HashMap<String, String>(); PRIVILEGE_MAP.put(PRIVILEGE_XZGL, "行政管理"); PRIVILEGE_MAP.put(PRIVILEGE_HQFW, "后勤服务"); PRIVILEGE_MAP.put(PRIVILEGE_ZXXX, "在线学习"); PRIVILEGE_MAP.put(PRIVILEGE_NSFW, "纳税服务"); PRIVILEGE_MAP.put(PRIVILEGE_SPACE, "我的空间"); }}
import java.util.HashMap;
import java.util.Map;
/**
* Created by ozc on 2017/5/26.
*/
public class Constant {
/*----------------------系统权限集合--------------------------*/
public static String PRIVILEGE_XZGL = "xzgl";
public static String PRIVILEGE_HQFW = "hqfw";
public static String PRIVILEGE_ZXXX = "zxxx";
public static String PRIVILEGE_NSFW = "nsfw";
public static String PRIVILEGE_SPACE = "spaces";
//使用一个Map集合来装载着这些权限。
public static Map<String, String> PRIVILEGE_MAP;
static {
PRIVILEGE_MAP = new HashMap<String, String>();
PRIVILEGE_MAP.put(PRIVILEGE_XZGL, "行政管理");
PRIVILEGE_MAP.put(PRIVILEGE_HQFW, "后勤服务");
PRIVILEGE_MAP.put(PRIVILEGE_ZXXX, "在线学习");
PRIVILEGE_MAP.put(PRIVILEGE_NSFW, "纳税服务");
PRIVILEGE_MAP.put(PRIVILEGE_SPACE, "我的空间");
}
}
设计角色类
我们的角色类应该使用一个Set集合来保存对应的权限数据的,那么Set集合的元素类型是什么呢???想一下…
之前我们在用的时候,如果有权限表。我们在角色中Set集合的元素应该是Privilege类。但是现在是没有权限表的。我们怎么通过角色来获取所有的权限呢??
再看回这样ER图:我们在角色Set集合中保存着角色与关系表这个不就行了吗!!!
这里写图片描述于是我们这样设计:
package zhongfucheng.role.entity;import java.io.Serializable;import java.util.Set;/** * Created by ozc on 2017/5/26. */public class Role implements Serializable { private String roleId; private String state; private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } private Set<RolePrivilege> rolePrivilegeSet; public static String USER_STATE_VALID = "1";//有效, public static String USER_STATE_INVALID = "0";//无效 public String getRoleId() { return roleId; } public void setRoleId(String roleId) { this.roleId = roleId; } public String getState() { return state; } public void setState(String state) { this.state = state; } public Set<RolePrivilege> getRolePrivilegeSet() { return rolePrivilegeSet; } public void setRolePrivilegeSet(Set<RolePrivilege> rolePrivilegeSet) { this.rolePrivilegeSet = rolePrivilegeSet; } public static String getUserStateValid() { return USER_STATE_VALID; } public static void setUserStateValid(String userStateValid) { USER_STATE_VALID = userStateValid; } public static String getUserStateInvalid() { return USER_STATE_INVALID; } public static void setUserStateInvalid(String userStateInvalid) { USER_STATE_INVALID = userStateInvalid; }}
import java.io.Serializable;
import java.util.Set;
/**
* Created by ozc on 2017/5/26.
*/
public class Role implements Serializable {
private String roleId;
private String state;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private Set<RolePrivilege> rolePrivilegeSet;
public static String USER_STATE_VALID = "1";//有效,
public static String USER_STATE_INVALID = "0";//无效
public String getRoleId() {
return roleId;
}
public void setRoleId(String roleId) {
this.roleId = roleId;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public Set<RolePrivilege> getRolePrivilegeSet() {
return rolePrivilegeSet;
}
public void setRolePrivilegeSet(Set<RolePrivilege> rolePrivilegeSet) {
this.rolePrivilegeSet = rolePrivilegeSet;
}
public static String getUserStateValid() {
return USER_STATE_VALID;
}
public static void setUserStateValid(String userStateValid) {
USER_STATE_VALID = userStateValid;
}
public static String getUserStateInvalid() {
return USER_STATE_INVALID;
}
public static void setUserStateInvalid(String userStateInvalid) {
USER_STATE_INVALID = userStateInvalid;
}
}
设计角色与权限关系类
角色与权限关系类只有两个属性:角色的id和权限的code….这两个是外键列。一张表中一定是要有主键列的,于是我们采用的是复合主键的方式。
对于复合主键,它是要让该类维护一个复合主键类的:
将主键所对应属性提取出一个类(称之为主键类),并且主键类需要实现Serializable接口,重写hashCode和equals()方法
public class RolePrivilege implements Serializable { private CompositeKey compositeKey; public CompositeKey getCompositeKey() { return compositeKey; } public void setCompositeKey(CompositeKey compositeKey) { this.compositeKey = compositeKey; }}class RolePrivilege implements Serializable {
private CompositeKey compositeKey;
public CompositeKey getCompositeKey() {
return compositeKey;
}
public void setCompositeKey(CompositeKey compositeKey) {
this.compositeKey = compositeKey;
}
}
复合主键类
按照ER图,我们复合主键就两个属性:role_id和code。。
但是呢,我们想一下需求:在获取角色所有权限的时候,Set集合装载着角色与权限的关系,而角色与权限的关系装载着role_id和code。而很有可能:在我查看角色拥有所有权限的时候,想要得到角色的名称。这里仅仅查出来的是角色id,还要通过角色id得到角色的名称…这样就有点麻烦了。于是我们写成Role对象。到时候就能直接获取了。
package zhongfucheng.role.entity;import java.io.Serializable;/** * Created by ozc on 2017/5/26. */public class CompositeKey implements Serializable { private String code; private Role role; @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; CompositeKey that = (CompositeKey) o; if (code != null ? !code.equals(that.code) : that.code != null) return false; return role != null ? role.equals(that.role) : that.role == null; } @Override public int hashCode() { int result = code != null ? code.hashCode() : 0; result = 31 * result + (role != null ? role.hashCode() : 0); return result; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public Role getRole() { return role; } public void setRole(Role role) { this.role = role; }}
import java.io.Serializable;
/**
* Created by ozc on 2017/5/26.
*/
public class CompositeKey implements Serializable {
private String code;
private Role role;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CompositeKey that = (CompositeKey) o;
if (code != null ? !code.equals(that.code) : that.code != null) return false;
return role != null ? role.equals(that.role) : that.role == null;
}
@Override
public int hashCode() {
int result = code != null ? code.hashCode() : 0;
result = 31 * result + (role != null ? role.hashCode() : 0);
return result;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
}
角色映射表配置
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping> <class name="zhongfucheng.role.entity.Role" table="role"> <id name="roleId" type="java.lang.String"> <column name="roleId" length="32" /> <generator class="uuid.hex" /> </id> <property name="state" type="java.lang.String"> <column name="state" length="1" /> </property> <property name="name" type="java.lang.String"> <column name="name" length="20" not-null="true" /> </property> <!-- 一方维护多方的数据,inverse设置为true,没有控制权限 设置级联保存更新,在保存角色的时候,将权限也保存起来了。 不设置懒加载,直接获取到权限的数据 --> <set name="rolePrivilegeSet" lazy="false" inverse="true" cascade="save-update" > <key> <column name="role_id"></column> </key> <one-to-many class="zhongfucheng.role.entity.RolePrivilege" ></one-to-many> </set> </class></hibernate-mapping>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="zhongfucheng.role.entity.Role" table="role">
<id name="roleId" type="java.lang.String">
<column name="roleId" length="32" />
<generator class="uuid.hex" />
</id>
<property name="state" type="java.lang.String">
<column name="state" length="1" />
</property>
<property name="name" type="java.lang.String">
<column name="name" length="20" not-null="true" />
</property>
<!--
一方维护多方的数据,inverse设置为true,没有控制权限
设置级联保存更新,在保存角色的时候,将权限也保存起来了。
不设置懒加载,直接获取到权限的数据
-->
<set name="rolePrivilegeSet" lazy="false" inverse="true" cascade="save-update" >
<key>
<column name="role_id"></column>
</key>
<one-to-many class="zhongfucheng.role.entity.RolePrivilege" ></one-to-many>
</set>
</class>
</hibernate-mapping>
------ - - - -更新
上面我们是将inverse属性设置为true的,但是下面的代码还是使用了一的一方来维护多个一方的数据。这样是不合理的。
角色与权限映射表配置
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping> <class name="zhongfucheng.role.entity.RolePrivilege" table="role_privilege"> <composite-id name="id" class="zhongfucheng.role.entity.CompositeKey"> <key-many-to-one name="role" class="zhongfucheng.role.entity.Role" lazy="false"> <column name="role_id "></column> </key-many-to-one> <key-property name="code" type="java.lang.String"> <column name="code"></column> </key-property> </composite-id> </class></hibernate-mapping>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="zhongfucheng.role.entity.RolePrivilege" table="role_privilege">
<composite-id name="id" class="zhongfucheng.role.entity.CompositeKey">
<key-many-to-one name="role" class="zhongfucheng.role.entity.Role" lazy="false">
<column name="role_id "></column>
</key-many-to-one>
<key-property name="code" type="java.lang.String">
<column name="code"></column>
</key-property>
</composite-id>
</class>
</hibernate-mapping>
Role模块的CRUD
没啥好说的,我们在User模块中已经写过了。我们可以直接复制过来,然后将不要的功能去掉。
dao-->service--->action这样改完,就有了Role模块的CRUD了。
最后:
添加模块
把权限的集合带过去给JSP页面显示出来,JSP使用Struts的checkbox进行遍历【很好用】
public String addUI() { ActionContext.getContext().getContextMap().put("privilegeMap", Constant.PRIVILEGE_MAP); return "addUI"; }
ActionContext.getContext().getContextMap().put("privilegeMap", Constant.PRIVILEGE_MAP);
return "addUI";
}
使用checkbox标签遍历
<tr> <td class="tdBg" width="200px">角色权限:</td> <td> <%-- checkboxlist:自动把Map集合遍历出来,生成对应的key value,Map集合的key作为checkbox的key,value作为checkbox的value list:集合 name:把数据带过去给服务器 --%> <s:checkboxlist list="#privilegeMap" name="privilegeIds"/> </td> </tr>
<td class="tdBg" width="200px">角色权限:</td>
<td>
<%--
checkboxlist:自动把Map集合遍历出来,生成对应的key value,Map集合的key作为checkbox的key,value作为checkbox的value
list:集合
name:把数据带过去给服务器
--%>
<s:checkboxlist list="#privilegeMap" name="privilegeIds"/>
</td>
</tr>
这里写图片描述
这里写图片描述
/************数据自动封装权限的id*************************/ private String[] privilegeIds; public String[] getPrivilegeIds() { return privilegeIds; } public void setPrivilegeIds(String[] privilegeIds) { this.privilegeIds = privilegeIds; }
private String[] privilegeIds;
public String[] getPrivilegeIds() {
return privilegeIds;
}
public void setPrivilegeIds(String[] privilegeIds) {
this.privilegeIds = privilegeIds;
}
处理角色与权限的关系。在配置中使用了级联保存,因此可以直接保存数据
public String add() throws IOException { if (role != null) { //处理角色与权限的关系 if (privilegeIds != null) { HashSet<RolePrivilege> set = new HashSet<>(); //得到每一个权限的值--->entity给出对应的构造方法... for (int i = 0; i < privilegeIds.length; i++) { set.add(new RolePrivilege(new CompositeKey(role, privilegeIds[i]))); } role.setRolePrivilegeSet(set); } roleServiceImpl.save(role); //跳转到列表显示页面 return "list"; } return null; }
if (role != null) {
//处理角色与权限的关系
if (privilegeIds != null) {
HashSet<RolePrivilege> set = new HashSet<>();
//得到每一个权限的值--->entity给出对应的构造方法...
for (int i = 0; i < privilegeIds.length; i++) {
set.add(new RolePrivilege(new CompositeKey(role, privilegeIds[i])));
}
role.setRolePrivilegeSet(set);
}
roleServiceImpl.save(role);
//跳转到列表显示页面
return "list";
}
return null;
}
这里写图片描述
这里写图片描述
显示模块
在显示模块中,主要是显示角色的权限中有点绕…..
角色的权限用set集合保存起来,set集合元素是角色与权限的关系,角色与权限是一个类,该类保存着主键类,主键类存储的是角色和权限code。
我们的目的是:得到角色含有的权限。而目前为止,我们最多只能得到每个权限code值:
而我们想要显示的是权限的名称,于是我们得把权限集合传过去,根据code得到权限的名称:
public String listUI() { roleList = roleServiceImpl.findObjects(); ActionContext.getContext().getContextMap().put("privilegeMap", Constant.PRIVILEGE_MAP); return "listUI"; }
roleList = roleServiceImpl.findObjects();
ActionContext.getContext().getContextMap().put("privilegeMap", Constant.PRIVILEGE_MAP);
return "listUI";
}
JSP页面取值:注意懒加载的问题,设定不要懒加载。不然会出现: java.io.IOException: Stream closed
<s:iterator value="rolePrivilegeSet"> <s:property value="#privilegeMap[compositeKey.code]"/> </s:iterator>
<s:property value="#privilegeMap[compositeKey.code]"/>
</s:iterator>
这里写图片描述
单个删除功能
跳转到Action中处理,把id传递过去…
function doDelete(id) { document.forms[0].action = "${basePath}role/role_delete.action?role.roleId="+id; document.forms[0].submit(); }
document.forms[0].action = "${basePath}role/role_delete.action?role.roleId="+id;
document.forms[0].submit();
}
判断是否为空,不为空就删除。返回到列表页面
2017/5/31 12:59:27 //删除 public String delete() { if (role != null && role.getRoleId() != null) { roleServiceImpl.delete(role.getRoleId()); } return "list"; }5/31 12:59:27 //删除
public String delete() {
if (role != null && role.getRoleId() != null) {
roleServiceImpl.delete(role.getRoleId());
}
return "list";
}
修改模块
数据回显页面,主要就是角色的权限那里怎么回显。我们把所有的权限带过去,用字符串数组记录当前角色有什么权限
//得到所有的权限 ActionContext.getContext().getContextMap().put("privilegeMap", Constant.PRIVILEGE_MAP); //外边已经传了id过来了,我们要找到id对应的Role if (role != null && role.getRoleId() != null) { //直接获取出来,后面JSP会根据Role有getter就能读取对应的信息! role = roleServiceImpl.findObjectById(role.getRoleId()); //得到角色所有的权限,把它封装到privilegeIds字符数组中。 //处理权限回显 if (role.getRolePrivilegeSet() != null) { privilegeIds = new String[role.getRolePrivilegeSet().size()]; int i = 0; for (RolePrivilege rp : role.getRolePrivilegeSet()) { privilegeIds[i++] = rp.getCompositeKey().getCode(); } } } return "editUI";
ActionContext.getContext().getContextMap().put("privilegeMap", Constant.PRIVILEGE_MAP);
//外边已经传了id过来了,我们要找到id对应的Role
if (role != null && role.getRoleId() != null) {
//直接获取出来,后面JSP会根据Role有getter就能读取对应的信息!
role = roleServiceImpl.findObjectById(role.getRoleId());
//得到角色所有的权限,把它封装到privilegeIds字符数组中。
//处理权限回显
if (role.getRolePrivilegeSet() != null) {
privilegeIds = new String[role.getRolePrivilegeSet().size()];
int i = 0;
for (RolePrivilege rp : role.getRolePrivilegeSet()) {
privilegeIds[i++] = rp.getCompositeKey().getCode();
}
}
}
return "editUI";
在JSP页面,使用checkboxlist标签进行遍历。
<s:checkboxlist list="#privilegeMap" name="privilegeIds" ></s:checkboxlist> </s:checkboxlist>
这里写图片描述
得到JSP传递过来的ids,封装成一个set集合。将set集合赋值给role对象。
public String edit() throws IOException { //Struts2会自动把JSP带过来的数据封装到Role对象上 if (role.getRoleId() != null && role != null) { Set<RolePrivilege> set = new HashSet<>(); //得到修改的权限id,封装到set集合中。 for (String privilegeId : privilegeIds) { set.add(new RolePrivilege(new CompositeKey(role, privilegeId))); } role.setRolePrivilegeSet(set); roleServiceImpl.update(role); } return "list"; }
//Struts2会自动把JSP带过来的数据封装到Role对象上
if (role.getRoleId() != null && role != null) {
Set<RolePrivilege> set = new HashSet<>();
//得到修改的权限id,封装到set集合中。
for (String privilegeId : privilegeIds) {
set.add(new RolePrivilege(new CompositeKey(role, privilegeId)));
}
role.setRolePrivilegeSet(set);
roleServiceImpl.update(role);
}
return "list";
}
仅仅是使用update(role)方法是不够的,因此Hibernate在更新操作的时候,会先把数据查询出来。当我们更改角色权限的时候,它会将我们已有的权限保留下来,如果有新的就继续添加。它不会把我们没勾选的剔除的。
因此,我们需要在更新的之前,把当前角色所有的权限给删了。
//在修改之前,把角色的所有权限给删除了。不然会遗留之前的权限下来。 roleDaoImpl.deleteRolePrivilegeByRoleId(role.getRoleId());
roleDaoImpl.deleteRolePrivilegeByRoleId(role.getRoleId());
/*** * 根据角色id删除所有的权限 * */ @Override public void deleteRolePrivilegeByRoleId(String roleId) { String sql = "DELETE FROM RolePrivilege WHERE compositeKey.role.roleId= ?"; Query query = getSession().createQuery(sql); query.setParameter(0, roleId); query.executeUpdate(); }
@Override
public void deleteRolePrivilegeByRoleId(String roleId) {
String sql = "DELETE FROM RolePrivilege WHERE compositeKey.role.roleId= ?";
Query query = getSession().createQuery(sql);
query.setParameter(0, roleId);
query.executeUpdate();
}
效果:
这里写图片描述 用户与角色之间的关系我们在做用户模块的时候,漏掉了最后一个功能。在新增功能中是可以选择角色的。
这里写图片描述用户与角色之间的关系也是多对多
这里写图片描述现在呢,我们的用户表已经是写的了。我们最好就不要修改原有的用户表数据。那我们在不修改用户表代码的情况下,又怎么来实现多对多呢??
跟角色与权限是一样的。使用中间表来维护它们的关系就行了。
用户:user 用户id,名称... 1 用户1 2 用户2 用户角色:user_role 用户id,角色id 1 1 1 2 2 2 角色:role 角色Id,名称 1 管理员 2 一般用户
1 用户1
2 用户2
用户角色:user_role
用户id,角色id
1 1
1 2
2 2
角色:role
角色Id,名称
1 管理员
2 一般用户
设计中间表
public class UserRole implements Serializable { private UserRoleId userRoleId; public UserRoleId getUserRoleId() { return userRoleId; } public void setUserRoleId(UserRoleId userRoleId) { this.userRoleId = userRoleId; }}class UserRole implements Serializable {
private UserRoleId userRoleId;
public UserRoleId getUserRoleId() {
return userRoleId;
}
public void setUserRoleId(UserRoleId userRoleId) {
this.userRoleId = userRoleId;
}
}
主键表
public class UserRoleId implements Serializable { private String user_id; //在使用的时候,Role相关的数据会用得特别多。为了方便使用了Role对象。而user就不需要使用User对象了。 private Role role; @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; UserRoleId that = (UserRoleId) o; if (user_id != null ? !user_id.equals(that.user_id) : that.user_id != null) return false; return role != null ? role.equals(that.role) : that.role == null; } @Override public int hashCode() { int result = user_id != null ? user_id.hashCode() : 0; result = 31 * result + (role != null ? role.hashCode() : 0); return result; } public String getUser_id() { return user_id; } public void setUser_id(String user_id) { this.user_id = user_id; } public Role getRole() { return role; } public void setRole(Role role) { this.role = role; }}class UserRoleId implements Serializable {
private String user_id;
//在使用的时候,Role相关的数据会用得特别多。为了方便使用了Role对象。而user就不需要使用User对象了。
private Role role;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UserRoleId that = (UserRoleId) o;
if (user_id != null ? !user_id.equals(that.user_id) : that.user_id != null) return false;
return role != null ? role.equals(that.role) : that.role == null;
}
@Override
public int hashCode() {
int result = user_id != null ? user_id.hashCode() : 0;
result = 31 * result + (role != null ? role.hashCode() : 0);
return result;
}
public String getUser_id() {
return user_id;
}
public void setUser_id(String user_id) {
this.user_id = user_id;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
}
映射文件
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="zhongfucheng.user.entity.UserRole" table="user_role"> <composite-id name="userRoleId" class="zhongfucheng.user.entity.UserRoleId"> <!--manytoone可以生成外键字段。--> <key-many-to-one name="role" class="zhongfucheng.role.entity.Role" column="role_id" lazy="false"/> <key-property name="user_id" column="user_id" type="java.lang.String"/> </composite-id> </class> </hibernate-mapping>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="zhongfucheng.user.entity.UserRole" table="user_role">
<composite-id name="userRoleId" class="zhongfucheng.user.entity.UserRoleId">
<!--manytoone可以生成外键字段。-->
<key-many-to-one name="role" class="zhongfucheng.role.entity.Role" column="role_id" lazy="false"/>
<key-property name="user_id" column="user_id" type="java.lang.String"/>
</composite-id>
</class>
</hibernate-mapping>
增加模块
在跳转到JSP页面的前,把所有的角色找出来。放到request域对象中,让JSP页面显示出来。
public String addUI() { //把所有的角色查询出来,带过去给JSP页面显示 ActionContext.getContext().getContextMap().put("roleList", roleServiceImpl.findObjects()); return "addUI"; }
//把所有的角色查询出来,带过去给JSP页面显示
ActionContext.getContext().getContextMap().put("roleList", roleServiceImpl.findObjects());
return "addUI";
}
<%-- list是集合对象 name是要带给服务器端的字符串数组。 listkey 是集合元素对象的id listValue 是集合元素对象的名字 --%> <s:checkboxlist list="#roleList" name="userRoleIds" listKey="roleId" listValue="name"/>
<s:checkboxlist list="#roleList" name="userRoleIds" listKey="roleId" listValue="name"/>
这里写图片描述
编辑模块
编辑回显数据
在编辑模块中,需要将该用户所拥有的角色查询出来。然后把查询出来的id值放到数组中。
public String editUI() { //把所有的角色查询出来,带过去给JSP页面显示 ActionContext.getContext().getContextMap().put("roleList", roleServiceImpl.findObjects()); //外边已经传了id过来了,我们要找到id对应的User if (user != null &&user.getId() != null ) { //直接获取出来,后面JSP会根据User有getter就能读取对应的信息! user = userServiceImpl.findObjectById(user.getId()); //通过用户的id得到所拥有UserRole List<UserRole> roles = userServiceImpl.findRoleById(user.getId()); //把用户拥有角色的id填充到数组中,数组最后回显到JSP页面 int i=0; userRoleIds = new String[roles.size()]; for (UserRole role : roles) { userRoleIds[i++] = role.getUserRoleId().getRole().getRoleId(); } } return "editUI"; }
//把所有的角色查询出来,带过去给JSP页面显示
ActionContext.getContext().getContextMap().put("roleList", roleServiceImpl.findObjects());
//外边已经传了id过来了,我们要找到id对应的User
if (user != null &&user.getId() != null ) {
//直接获取出来,后面JSP会根据User有getter就能读取对应的信息!
user = userServiceImpl.findObjectById(user.getId());
//通过用户的id得到所拥有UserRole
List<UserRole> roles = userServiceImpl.findRoleById(user.getId());
//把用户拥有角色的id填充到数组中,数组最后回显到JSP页面
int i=0;
userRoleIds = new String[roles.size()];
for (UserRole role : roles) {
userRoleIds[i++] = role.getUserRoleId().getRole().getRoleId();
}
}
return "editUI";
}
JSP通过checkboxlist进行回显,指定了name值就能够自动判定我们的用户拥有的角色是什么了。
<s:checkboxlist list="#roleList" name="userRoleIds" listKey="roleId" listValue="name"></s:checkboxlist></s:checkboxlist>
这里写图片描述
处理编辑操作
在更新之前,首先删除用户与角色之间的关系【历史遗留问题】,如果不删除,那么用户所拥有的角色就一直保留着。无论你在JSP页面有没有勾选。
public String edit() throws IOException { //Struts2会自动把JSP带过来的数据封装到User对象上 if (user.getId() != null && user != null) { if (headImg != null) { //得到要把头像上传到服务器的路径 javax.servlet.ServletContext servletContext = ServletActionContext.getServletContext(); String realPath = servletContext.getRealPath("upload/user"); //由于用户上传的名字可能会相同,如果相同就被覆盖掉,因此我们要修改上传文件的名字【独一无二】 headImgFileName = UUID.randomUUID().toString() + headImgFileName.substring(headImgFileName.lastIndexOf(".")); FileUtils.copyFile(headImg, new File(realPath, headImgFileName)); //设置图片与用户的关系 user.setHeadImg(headImgFileName); } if (userRoleIds != null) { //删除用户与角色之间的关系【历史遗留问题】 userServiceImpl.deleteUserRoleById(userRoleIds); //保存用户与角色。 userServiceImpl.saveUserAndRole(user,userRoleIds); } } return "list"; }
//Struts2会自动把JSP带过来的数据封装到User对象上
if (user.getId() != null && user != null) {
if (headImg != null) {
//得到要把头像上传到服务器的路径
javax.servlet.ServletContext servletContext = ServletActionContext.getServletContext();
String realPath = servletContext.getRealPath("upload/user");
//由于用户上传的名字可能会相同,如果相同就被覆盖掉,因此我们要修改上传文件的名字【独一无二】
headImgFileName = UUID.randomUUID().toString() + headImgFileName.substring(headImgFileName.lastIndexOf("."));
FileUtils.copyFile(headImg, new File(realPath, headImgFileName));
//设置图片与用户的关系
user.setHeadImg(headImgFileName);
}
if (userRoleIds != null) {
//删除用户与角色之间的关系【历史遗留问题】
userServiceImpl.deleteUserRoleById(userRoleIds);
//保存用户与角色。
userServiceImpl.saveUserAndRole(user,userRoleIds);
}
}
return "list";
}
调用保存用户与角色的关系。如果id不是为空的,那么就执行更新,如果id为空,就执行保存。
@Override public void saveUserAndRole(User user, String... userRoleIds) { //保存或更新用户 if (user.getId() != null) { userDaoImpl.update(user); } else { userDaoImpl.save(user); } //判断有没有把id带过来 if (userRoleIds != null) { for (String userRoleId : userRoleIds) { System.out.println(userRoleId); userDaoImpl.saveUserRole(new UserRole(new UserRoleId(user.getId(), new Role(userRoleId)))); } } }
public void saveUserAndRole(User user, String... userRoleIds) {
//保存或更新用户
if (user.getId() != null) {
userDaoImpl.update(user);
} else {
userDaoImpl.save(user);
}
//判断有没有把id带过来
if (userRoleIds != null) {
for (String userRoleId : userRoleIds) {
System.out.println(userRoleId);
userDaoImpl.saveUserRole(new UserRole(new UserRoleId(user.getId(), new Role(userRoleId))));
}
}
}
总结
如果文章有错的地方欢迎指正,大家互相交流。习惯在微信看技术文章,想要获取更多的Java资源的同学,可以关注微信公众号:Java3y