1. 程式人生 > >ssm框架-多對多之間的crud

ssm框架-多對多之間的crud

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" onclick="window.location.href='user'" style="padding:5px 10px;margin-left: 40px;">使用者管理</button></div>
	<div><button id="RoleBtn" onclick="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" onclick="findBtn()"/>
	<input type="button" value="修改" id="update" onclick="edit()"/>
	<input type="button" value="刪除" id="delete" onclick="remove()" />
	<input type="button" value="新增" id="insert" onclick="add()"/>
	<table id="user_table">
			<thead>
				<tr>
					<th><input type="checkbox"  onclick="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>

使用者介面:

角色介面: