写再前面的话
1,本文为Java学习五部分第二部分所有项目回顾(前端练习系列-对应Java体系第二部分第三阶段内容)这些再前面的博客里没有。因为感觉把练习作业单独写出来会更好一些。
2,Java知识体系(第五部分第一阶段包括整体快递e站系列,数据库练习系列,程序创新大会报名表系列,Javaweb系列(用户登录,快递e站),SSM系列,微服务系列,实战系列,等)还是应该刚写完作业就写博客的。
3,Javaweb项目是我们学习过程中遇到的第一个比较完整的项目,是一个分水岭。本项目是Javaweb项目的前置项目2。
目录标题
前言-权限模块:
一,什么是权限模块的功能?
“权限”主要功能是描述用户操作业务的范围。
“模块”主要的功能是描述和处理业务,
“权限”根据“模块”设计,“
模块”依据“权限”提供的信息进行控制。用SQL可以简单的描述他们之间的关系 :
“SELECT权限.允许的信息 FROM 模块 WHERE 权限.条件 = TRUE”权限的控制无非是控制用户在应用中的宽度和深度。
二,描述一下权限模块涉及到的数据表?
角色与用户为一对多的关系。
权限管理有权限表,角色表,用户表。因为权限表与角色表是多对多的关系,所以加一个权限角色中间表。用户于角色是一对多的关系。
一个用户登录系统,他只有一种身份,系统判断用户的身份,决定用户可以干什么。(例子应该能懂)
画一下表:
参考:常见模块设计–权限管理(一)
任务目的
理解权限管理的实现逻辑,实现角色管理和人员管理
任务需求
再项目中实现基本的权限管理功能。
过程简单描述:
1.熟悉权限模块的功能
2.理解权限模块涉及的数据表
3.实现用户列表展示
4.实现角色的增删改查
5.实现权限菜单的动态展示
具体思路及在整体代码实现
本模块基于学生管理模块,因此前置代码(即文件中白色标题的代码)详见文章Javaweb项目-快递e站前置1-学生管理(半重点)
基于上一篇代码来进行分析。
前端页面
数据库
通过上文对于用户权限的分析,我们至少要创建4张表。菜单信息表menu、角色信息表role、登录用户信息表users和连接role和menu的中间表middle。
menu
role
users
middle
实体类的定义
用户表已经创建了,中间表实体类不用再bean层创建。所以我们要创建角色类,菜单类。
Role
package com.yhp.bean;
import java.util.List;
public class Role {
@Override
public String toString() {
return "Role{" +
"roleId=" + roleId +
", roleName='" + roleName + '\'' +
", roleState=" + roleState +
", usersList=" + usersList +
", menuList=" + menuList +
'}';
}
private Integer roleId;
private String roleName;
private Integer roleState;
private List<Users> usersList;
private List<Menu> menuList;
public Integer getRoleId() {
return roleId;
}
public void setRoleId(Integer roleId) {
this.roleId = roleId;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public Integer getRoleState() {
return roleState;
}
public void setRoleState(Integer roleState) {
this.roleState = roleState;
}
public List<Users> getUsersList() {
return usersList;
}
public void setUsersList(List<Users> usersList) {
this.usersList = usersList;
}
public List<Menu> getMenuList() {
return menuList;
}
public void setMenuList(List<Menu> menuList) {
this.menuList = menuList;
}
}
Menu
package com.yhp.bean;
import java.util.List;
public class Menu {
private Integer menuId;
private String menuName;
private Integer upmenuId;
@Override
public String toString() {
return "Menu{" +
"menuId=" + menuId +
", menuName='" + menuName + '\'' +
", upmenuId=" + upmenuId +
", state=" + state +
", desc='" + desc + '\'' +
", url='" + url + '\'' +
", roleList=" + roleList +
", secondMenuList=" + secondMenuList +
'}';
}
private Integer state;
public List<Menu> getSecondMenuList() {
return secondMenuList;
}
public void setSecondMenuList(List<Menu> secondMenuList) {
this.secondMenuList = secondMenuList;
}
private String desc;
private String url;
private List<Role> roleList;
private List<Menu> secondMenuList;//保存二级目录
public Integer getMenuId() {
return menuId;
}
public void setMenuId(Integer menuId) {
this.menuId = menuId;
}
public String getMenuName() {
return menuName;
}
public void setMenuName(String menuName) {
this.menuName = menuName;
}
public Integer getUpmenuId() {
return upmenuId;
}
public void setUpmenuId(Integer upmenuId) {
this.upmenuId = upmenuId;
}
public Integer getState() {
return state;
}
public void setState(Integer state) {
this.state = state;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public List<Role> getRoleList() {
return roleList;
}
public void setRoleList(List<Role> roleList) {
this.roleList = roleList;
}
}
users
这个也加上吧,都属于权限规则里的。
package com.yhp.bean;
public class Users {
private Integer userId;
private String loginName;
private String passWord;
private String realName;
private Integer sex;
@Override
public String toString() {
return "Users{" +
"userId=" + userId +
", loginName='" + loginName + '\'' +
", passWord='" + passWord + '\'' +
", realName='" + realName + '\'' +
", sex=" + sex +
", email='" + email + '\'' +
", address='" + address + '\'' +
", phone='" + phone + '\'' +
", cardId='" + cardId + '\'' +
", desc='" + desc + '\'' +
", roleId=" + roleId +
", role=" + role +
'}';
}
private String email;
private String address;
private String phone;
private String cardId;
private String desc;
private Integer roleId;
private Role role;
public Integer getSex() {
return sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getCardId() {
return cardId;
}
public void setCardId(String cardId) {
this.cardId = cardId;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public Integer getRoleId() {
return roleId;
}
public void setRoleId(Integer roleId) {
this.roleId = roleId;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getLoginName() {
return loginName;
}
public void setLoginName(String loginName) {
this.loginName = loginName;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
public String getRealName() {
return realName;
}
public void setRealName(String realName) {
this.realName = realName;
}
}
实体类的表关系
对象是一对一的关系,集合是一对多的关系。
因为一个用户对应一个角色所以再用户类加一个:
private Role role;
一个角色对应多个用户,有多个菜单权限,所以:
private List<Users> usersList;
private List<Menu> menuList;
同样的一个菜单权限对应多个角色
private List<Role> roleList;
菜单也是分级别的:
private List<Menu> secondMenuList;//保存二级目录
代码的层次结构,工具类及配置文件再之前的代码里就写个了。这里略。
附:资料给定创建SQL表语句:
CREATE TABLE `menu` (
`menuid` int NOT NULL AUTO_INCREMENT,
`menuname` varchar(255) DEFAULT NULL,
`upmenuid` int DEFAULT NULL,
`state` int DEFAULT NULL,
`desc` varchar(50) DEFAULT NULL,
`url` varchar(20) DEFAULT NULL,
PRIMARY KEY (`menuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `middle` (
`middleid` int NOT NULL AUTO_INCREMENT,
`roleid` int DEFAULT NULL,
`menuid` int DEFAULT NULL,
PRIMARY KEY (`middleid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `role` (
`roleid` int NOT NULL AUTO_INCREMENT,
`rolename` varchar(10) DEFAULT NULL,
`rolestate` int DEFAULT NULL COMMENT '0 禁⽤ 1 启⽤',
PRIMARY KEY (`roleid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `users` (
`userid` int NOT NULL AUTO_INCREMENT,
`loginname` varchar(10) DEFAULT NULL,
`password` varchar(12) DEFAULT NULL,
`realname` varchar(10) DEFAULT NULL,
`sex` int DEFAULT NULL,
`email` varchar(20) DEFAULT NULL,
`address` varchar(50) DEFAULT NULL,
`phone` varchar(12) DEFAULT NULL,
`cardid` varchar(20) DEFAULT NULL,
`desc` varchar(50) DEFAULT NULL,
`roleid` int DEFAULT NULL,
PRIMARY KEY (`userid`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
具体功能及详细代码实现
用户列表展示
上一篇,我们已经知道了学生管理的实现,这里的代码是基于上一版的。
用户列表展示,首先我们应该写一下用户的servlet,引入对应的url。
@WebServlet(urlPatterns = {"/power/user/users"})
public class UsersServlet extends HttpServlet {
private UsersService usersService=new UsersServiceImpl();
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getParameter("method");
if("select".equals(method)){
select(req,resp);
}
}
}
url是/power/user/users,我们记得改一下前端的url(直接到分页查询方法),
<td>
<a class=menuchild href="power/user/users?method=select" target="right">用户管理</a>
</td>
具体的查询方法:
控制层:
1,接受参数(分页+模糊查,这个之前讲过了,我们这里直接调用)
2,调取service方法
3,存储查询到的值,并跳转到对应界面。
//查询数据(分页)
protected void select(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.接收参数(分页参数+模糊查参数)
String index = req.getParameter("index");
int pageIndex=(index==null||index.length()==0)?1:Integer.parseInt(index);
//2.调取service方法(1.查询数据列表的方法 2.查询总条数的方法)
PageUtil pageUtil = new PageUtil();
List<Users> usersList = usersService.getUsersList(pageIndex, pageUtil.getPageSize());
int total = usersService.total();
pageUtil.setTotal(total);
pageUtil.setPageIndex(pageIndex);
pageUtil.setDataList(usersList);
//3.存值跳页面
req.setAttribute("pi",pageUtil);
req.getRequestDispatcher("list.jsp").forward(req,resp);
}
service::
/**
* 查询用户列表
*/
public List<Users> getUsersList(int pageIndex,int pageSize);
/**
* 查询总条数
*/
public int total();
@Override
public List<Users> getUsersList(int pageIndex, int pageSize) {
return usersDao.getUsersList(pageIndex, pageSize);
}
@Override
public int total() {
return usersDao.total();
}
mapper:
/**
* 查询用户列表
*/
public List<Users> getUsersList(int pageIndex, int pageSize);
/**
* 查询总条数
*/
public int total();
因为查询用户的语句不光有用户,还有用户对应的角色信息,所以需要多表连查。
需要把查询到的角色信息放入到返回的用户结果集。
@Override
public List<Users> getUsersList(int pageIndex, int pageSize) {
List<Users> usersList=new ArrayList<Users>();
try {
String sql="select userid,loginname,realname,rolename from users u,role r where u.roleid=r.roleid limit ?,?";
List params=new ArrayList();
params.add((pageIndex-1)*pageSize);
params.add(pageSize);
resultSet = query(sql, params);
while(resultSet.next()){
//1.取出各表的数据
Users users = new Users();
users.setUserId(resultSet.getInt("userid"));
users.setLoginName(resultSet.getString("loginname"));
users.setRealName(resultSet.getString("realname"));
Role role = new Role();
role.setRoleName(resultSet.getString("rolename"));
//2.建立关系
users.setRole(role);
usersList.add(users);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
closeAll();
}
return usersList;
}
@Override
public int total() {
int total=0;
try {
String sql="select count(1) from users u,role r where u.roleid=r.roleid ";
resultSet = query(sql, null);
while(resultSet.next()){
total=resultSet.getInt(1);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
closeAll();
}
return total;
}
查询结果再页面展示:
forEach循环动态展示数据。
<c:forEach items="${pi.dataList}" var="u" varStatus="sta">
<tr align="center">
<th><input type="checkbox"/></th>
<td>
${sta.count}
</td>
<td>
${u.loginName}
</td>
<td>
<a href="info.html">${u.realName}</a>
</td>
<td>
${u.role.roleName}
</td>
<td>
<a href="edit.html">修改</a>
<a href="javascript:void(0)" onclick="del();return false" class="tablelink"> 删除</a>
</td>
</tr>
</c:forEach>
分页信息动态展示
<div class='MainStyle'><div class=''>
<a href='/power/user/users?method=select' target='_self'>首页</a></div>
<div class=''><a href='/power/user/users?method=select&index=${pi.pageIndex-1<=1?1:pi.pageIndex-1}' target='_self'>上一页</a></div>
<c:forEach begin="1" end="${pi.totalPages}" var="indexa">
<div class= ${pi.pageIndex==indexa?'NowItemStyle':''} >
<a href='/power/user/users?method=select&index=${indexa}' target='_self'>${indexa}</a></div>
</c:forEach>
<div class=''><a href='/power/user/users?method=select&index=${pi.pageIndex+1>=pi.totalPages?pi.totalPages:pi.pageIndex+1}' target='_self'>下一页</a></div>
<div class=''><a href='/power/user/users?method=select&index=${pi.totalPages}' target='_self'>尾页</a></div>
<div class=''>总共<b>${pi.total}</b>条数据</div><div class=''>每页<b>${pi.pageSize}</b>条数据</div>
<div class=''><b>1</b>/3</div><div class='SearchStyle'><input type='text' id='john_Page_Search' onkeydown="if(event.keyCode == 13){page_searchIndex();}"/></div>
<div class=''><input type='button' value='Go' onclick="page_searchIndex()"/></div></div>
<script>
function page_searchIndex(){
var searchText = document.getElementById('john_Page_Search');
var searchIndex = searchText != null && searchText.value != '' ? parseInt(searchText.value) : 0;
if(searchIndex > 0 && searchIndex <= 3) {
window.location='StudentMaterial.aspx?page=' + searchIndex;
} else { alert('需要跳转的页码不能超出范围!'); }
}
</script>
</div>
分页成功:
新增人员
思路分析
和之前写学生新增的思路是一致的,他不是单表查询,学生新增需要班级表,用户新增需要角色表。
思路如下:
1,点击新增人员
2,查询角色列表(servlet)
3,跳转到新增页面,遍历角色信息
4,后台传入的是角色的id到新增方法(insert)
5,新增成功则返回列表数据
6,新增失败则返回查询角色列表的请求。
具体代码就不写了,把之前的学生新镇方法,复制一遍就可以了。
角色列表展示
这里的思路可以查考用户列表展示,这个比那个还简单一些。
url是/power/role/roles,我们改一下前端的url(直接到分页查询方法),
<td>
<a class=menuchild href="power/role/roles?method=select" target="right">用户管理</a>
</td>
控制层方法:
/**
*@ClassName UsersServlet
*@Description ToDo 还有角色列表的删除,修改方法待完成。都过一遍之后再写吧
*@Author Administrator
*@Data 2021/11/3 7:57
*@Version 1.0
**/
@WebServlet(urlPatterns = {"/power/role/roles"})
public class RoleServlet extends HttpServlet {
private RoleService roleService=new RoleServiceImpl();
private MenuService menuService=new MenuServiceImpl();
private MiddleDao middleDao = new MiddleDaoImpl();
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getParameter("method");
if("select".equals(method)){
select(req,resp);
};
}
}
//查询数据(分页)
protected void select(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取参数
//1.1 模糊查条件
String roleName = req.getParameter("roleName");
//1.接收参数(分页参数+模糊查参数)
String index = req.getParameter("index");
int pageIndex=(index==null||index.length()==0)?1:Integer.parseInt(index);
//2.调取service方法(1.查询数据列表的方法 2.查询总条数的方法)
PageUtil pageUtil = new PageUtil();
List<Role> roleList = roleService.getRoleList(roleName,pageIndex, pageUtil.getPageSize());
System.out.println(roleList);
int total = roleService.total();
pageUtil.setTotal(total);
pageUtil.setPageIndex(pageIndex);
pageUtil.setDataList(roleList);
//3.存值跳页面
req.setAttribute("roleName",roleName); //存储模糊查条件
req.setAttribute("pi1",pageUtil);
req.getRequestDispatcher("list.jsp").forward(req,resp);
}
}
service:
public List<Role> getRoleList(String roleName, int pageIndex, int pageSize);
public int total();
@Override
public List<Role> getRoleList(String roleName, int pageIndex, int pageSize) {
return roleDao.getRoleList(roleName,pageIndex, pageSize);
}
@Override
public int total() {
return roleDao.total();
}
mapper:
public List<Role> getRoleList(String roleName, int pageIndex, int pageSize);
public int total();
@Override
public List<Role> getRoleList(String roleName, int pageIndex, int pageSize) {
List<Role> roleList=new ArrayList<>();
List params=new ArrayList();
try {
StringBuffer sqlbuf=new StringBuffer(" select * from role where 1=1 and rolestate!=0 ");
if(roleName!=null&&roleName.length()>0){
sqlbuf.append(" and rolename like ? ");
params.add("%"+roleName+"%");
}
//分页
sqlbuf.append(" limit ?,?"); //1 5 limit 0,5
params.add((pageIndex-1)*pageSize);
params.add(pageSize);
resultSet = query(sqlbuf.toString(), params);
while(resultSet.next()){
Role role = new Role();
role.setRoleId(resultSet.getInt("roleid"));
role.setRoleName(resultSet.getString("rolename"));
role.setRoleState(resultSet.getInt("rolestate"));
//补全所有的列
roleList.add(role);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
closeAll();
}
return roleList;
}
@Override
public int total() {
int total=0;
try {
String sql="select count(1) from role r where 1=1 and rolestate!=0 ";
resultSet = query(sql, null);
while(resultSet.next()){
total=resultSet.getInt(1);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
closeAll();
}
return total;
}
前端代码:
forEach循环动态展示数据。
<c:forEach items="${pi1.dataList}" var="r" varStatus="sta">
<tr align="center">
<th><input type="checkbox"/></th>
<td>
${sta.count}
</td>
<td>
${r.roleName}
</td>
<td>
${r.roleState==1?'启用':'禁用'}
</td>
<td>
<a href="javascript:alert('操作成功!');">启用</a>
<%-- <a href="info.html">详情</a>--%>
<a href="/power/role/roles?method=findbyid&roleId=${r.roleId}">修改</a>
<a href="/power/role/roles?method=delete&roleId=${r.roleId}"> 删除</a>
</td>
</tr>
</c:forEach>
分页信息动态展示
<div class='MainStyle'><div class=''>
<a href='/power/role/roles?method=select' target='_self'>首页</a></div>
<div class=''><a href='/power/role/roles?method=select&index=${pi1.pageIndex-1<=1?1:pi1.pageIndex-1}' target='_self'>上一页</a></div>
<c:forEach begin="1" end="${pi1.totalPages}" var="indexa">
<div class= ${pi1.pageIndex==indexa?'NowItemStyle':''} >
<a href='/power/role/roles?method=select&index=${indexa}' target='_self'>${indexa}</a></div>
</c:forEach>
<div class=''><a href='/power/role/roles?method=select&index=${pi1.pageIndex+1>=pi1.totalPages?pi1.totalPages:pi1.pageIndex+1}' target='_self'>下一页</a></div>
<div class=''><a href='/power/role/roles?method=select&index=${pi1.totalPages}' target='_self'>尾页</a></div>
<div class=''>总共<b>${pi1.total}</b>条数据</div><div class=''>每页<b>${pi1.pageSize}</b>条数据</div>
<div class=''><b>1</b>/3</div><div class='SearchStyle'><input type='text' id='john_Page_Search' onkeydown="if(event.keyCode == 13){page_searchIndex();}"/></div>
<div class=''><input type='button' value='Go' onclick="page_searchIndex()"/></div></div>
<script>
function page_searchIndex(){
var searchText = document.getElementById('john_Page_Search');
var searchIndex = searchText != null && searchText.value != '' ? parseInt(searchText.value) : 0;
if(searchIndex > 0 && searchIndex <= 3) {
window.location='StudentMaterial.aspx?page=' + searchIndex;
} else { alert('需要跳转的页码不能超出范围!'); }
}
</script>
</div>
新增角色1
新增加角色的时候,要动态显示菜单资源。
前端:(点击新增角色)
<div class="div_head" style="width: 100%;text-align:center;">
<span> <span style="float:left">当前位置是:权限管理-》角色管理</span> <span
style="float:right;margin-right: 8px;font-weight: bold">
<a style="text-decoration: none;" href="/power/role/roles?method=selectmenus">【新增角色】</a>
</span>
</div>
角色控制层建立对应方法:
//查询菜单列表
protected void selectmenus(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.接收参数
//2.调取service方法
List<Menu> menuList = menuService.getMenuList();
req.setAttribute("menulist",menuList);
System.out.println(menuList);
req.getRequestDispatcher("add.jsp").forward(req,resp);
}
service
//查询菜单列表
public List<Menu> getMenuList();
那个查询到的菜单要进行分级处理,我们通过他们的UpmenuId来进行
private MenuDao dao=new MenuDaoImpl();
@Override
public List<Menu> getMenuList() {
List<Menu> menuList = dao.getMenuList();//未分一二级
List<Menu> newMenuList=new ArrayList<>();//保存分级以后的菜单
for (Menu menu : menuList) {
if(menu.getUpmenuId()==0){ //说明是一级菜单
List<Menu> secondList = new ArrayList<>();
for (Menu second : menuList) {// 如果二级菜单的getUpmenuId等于一级菜单的id,那么再一级菜单里添加对应的二级菜单
if(second.getUpmenuId()==menu.getMenuId()){
secondList.add(second);
}
}
menu.setSecondMenuList(secondList);
newMenuList.add(menu);
}
}
return newMenuList;
}
mapper
//查询菜单列表
public List<Menu> getMenuList();
@Override
public List<Menu> getMenuList() {
List<Menu> menuList=new ArrayList<>();
try {
String sql="select * from menu";
resultSet = query(sql, null);
while(resultSet.next()){
Menu menu = new Menu();
menu.setMenuId(resultSet.getInt("menuid"));
menu.setMenuName(resultSet.getString("menuname"));
menu.setUpmenuId(resultSet.getInt("upmenuid"));
menu.setState(resultSet.getInt("state"));
menu.setDesc(resultSet.getString("desc"));
menu.setUrl(resultSet.getString("url"));
menuList.add(menu);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
closeAll();
}
return menuList;
}
前端的菜单资源展示:
循环遍历菜单
<tr width="120px;">
<td>菜单资源<span style="color:red">*</span>:</td>
<td>
<c:forEach items="${menulist}" var="m" >
<ul>
<li><input type="checkbox" value="${m.menuId}" name="menuid" />${m.menuName}
<ul>
<c:forEach items="${m.secondMenuList}" var="m2">
<li> <input type="checkbox" value="${m2.menuId}" name="menuid" />${m2.menuName}</li>
</c:forEach>
</ul>
</li>
</ul>
</c:forEach>
</td>
</tr>
新增角色2’
新增角色方法:
前端:
1,表单里加入新增方法。
2,
<body>
<div class="div_head">
<span>
<span style="float:left">当前位置是:教务中心-》考试-》新增</span>
<span style="float:right;margin-right: 8px;font-weight: bold">
<a style="text-decoration: none" href="javascript:history.back();">【返回】</a>
</span>
</span>
</div>
</div>
<div class="cztable">
<form action="/power/role/roles?method=insert" method="post">
<table border="1" width="100%" class="table_a">
<input type="hidden" name="roleId" value="${-1}">
<tr width="120px;">
<td width="120px">角色名:<span style="color:red">*</span>:</td>
<td>
<input type="text" name="rolename" value="管理员" />
</td>
</tr>
<tr width="120px;">
<td>菜单资源<span style="color:red">*</span>:</td>
<td>
<c:forEach items="${menulist}" var="m" >
<ul>
<li><input type="checkbox" value="${m.menuId}" name="menuid" />${m.menuName}
<ul>
<c:forEach items="${m.secondMenuList}" var="m2">
<li> <input type="checkbox" value="${m2.menuId}" name="menuid" />${m2.menuName}</li>
</c:forEach>
</ul>
</li>
</ul>
</c:forEach>
</td>
</tr>
<tr>
<td>启用状态<span style="color:red">*</span>:</td>
<td>
<input type="radio" name="state" checked value="1" />启用
<input type="radio" name="state" value="0"/>禁用
</td>
</tr>
<tr width="120px">
<td colspan="2" align="center">
<input type="submit" value="添加" />
</td>
</tr>
</table>
</form>
</div>
</div>
</div>
</div>
</body>
控制层方法:
//新增角色
protected void insert(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//Integer roleid = Integer.parseInt(req.getParameter("roleId"));
String rolename = req.getParameter("rolename");
String state = req.getParameter("state");
String[] menuids = req.getParameterValues("menuid");
int i = roleService.insertRole(-1,rolename, state, menuids);
if(i>0){
resp.sendRedirect("/power/role/roles?method=select");
}else{
resp.sendRedirect("/power/role/roles?method=selectmenus");
}
}
service
public int insertRole(Integer roleid,String rolename,String state,String[] ids);
新增角色表的时候,还要新增中间表的信息(角色id-菜单id)
@Override //事务问题
public int insertRole(Integer roleid,String rolename, String state, String[] ids) {
int k1=0;
try {
//1.新增角色表
Role role = new Role();
role.setRoleId(roleid);
role.setRoleName(rolename);
role.setRoleState(Integer.parseInt(state));
int k = roleDao.insert(role);// k是新增角色的id值。他需要通过工具类里的Statement.RETURN_GENERATED_KEYS属性获得
//2.新增中间表
//如何获得新增数据的id?
middleDao.insertMiddle(k,ids);
k1=1;
} catch (NumberFormatException e) {
e.printStackTrace();
}
return k1;
}
mapper
public int insert(Role role);
要返回新增角色的id值
@Override
public int insert(Role role) {
int key = 0; //新增数据的id
try {
String sql="insert into role values(null,?,?)";
List params=new ArrayList();
params.add(role.getRoleName());
params.add(role.getRoleState());
int update = update(sql, params);//update变量保存的是受影响的行数
ResultSet generatedKeys = pps.getGeneratedKeys();
if(generatedKeys.next()){
key = generatedKeys.getInt(1);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
closeAll();
}
return key;
}
//新增角色
public int insertMiddle(int roleid,String[] ids);
@Override
public int insertMiddle(int roleid, String[] ids) {
int k=0;
try {
String sql="insert into middle values(null,?,?)";
//批量新增
pps = getPps(sql);
for (String id : ids) {
pps.setInt(1,roleid);
pps.setString(2,id);
pps.addBatch();
}
pps.executeBatch();
k=1;
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
closeAll();
}
return k;
}
对应的工具类改变:
加入参数:Statement.RETURN_GENERATED_KEYS
//4.得到预状态通道
protected PreparedStatement getPps(String sql){
try {
pps= getConnection().prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return pps;
}
修改角色
修改,删除角色方法和那个学生管理里的类似,这里就直接放代码了。
修改界面
列表;
<td>
<a href="javascript:alert('操作成功!');">启用</a>
<%-- <a href="info.html">详情</a>--%>
<a href="/power/role/roles?method=findbyid&roleId=${r.roleId}">修改</a>
<a href="/power/role/roles?method=delete&roleId=${r.roleId}"> 删除</a>
</td>
修改界面:
<form action="/power/role/roles?method=Update" method="post">
<input type="hidden" name="roleId" value="${stu1.roleId}">
<table border="1" width="100%" class="table_a">
<tr width="120px;">
<td width="120px">角色名:<span style="color:red">*</span>:</td>
<td>
<input type="text" name="rolename" value="${stu1.roleName}" />
</td>
</tr>
<tr width="120px;">
<td>菜单资源<span style="color:red">*</span>:</td>
<td>
<ul>
<c:forEach items="${menuList}" var="m">
<li>
<c:set var="flag" value="false"></c:set>
<c:forEach items="${stu1.menuList}" var="ml">
<c:if test="${ml.menuId==m.menuId}">
<c:set var="flag" value="true"></c:set>
</c:if>
</c:forEach>
<input type="checkbox" ${flag==true?'checked':''} name="menuId" class="pMenu"
value="${m.menuId}"/>${m.menuName}
<ul>
<c:forEach items="${m.secondMenuList}" var="sub">
<c:set var="flag" value="false"></c:set>
<c:forEach items="${stu1.menuList}" var="ml">
<c:if test="${ml.menuId==sub.menuId}">
<c:set var="flag" value="true"></c:set>
</c:if>
</c:forEach>
<li> <input type="checkbox" ${flag==true?'checked':''}
name="menuId" class="sMenu"
value="${sub.menuId}"/>${sub.menuName}</li>
</c:forEach>
</ul>
</li>
</c:forEach>
</ul>
</td>
</tr>
<tr>
<td>启用状态<span style="color:red">*</span>:</td>
<td>
<input type="radio" name="rolestate" ${stu1.roleState==1?'checked':''} value="1"/>启用 <input
type="radio" name="rolestate" ${stu1.roleState==0?'checked':''} value="0"/>禁用
</td>
</tr>
<tr width="120px">
<td colspan="2" align="center">
<input type="submit" value="修改" />
</td>
</tr>
</table>
</form>
主键查询对应的方法
servlet:
//主键查询
private void findbyid(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String sid = req.getParameter("roleId");
//根据主键查询角色信息
Role role = roleService.getRoleById(Integer.parseInt(sid));
System.out.println(role);
//得到所有的角色列表
List<Menu> menuList = menuService.getMenuList();
System.out.println(menuList);
req.setAttribute("stu1",role);
req.setAttribute("menuList", menuList);
req.getRequestDispatcher("edit.jsp").forward(req,resp);/**/
}
根据主键查询角色信息:
service:
Role getRoleById(int roleid);
@Override
public Role getRoleById(int roleid) {
return roleDao.getRoleById(roleid);
}
mapper:
Role getRoleById(int roleid);
@Override
public Role getRoleById(int roleid) {
Role role = new Role();
//List<Menu> newMenuList=new ArrayList<>();//保存分级以后的菜单
try {
String sql = "select rolename, rolestate, menuid from role left join middle on role.roleid=middle.roleid where role.roleid=?";
List params = new ArrayList();
params.add(roleid);
resultSet = query(sql, params);
MenuDao menuDao = new MenuDaoImpl();
List<Menu> menuList = new ArrayList<>();
while (resultSet.next()) {
if (role.getRoleId() == null) {
role.setRoleId(roleid);
role.setRoleName(resultSet.getString("rolename"));
role.setRoleState(resultSet.getInt("rolestate"));
}
int menuid = resultSet.getInt("menuid");
menuList.add(menuDao.getMenuById(menuid));
}
/* for (Menu menu : menuList) {
if(menu.getUpmenuId()==0){ //说明是一级菜单
List<Menu> secondList = new ArrayList<>();
for (Menu second : menuList) {
if(second.getUpmenuId()==menu.getMenuId()){
secondList.add(second);
}
}
menu.setSecondMenuList(secondList);
newMenuList.add(menu);
}
}*/
role.setMenuList(menuList);
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
closeAll();
}
return role;
}
得到所有的角色列表:
service:
//查询菜单列表
public List<Menu> getMenuList();
private MenuDao dao=new MenuDaoImpl();
@Override
public List<Menu> getMenuList() {
List<Menu> menuList = dao.getMenuList();//未分一二级
List<Menu> newMenuList=new ArrayList<>();//保存分级以后的菜单
for (Menu menu : menuList) {
if(menu.getUpmenuId()==0){ //说明是一级菜单
List<Menu> secondList = new ArrayList<>();
for (Menu second : menuList) {
if(second.getUpmenuId()==menu.getMenuId()){
secondList.add(second);
}
}
menu.setSecondMenuList(secondList);
newMenuList.add(menu);
}
}
return newMenuList;
}
mapper:
//查询菜单列表
public List<Menu> getMenuList();:
@Override
public List<Menu> getMenuList() {
List<Menu> menuList=new ArrayList<>();
try {
String sql="select * from menu";
resultSet = query(sql, null);
while(resultSet.next()){
Menu menu = new Menu();
menu.setMenuId(resultSet.getInt("menuid"));
menu.setMenuName(resultSet.getString("menuname"));
menu.setUpmenuId(resultSet.getInt("upmenuid"));
menu.setState(resultSet.getInt("state"));
menu.setDesc(resultSet.getString("desc"));
menu.setUrl(resultSet.getString("url"));
menuList.add(menu);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
closeAll();
}
return menuList;
}
修改对应的方法
// 修改
private void update(HttpServletRequest req, HttpServletResponse resp) throws IOException {
Integer roleid = Integer.parseInt(req.getParameter("roleId"));
String rolename = req.getParameter("rolename");
String[] menuids = req.getParameterValues("menuId");
//Integer rolestate = Integer.parseInt(req.getParameter("rolestate"));
String rolestate = req.getParameter("rolestate");
int i = roleService.updateRole(roleid, rolename, rolestate, menuids);
resp.setContentType("text/html;charset=utf-8");
PrintWriter pw = resp.getWriter();
if(i > 0){
pw.println("<script>alert('更新成功!');location.href='/power/role/roles?method=select'</script>");
}else{
pw.println("<script>alert('更新失败!');location.href='/power/role/roles?method=select'</script>");
}
}
service:
// 更新方法
int updateRole(Integer roleid, String rolename, String rolestate, String[] menuids);
@Override
public int updateRole(Integer roleid, String rolename, String rolestate, String[] menuids) {
int i = roleDao.deleteRowById(roleid);
//System.out.println("删除成功");
if(i == 0){
return 0;
}
return insertRole(roleid, rolename, rolestate, menuids);
}
mapper:
删除角色:
int deleteRowById(Integer roleid);
@Override
public int deleteRowById(Integer roleid) {
try {
String sql = "delete from role where roleid=?";
List params = new ArrayList();
params.add(roleid);
int i = update(sql, params);
sql = "delete from middle where roleid=?";
int k = update(sql, params);
if (i > 0 || k > 0) {
return 1;
} else {
return 0;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
closeAll();
}
return 0;
}
增加角色:
同上面新增加角色的方法,是同时新增那个角色与中间表信息。
删除角色
前端:
<td>
<a href="javascript:alert('操作成功!');">启用</a>
<%-- <a href="info.html">详情</a>--%>
<a href="/power/role/roles?method=findbyid&roleId=${r.roleId}">修改</a>
<a href="/power/role/roles?method=delete&roleId=${r.roleId}"> 删除</a>
</td>
croller:
//删除角色
private void deletestu(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String roleid = req.getParameter("roleId");
//删除中间表
middleDao.delStu(roleid);
//删除角色表
roleService.delStu(roleid);
resp.setContentType("text/html;charset=utf-8");
PrintWriter writer = resp.getWriter();
writer.println("<script>location.href='/power/role/roles?method=select'</script>");
}
删除中间表:
mapper
int delStu(String roleid);
@Override
public int delStu(String roleid) {
try {
String sql="delete from middle where roleid=?";
List list = new ArrayList();
list.add(roleid);
int count = update(sql,list);
if(count > 0){
return count;
}
return 0;
} finally {
closeAll();
}
}
删除角色表:
service:
int delStu(String roleid);
@Override
public int delStu(String roleid) {
return roleDao.delStu(roleid);
}
mapper:
int delStu(String roleid);
@Override
public int delStu(String roleid) {
int update = 0;
try {
String sql="update role set rolestate=? where roleid=?";
List params=new ArrayList();
params.add(RoleEnum.SUSPENSION.type);
params.add(roleid);
update = update(sql, params);
} catch (Exception e) {
e.printStackTrace();
} finally {
closeAll();
}
return update;
}
动态角色列表
每个用户登录后看到的界面应该是不一样的,改怎么修改。
修改之后的登录方法:
croller
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.接收参数
String username = req.getParameter("username");
String password = req.getParameter("password");
//2.调取service
UsersService usersService = new UsersServiceImpl();
Users users = usersService.login(username, password);
//3.跳转页面
if(users==null){
//以弹窗方式提示用户,登录失败
resp.setContentType("text/html;charset=utf-8");
PrintWriter writer = resp.getWriter();
writer.println("<script>location.href='login.jsp';alert('用户名或密码不正确');</script>");
}else{
//跳转到主页面
//保存用户信息
req.getSession().setAttribute("u1",users);
resp.sendRedirect("index.jsp");
}
}
service:
/**
* 登录方法
*/
public Users login(String username,String password);
@Override
public Users login(String username, String password) {
Users users = usersDao.login(username, password);
if(users==null){
return null;
}
//根据角色id查询角色,菜单信息(三表联查)
Integer roleId = users.getRoleId();
Role role = roleDao.findbyid(roleId);
//需要对菜单进行分级
List<Menu> menuList = role.getMenuList();
List<Menu> newMenuList=new ArrayList<>();//保存分级以后的菜单
for (Menu menu : menuList) {
if(menu.getUpmenuId()==0){ //说明是一级菜单
List<Menu> secondList = new ArrayList<>();
for (Menu second : menuList) {
if(second.getUpmenuId()==menu.getMenuId()){
secondList.add(second);
}
}
menu.setSecondMenuList(secondList);
newMenuList.add(menu);
}
}
role.setMenuList(newMenuList);
users.setRole(role);
return users;
}
mapper:
/**
* 登录方法
*/
public Users login(String username, String password);
@Override
public Users login(String username, String password) {
Users users= null;
try {
String sql="select * from users where loginname=? and password=?";
ArrayList arrayList = new ArrayList();
arrayList.add(username);
arrayList.add(password);
resultSet = query(sql, arrayList);
if(resultSet==null){
return null;
}
while(resultSet.next()){
users=new Users();
users.setLoginName(username);
users.setRealName(resultSet.getString("realname"));
users.setUserId(resultSet.getInt("userid"));
users.setRoleId(resultSet.getInt("roleid"));
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
closeAll();
}
return users;
}
public Role findbyid(int roleid);
@Override
public Role findbyid(int roleid) {
Role role = new Role();
List menuList=new ArrayList();
try {
String sql="select * from role r,menu m,middle mid where r.roleid=mid.roleid and mid.menuid=m.menuid and r.roleid=?";
List params=new ArrayList();
params.add(roleid);
resultSet=query(sql,params);
while(resultSet.next()){
role.setRoleId(resultSet.getInt("roleid"));
role.setRoleName(resultSet.getString("rolename"));
role.setRoleState(resultSet.getInt("rolestate"));
Menu menu = new Menu();
menu.setMenuId(resultSet.getInt("menuid"));
menu.setMenuName(resultSet.getString("menuname"));
menu.setUrl(resultSet.getString("url"));
menu.setState(resultSet.getInt("state"));
menu.setUpmenuId(resultSet.getInt("upmenuid"));
menuList.add(menu);
}
role.setMenuList(menuList);
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
closeAll();
}
return role;
}
前端:
<c:forEach items="${u1.role.menuList}" var="m1">
<table cellspacing=0 cellpadding=0 width=150 border=0>
<tr height=22>
<td style="padding-left: 30px" background=./img/menu_bt.jpg>
<a class=menuparent onclick=expand(${m1.menuId}) href="javascript:void(0);">${m1.menuName}</a>
</td>
</tr>
<tr height=4>
<td></td>
</tr>
</table>
<table id=child${m1.menuId} style="display: none" cellspacing=0 cellpadding=0 width=150 border=0>
<c:forEach items="${m1.secondMenuList}" var="m2">
<tr height=20>
<td align=middle width=30>
<img height=9 src="./img/menu_icon.gif" width=9>
</td>
<td>
<a class=menuchild href="${m2.url}" target="right">${m2.menuName}</a>
</td>
</tr>
</c:forEach>
<tr height=4>
<td colspan=2></td>
</tr>
</table>
</c:forEach>
数据表的url:
具体代码见资料
资料下载链接(笔记+代码+其他):百度网
链接:https://pan.baidu.com/s/1nTQC1dvr7NC8O7L3I8-mUg
提取码:1111
感谢阅读,祝你从此一帆风顺。