标签:ssh
1、角色和权限的关系
系统中可以存在多个角色,每个角色可以自由的组合系统定义的权限集合,即角色和权限的关系是多对多的关系。为了保存这种多对多关系,需要一个“角色权限表”来保存。
角色和权限的多对多关系,可以进行拆分:“角色”与“角色权限”的关系、“权限”和“角色权限”的关系。“角色”与“角色权限”的关系是一对多的关系;而“权限”与“角色权限”的关系也是一对多的关系。
这里的特殊之处是:由于系统的权限的数目比较少,以常量的形式存储于类文件中,因此不存在“权限”表;而“角色”和“角色权限”是需要保存的,因而需要“角色表”和“角色权限表”,所以进行的操作,则是维护“角色表”和“角色权限表”之间一对多的关系。
将系统中需要使用到的权限定义出来(PrivilegeStatics类):粗粒度的分配各个子系统的访问权限;这些权限可以定义在常量文件中。
package com.rk.core.constant; import java.util.HashMap; import java.util.Map; public class PrivilegeStatics { /*----------------------系统权限集合--------------------------*/ 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"; 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, "我的空间"); } }
2、entity->dao->service->action->config
2.1、实体类和映射文件(*.hbm.xml)
Role.java
由于“角色”与“角色权限”之间是一对多的关系,因此Role实体类中包含Set<RolePrivilege> rolePrivileges对象。
package com.rk.tax.entity; import java.io.Serializable; import java.util.Set; import org.apache.commons.lang3.StringUtils; public class Role implements Serializable { private String roleId; private String name; private String state; private Set<RolePrivilege> rolePrivileges; //角色状态 public static String ROLE_STATE_VALID = "1";//有效 public static String ROLE_STATE_INVALID = "0";//无效 public Role() { } public Role(String roleId) { this.roleId = roleId; } public String getRoleId() { return roleId; } public void setRoleId(String roleId) { this.roleId = roleId; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getState() { return state; } public void setState(String state) { this.state = state; } public Set<RolePrivilege> getRolePrivileges() { return rolePrivileges; } public void setRolePrivileges(Set<RolePrivilege> rolePrivileges) { this.rolePrivileges = rolePrivileges; } @Override public boolean equals(Object obj) { if(this == obj) return true; if(obj == null) return false; if(this.getClass() != obj.getClass()) return false; Role other = (Role) obj; if(!StringUtils.equals(this.roleId, other.roleId)) return false; if(!StringUtils.equals(this.name, other.name)) return false; if(!StringUtils.equals(this.state, other.state)) return false; return true; } }
Role.hbm.xml
注意:在对rolePrivileges属性进行映射的时候,它的inverse属性为true,表示“在操作Role对象时,不会对角色表 和 角色权限表 之间的关系进行映射”,lazy="false"表示不使用懒加载,cascade="save-update,delete"表示进行级联的保存、更新和删除(换句话说,如果保存Role对象时,如果rolePrivileges有值,也会保存相应的RolePrivilege对象;有一点,我很在意,就是在删除的时候,它是否能够级联删除呢?在我印象中,是不能删除的。我是这样理解的:虽然很多人都在说cascade和inverse之间没有关系,而我认为cascade要优先于inverse。如果不能进行删除,我想可能是因为Role没有办法解除两者之间的关系。如果能够删除,则表示我猜测错误了。)。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.rk.tax.entity" auto-import="true"> <class name="Role" table="T_Roles"> <id name="roleId" column="role_id" type="string" length="32"> <generator class="uuid.hex"></generator> </id> <property name="name" column="name" type="string" length="20" not-null="true"></property> <property name="state" column="state" type="string" length="1"></property> <set name="rolePrivileges" inverse="true" lazy="false" cascade="save-update,delete"> <key column="role_id"></key> <one-to-many class="RolePrivilege"/> </set> </class> </hibernate-mapping>
RolePrivilege.java,它表示“角色权限表”,而这里的特殊之处,就是它没有直接存储两个属性,而是使用了一个类来代表一个共同主键。
package com.rk.tax.entity; public class RolePrivilege { private RolePrivilegeId id; public RolePrivilege() { } public RolePrivilege(RolePrivilegeId id) { this.id = id; } public RolePrivilegeId getId() { return id; } public void setId(RolePrivilegeId id) { this.id = id; } }
RolePrivilegeId.java ,在这里需要注意的是它存储的属性是Role类型的变量role,而不是String类型的变量role_id。在这里回顾一下Role.java中定义了Set<RolePrivilege> rolePrivileges属性,也就是说Role类对象中可以直接(由于映射文件中设置了lazy="false")查看Role拥有的“角色权限”信息,而这里保存Role类型的role对象,这样做的目的是,我们能够通过RolePrivilege对象直接找到它所属于的角色信息。
package com.rk.tax.entity; import java.io.Serializable; import org.apache.commons.lang3.StringUtils; public class RolePrivilegeId implements Serializable { private Role role; private String code; public RolePrivilegeId() { } public RolePrivilegeId(Role role, String code) { this.role = role; this.code = code; } public Role getRole() { return role; } public void setRole(Role role) { this.role = role; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((code == null) ? 0 : code.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (this.getClass() != obj.getClass()) return false; RolePrivilegeId other = (RolePrivilegeId) obj; if(!StringUtils.equals(this.code, other.code)) return false; if (this.role == null && other.role != null) { return false; } else if (!this.role.equals(other.role)){ return false; } return true; } }
RolePrivilege.hbm.java
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.rk.tax.entity" auto-import="true"> <class name="RolePrivilege" table="R_Role_Privilege"> <composite-id name="id" class="RolePrivilegeId"> <key-many-to-one name="role" column="role_id" lazy="false" class="Role"></key-many-to-one> <key-property name="code" column="code" type="string" length="20"></key-property> </composite-id> </class> </hibernate-mapping>
2.2、dao层
这里只有RoleDao,基于的操作是继承于BaseDao<Role>对象,而它只有一个方法deleteRolePrivilegeByRoleId,是通过roleId来删除相应的角色权限信息。
RoleDao.java
package com.rk.tax.dao; import com.rk.core.dao.BaseDao; import com.rk.tax.entity.Role; public interface RoleDao extends BaseDao<Role>{ void deleteRolePrivilegeByRoleId(String roleId); }
RoleDaoImpl.java
package com.rk.tax.dao.impl; import org.hibernate.Query; import com.rk.core.dao.impl.BaseDaoImpl; import com.rk.tax.dao.RoleDao; import com.rk.tax.entity.Role; public class RoleDaoImpl extends BaseDaoImpl<Role> implements RoleDao { public void deleteRolePrivilegeByRoleId(String roleId) { Query query = getSession().createQuery("delete from RolePrivilege where id.role.roleId=?"); query.setParameter(0, roleId); query.executeUpdate(); } }
2.3、service层
RoleService.java
package com.rk.tax.service; import java.io.Serializable; import java.util.List; import com.rk.tax.entity.Role; public interface RoleService { //新增 public void save(Role entity); //更新 public void update(Role entity); //根据id删除 public void delete(Serializable id); //根据id查找 public Role findById(Serializable id); //查找列表 public List<Role> findAll(); }
RoleServiceImpl.java
package com.rk.tax.service.impl; import java.io.Serializable; import java.util.List; import javax.annotation.Resource; import org.springframework.stereotype.Service; import com.rk.tax.dao.RoleDao; import com.rk.tax.entity.Role; import com.rk.tax.service.RoleService; @Service("roleService") public class RoleServiceImpl implements RoleService { @Resource private RoleDao roleDao; public void save(Role entity) { roleDao.save(entity); } public void update(Role entity) { //1、删除该角色对应的所有权限 roleDao.deleteRolePrivilegeByRoleId(entity.getRoleId()); //2、更新角色及其权限 roleDao.update(entity); } public void delete(Serializable id) { roleDao.delete(id); } public Role findById(Serializable id) { return roleDao.findById(id); } public List<Role> findAll() { return roleDao.findAll(); } }
2.4、action层
RoleAction.java
package com.rk.tax.action; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.annotation.Resource; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Controller; import com.opensymphony.xwork2.ActionContext; import com.rk.core.action.BaseAction; import com.rk.core.constant.PrivilegeStatics; import com.rk.tax.entity.Role; import com.rk.tax.entity.RolePrivilege; import com.rk.tax.entity.RolePrivilegeId; import com.rk.tax.service.RoleService; @Controller("roleAction") @Scope("prototype") public class RoleAction extends BaseAction { /***** 1、业务数据 *****/ private List<Role> roleList; private Role role; private String[] privilegeIds; /***** 2、业务实现类 *****/ @Resource private RoleService roleService; /***** 3、页面响应操作 *****/ //列表页面 public String listUI(){ //加载权限集合 ActionContext.getContext().getContextMap().put("privilegeMap", PrivilegeStatics.PRIVILEGE_MAP); roleList = roleService.findAll(); return "listUI"; } //跳转到新增页面 public String addUI(){ //加载权限集合 ActionContext.getContext().getContextMap().put("privilegeMap", PrivilegeStatics.PRIVILEGE_MAP); return "addUI"; } //保存新增 public String add(){ if(role != null){ //处理权限保存 if(privilegeIds != null){ Set<RolePrivilege> set = new HashSet<RolePrivilege>(); for(int i=0;i<privilegeIds.length;i++){ set.add(new RolePrivilege(new RolePrivilegeId(role, privilegeIds[i]))); } role.setRolePrivileges(set); } roleService.save(role); } return "list"; } //跳转到编辑页面 public String editUI(){ //加载权限集合 ActionContext.getContext().getContextMap().put("privilegeMap", PrivilegeStatics.PRIVILEGE_MAP); if(role != null && role.getRoleId()!=null){ role = roleService.findById(role.getRoleId()); //处理回显 if(role.getRolePrivileges() != null && role.getRolePrivileges().size()>0){ privilegeIds = new String[role.getRolePrivileges().size()]; int i = 0; for(RolePrivilege rp : role.getRolePrivileges()){ privilegeIds[i] = rp.getId().getCode(); } } } return "editUI"; } //保存编辑 public String edit(){ if(role != null){ //处理权限保存 if(privilegeIds != null){ Set<RolePrivilege> set = new HashSet<RolePrivilege>(); for(int i=0;i<privilegeIds.length;i++){ set.add(new RolePrivilege(new RolePrivilegeId(role, privilegeIds[i]))); } role.setRolePrivileges(set); } roleService.update(role); } return "list"; } //删除 public String delete(){ if(role != null && role.getRoleId() != null){ roleService.delete(role.getRoleId()); } return "list"; } //批量删除 public String deleteSelected(){ if(selectedRow != null){ for(String id : selectedRow){ roleService.delete(id); } } return "list"; } // {{ public List<Role> getRoleList() { return roleList; } public void setRoleList(List<Role> roleList) { this.roleList = roleList; } public Role getRole() { return role; } public void setRole(Role role) { this.role = role; } public String[] getPrivilegeIds() { return privilegeIds; } public void setPrivilegeIds(String[] privilegeIds) { this.privilegeIds = privilegeIds; } // }} }
2.5、config
2.5.1、entity层配置
就是对实体类进行hibernate的映射,即*.hbm.xml文件
2.5.2、dao层配置
就是将dao注入到spring 的IOC容器中
bean-dao.xml (注意,在这里没有使用Annotation的方式,是因为它有一个parent属性,对于这一点,我查了查,目前超过自己的知识范围,看不太懂,而之后的service、action都使用Annotation的方式注入到spring的容器中。)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="userDao" class="com.rk.tax.dao.impl.UserDaoImpl" parent="baseDao"></bean> <bean id="roleDao" class="com.rk.tax.dao.impl.RoleDaoImpl" parent="baseDao"></bean> </beans>
2.5.3、service层
就是将service注入到spring的IOC容器当中
bean-service.xml这里去掉了之前的注册方式,而是使用注解扫描。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 开启注解扫描 --> <context:component-scan base-package="com.rk.tax.service.impl"></context:component-scan> </beans>
2.5.4、action层
action设置到注册到spring和struts当中。
bean-action.xml 使用注解方式对bean进行注册的方便之处,就是假如UserAction当中涉及到了UserService和RoleService,我们只需要在两个类型的变量上添加@Resource就可以完成注册,而不需要修改spring的xml文件。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 开启注解扫描 --> <context:component-scan base-package="com.rk.tax.action"></context:component-scan> </beans>
struts-role.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <package name="role_package" namespace="/tax" extends="base-default"> <action name="role_*" class="roleAction" method="{1}"> <result name="{1}">/WEB-INF/jsp/tax/role/{1}.jsp</result> <result name="list" type="redirectAction"> <param name="actionName">role_listUI</param> </result> </action> </package> </struts>
标签:ssh
原文地址:http://lsieun.blog.51cto.com/9210464/1840147