1、需求
现实生活中存在许多多对多之间的实例,例如用户与角色,一个用户可以拥有多个角色,一个角色亦可以属于多个用户,现需完成简单的用户界面,实现以下功能:
①实现用户列表与角色列表之间的转换;
②实现对用户界面和角色界面基础的增删改查功能;
③实现修改界面对表单的赋值;
④能够将多名角色填入表单中;
2、解决思路
①用户列表与角色列表实现简单,只需在button上加上相应地址的链接;
②多对多之间的增删改查相对于一对多要复杂一点,因为他们之间存在关联表(外码关联)
增:先添加用户表再添加关联表(先主后从)
删:先删除关联表再删除用户表(先从后主)
改:先删除关联表再重新全部插入关联表(这里采用全删全插,也可针对某条记录),再修改用户表
查:不要忽略,同样很重要,简单查询不再赘述,这里要注意有些用户不会因为没有角色而导致用户消失,所以查询时可以
区分主从表(跟上主从不同),主表不会因为从表没有数据而消失。
③赋值操作是根据checkbox勾选对应用户,通过用户id返回相应的数据,值得注意的是多个角色的返回是采用select-2控件实现的。
④注意对得到的相应的角色进行拼接。
3、代码实现(仅对用户界面)
项目结构
实体类
User
package com.itcast.domain;
import java.util.List;
public class User {
private String username;
private String password;
private String sex;
private String role;
private Integer id;
private List<Role> roles;
public List<Role> getRoles() {
return roles;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
}
UserRole
package com.itcast.domain;
public class UserRole {
private int userId;
private int roleId;
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public int getRoleId() {
return roleId;
}
public void setRoleId(int roleId) {
this.roleId = roleId;
}
}
DAO层
package com.itcast.dao;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.itcast.domain.User;
import com.itcast.domain.UserRole;
/**
* 持久层映射接口
* @author HXS
*
*/
public interface UserDao {
//添加用户
public void addUser(User user);
public void insertUserRole(List<UserRole> list);
//根据用户名查找用户
public List<User> findUserByName(String username);
public List<User> findUser();
//根据用户名修改用户
public void updateUser(User user);
//根据用户名删除用户
public void deleteUser(String[] ids);
public void deleteUserRole(String[] ids);
//表单赋值
public User getUserById(int id);
}
UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itcast.dao.UserDao">
<!-- resultMap:映射实体类和字段之间的一一对应的关系 -->
<resultMap id="userMap" type="com.itcast.domain.User">
<id property="id" column="id" />
<result property="username" column="username" />
<result property="password" column="password" />
<result property="sex" column="sex" />
<result property="role" column="role" />
<!-- 多对多关联映射:collection -->
<collection property="roles" ofType="com.itcast.domain.Role">
<id property="id" column="roleid" />
<result property="rolename" column="rolename" />
</collection>
</resultMap>
<!-- 用户添加 -->
<insert id="addUser" parameterType="com.itcast.domain.User" >
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
SELECT LAST_INSERT_ID()
</selectKey>
insert into l_user(username,password,sex) values(#{username},#{password},#{sex});
</insert>
<insert id="insertUserRole" parameterType="java.util.List">
INSERT INTO user_role (userid ,roleid) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.userId},#{item.roleId})
</foreach>
</insert>
<!-- 用户查询 -->
<select id="findUserByName" parameterType="String" resultType="com.itcast.domain.User">
select * from l_user where username=#{username}
</select>
<select id="findUser" resultMap="userMap">
SELECT u.id,u.username,u.password,u.sex,
GROUP_CONCAT(r.id) roleid,
GROUP_CONCAT(r.rolename) role
from l_user u LEFT JOIN user_role ur ON u.id=ur.userid
LEFT JOIN role r ON r.id=ur.roleid
GROUP BY u.id
<if test="username!=null and username!=''">
and u.username = #{username}
</if>
</select>
<!-- 用户修改 -->
<update id="updateUser" parameterType="com.itcast.domain.User">
update l_user
set username=#{username},password=#{password},sex=#{sex}
WHERE id=#{id}
</update>
<!-- 用户删除 -->
<delete id="deleteUser" parameterType="String">
delete from l_user
where id in
<foreach collection="array" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</delete>
<delete id="deleteUserRole" parameterType="String">
delete from user_role
where userid in
<foreach collection="array" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</delete>
<!-- 表单赋值 -->
<select id="getUserById" parameterType="int" resultMap="userMap">
SELECT u.id,u.username,u.password,u.sex,r.id roleid, r.rolename
from l_user u,role r,user_role ur
WHERE ur.userid=u.id and ur.roleid=r.id and u.id=#{id}
</select>
</mapper>
注:① 在resultMap映射中 property:"实体类属性",column:"数据库字段名"
② 在查询所有用户中left join的使用是来区分主从表的,在SQL命令中可以不使用GROUP_CONCAT来将角色分类, 直接在controller层对角色进行拼接,但过程繁琐,并且如果后来进行分页处理,会遇到无法解决的问题。
Service层
package com.itcast.service;
import java.util.List;
import com.itcast.domain.User;
import com.itcast.domain.UserRole;
public interface UserService {
//用户注册
void regist(User user);
void insertUserRole(List<UserRole> list);
//用户查询
List<User> find(String username);
List<User> findUser();
//用户修改
void update(User user);
//用户删除
void delete(String[] ids);
void deleteUserRole(String[] userids);
//表单赋值
User getUserById(int id);
}
Service层接口
package com.itcast.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.itcast.dao.UserDao;
import com.itcast.domain.User;
import com.itcast.domain.UserRole;
/**
* 业务层
*
* @author HXS
*
*/
@Service("userService")
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
public void regist(User user) {
userDao.addUser(user);
}
public List<User> find(String username) {
return userDao.findUserByName(username);
}
public List<User> findUser() {
return userDao.findUser();
}
public void update(User user) {
userDao.updateUser(user);
}
public void delete(String[] ids) {
userDao.deleteUser(ids);
}
public User getUserById(int id) {
return userDao.getUserById(id);
}
public void insertUserRole(List<UserRole> list) {
userDao.insertUserRole(list);
}
public void deleteUserRole(String[] userids) {
userDao.deleteUserRole(userids);
}
}
Web控制层
package com.itcast.controller;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import com.itcast.domain.Role;
import com.itcast.domain.User;
import com.itcast.domain.UserRole;
import com.itcast.service.UserService;
/**
* 功能概要:UserController
*/
@Controller
@RequestMapping("/")
public class UserController {
@Autowired
@Qualifier("userService")
private UserService userService;
//主界面
@RequestMapping("/")
public ModelAndView getIndex(){
ModelAndView mav = new ModelAndView();
mav.setViewName("user");
return mav;
}
@RequestMapping("doregister")
@ResponseBody
public Map<String,Object> doregister(User user){
userService.regist(user);
List<UserRole> userroles=new ArrayList<UserRole>();
if(user!=null&&user.getRole()!=null&&user.getRole()!=""){
String[] roleIdArr= user.getRole().split(",");//1,2,3
for(String roleId :roleIdArr){
//1 2 3
UserRole userrole=new UserRole();
userrole.setRoleId(Integer.parseInt(roleId));
userrole.setUserId(user.getId());
userroles.add(userrole);
}
}
if(userroles.size()>0){
userService.insertUserRole(userroles);
}
Map<String,Object> map=new HashMap<String, Object>();
map.put("status", 1);
return map;
}
//根据用户名查找用户
@RequestMapping("dofind")
@ResponseBody
public Map<String,Object> dofind(User user){
Map<String,Object> map=new HashMap<String, Object>();
String username=user.getUsername();
List<User> userList= userService.find(username);
map.put("userList",userList);
return map;
}
//显示所有用户
@RequestMapping("dofindUser")
@ResponseBody
public Map<String,Object> dofindUser(){
Map<String,Object> map=new HashMap<String, Object>();
List<User> userList= userService.findUser();
map.put("userList",userList);
return map;
}
//修改用户
@RequestMapping("doupdate")
@ResponseBody
public Map<String,Object> doupdate(User user){
//全删(根据用户id删除中间表)
String[] userids=new String[1];
userids[0]=user.getId().toString();
userService.deleteUserRole(userids);
//全插
String roles=user.getRole();
List<UserRole> list=new ArrayList<UserRole>();
if(!"".equals(roles)){
String[] roleIdArr= roles.split(",");
for (String roleId : roleIdArr) {
UserRole userrole=new UserRole();
userrole.setRoleId(Integer.parseInt(roleId));
userrole.setUserId(user.getId());
list.add(userrole);
}
}
userService.insertUserRole(list);
userService.update(user);
Map<String,Object> map=new HashMap<String, Object>();
map.put("status", 1);
return map;
}
//删除用户
@RequestMapping("dodelete")
@ResponseBody
public Map<String,Object> dodelete(String ids){
Map<String,Object> map=new HashMap<String, Object>();
String[] userids=ids.split(",");
userService.deleteUserRole(userids);
userService.delete(userids);
map.put("status",1);
return map;
}
//用户表单
@RequestMapping("detail")
public ModelAndView detail(){
ModelAndView mav = new ModelAndView();
mav.setViewName("userform");
return mav;
}
//表单赋值
@RequestMapping("getUserById")
@ResponseBody
public User getUserById(int id){
User user=userService.getUserById(id);
List<Role> roleList= user.getRoles();
String role="";
for (Role item :roleList) {
role+=item.getId()+",";
}
if(role.endsWith(",")){
role=role.substring(0, role.length()-1);
}
user.setRole(role);
return user;
}
}
user.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<meta charset="UTF-8">
<head>
<title>用户界面</title>
</head>
<script type="text/javascript" src="<%=request.getContextPath() %>/js/jquery-1.8.3.js"></script>
<script type="text/javascript" src="<%=request.getContextPath() %>/plugins/layer/layer.js"></script>
<style type="text/css">
table
{
border-collapse:collapse;
width:50%;margin-top:20px
}
table, td, th
{
border:1px solid black;
}
thead
{
background-color:lightblue;
}
</style>
<body style="padding-top: 50px;">
<div><button id="UserBtn" οnclick="window.location.href='user'" style="padding:5px 10px;margin-left: 40px;">用户管理</button></div>
<div><button id="RoleBtn" οnclick="window.location.href='role'"style="padding:5px 10px;margin-left: 40px;">角色管理</button></div>
<div align="center">
<h1>用户列表</h1>
<input type="text" name="username" id="username" placeholder="请输入用户名"/>
<input type="button" value="查询" id="find" οnclick="findBtn()"/>
<input type="button" value="修改" id="update" οnclick="edit()"/>
<input type="button" value="删除" id="delete" οnclick="remove()" />
<input type="button" value="添加" id="insert" οnclick="add()"/>
<table id="user_table">
<thead>
<tr>
<th><input type="checkbox" οnclick="checkAll(this)"/></th>
<th >用户名</th>
<th >密码</th>
<th >性别</th>
<th >角色名</th>
</tr>
</thead>
<tbody id="user_tbody">
</tbody>
</table>
</div>
<script type="text/javascript">
$(function(){
find();
});
function find(){
$.ajax({
url:"<%=request.getContextPath()%>/dofindUser",
type:"POST",
dataType:"json",
success:function(data){
console.log(data);
var htmlText="";
$.each(data.userList,function(index,element){
htmlText+='<tr>';
htmlText+=' <td align="center"><input type="checkbox" name="id" value="'+element.id+'"/></td>';
htmlText+=' <td align="center">'+element.username+'</td>';
htmlText+=' <td align="center">'+element.password+'</td>';
htmlText+=' <td align="center">'+element.sex+'</td>';
htmlText+=' <td align="center">'+element.role+'</td>';
htmlText+='</tr>';
});
$("#user_tbody").html(htmlText);
}
});
}
function findBtn(){
var username=$("#username").val();
if(username==""){
alert("请输入用户名")
return;
}
$.ajax({
url:"<%=request.getContextPath()%>/dofind",
type:"POST",
data:{username:username},
dataType:"json",
success:function(data){
console.log(data);
var htmlText="";
$.each(data.userList,function(index,element){
htmlText+='<tr>';
htmlText+=' <td align="center"><input type="checkbox" name="id" value="'+element.id+'"/></td>';
htmlText+=' <td align="center">'+element.username+'</td>';
htmlText+=' <td align="center">'+element.password+'</td>';
htmlText+=' <td align="center">'+element.sex+'</td>';
htmlText+=' <td align="center">'+element.role+'</td>';
htmlText+='</tr>';
});
$("#user_tbody").html(htmlText);
}
});
}
function add(){
layer.open({
type: 2,//1:自定义页面;2:iframe;
title:"用户表单",
area: ['600px', '350px'],
content:"<%=request.getContextPath()%>/detail" ,
btn:["确定","关闭"],
yes:function(index,layero){
//调用子页面方法
var iframeWin = window[layero.find('iframe')[0]['name']];
iframeWin.commit();
},
btn2:function(index,layero){
}
});
}
//全选/取消全选
function checkAll(obj){
if($(obj).is(":checked")==false){
$("input[name='id']").each(function(i,e){
$(e).attr("checked",false);
});
}else{
$("input[name='id']").each(function(i,e){
$(e).attr("checked",true);
});
}
}
//删除
function remove(){
// 1,2,3,4
var ids="";
$("input[name='id']:checked").each(function(i,e){
if(i==0){
ids=$(e).val();
}else{
ids+=","+$(e).val();
}
});
layer.confirm('确认删除勾选项?', {icon: 3, title:'提示'}, function(index){
$.ajax({
url:"<%=request.getContextPath()%>/dodelete",
type:"post",
data:{ids:ids},
dataType:"json",
success:function(data){
if(data.status==1){
layer.alert("删除成功!");
find();
}
}
});
layer.close(index);
});
}
var pageParam={
pageType:"",
id:""
}
function edit(){
var id= $("input[name='id']:checked").val();
pageParam.pageType="edit";
pageParam.id=id;
layer.open({
type: 2,//1:自定义页面;2:iframe;
title:"用户表单",
area: ['600px', '350px'],
content:"<%=request.getContextPath()%>/detail" ,
btn:["确定","关闭"],
yes:function(index,layero){
//调用子页面方法
var iframeWin = window[layero.find('iframe')[0]['name']];
iframeWin.commit();
},
btn2:function(index,layero){
}
});
}
</script>
</body>
</html>
userform.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<meta charset="UTF-8">
<head>
<title>用户界面</title>
</head>
<link href="<%=request.getContextPath() %>/plugins/select2-3.4.2/select2.css" rel="stylesheet" type="text/css"></link>
<script type="text/javascript" src="<%=request.getContextPath() %>/js/jquery-1.8.3.js"></script>
<script type="text/javascript" src="<%=request.getContextPath() %>/plugins/layer/layer.js"></script>
<script type="text/javascript" src="<%=request.getContextPath() %>/plugins/select2-3.4.2/select2.min.js"></script>
<style type="text/css">
table
{
border-collapse:collapse;
width:50%;margin-top:20px
}
table, td, th
{
border:1px solid black;
}
#update_table
{
width:100%;
}
#update_table td
{
padding:5px 0;
}
</style>
<body>
<form id="myform">
<input type="hidden" name="id"/>
<table id="update_table">
<tr>
<td>用户名:</td>
<td><input type="text" id="username" name="username" /></td>
</tr>
<tr>
<td>密 码:</td>
<td><input type="text" id="password" name="password"/></td>
</tr>
<tr>
<td>性 别:</td>
<td>
<input type="radio" name="sex" value="男">男
<input type="radio"name="sex" value="女">女
</td>
</tr>
<tr>
<td>角 色:</td>
<td>
<select id="role" name="role" multiple="multiple">
</select>
</td>
</tr>
</table>
</form>
<script type="text/javascript">
$(function(){
//多选
$("#role").select2({
placeholder:"请选择",
width:"200px"
});
//下拉框数据加载
$.ajax({
url:"<%=request.getContextPath()%>/dofindRole",
type:"POST",
dataType:"json",
success:function(data){
if(data!=null){
var htmlText=""
$.each(data.roleList,function(index,e){
htmlText+='<option value="'+e.id+'">'+e.rolename+'</option>';
});
$("#role").html(htmlText);
}
}
});
//表单赋值
var pageType=parent.pageParam.pageType;
if(pageType=="edit"){
var id=parent.pageParam.id;
$.ajax({
url:"<%=request.getContextPath()%>/getUserById",
type:"get",
data:{id:id},
dataType:"json",
success:function(data){
$("#username").val(data.username);
$("#password").val(data.password);
$("input[name='sex'][value='"+data.sex+"']").attr("checked",true);
$("#role").select2("val", data.role.split(','));
$("input[name='id']").val(data.id);
}
})
}
})
function commit(){
var pageType=parent.pageParam.pageType;
var urlStr="<%=request.getContextPath()%>/doregister";
if(pageType=="edit"){
urlStr="<%=request.getContextPath()%>/doupdate";
}
$.ajax({
url:urlStr,
type:"post",
data:$("#myform").serialize(),
dataType:"json",
success:function(data){
if(data.status==1){
var index = window.parent.layer.getFrameIndex(window.name);
window.parent.layer.close(index);
window.parent.find();//刷新父页面
window.parent.layer.alert("操作成功!")
}
}
});
}
</script>
</body>
</html>
用户界面:
角色界面: