ssm框架-多對多之間的crud
1、需求
現實生活中存在許多多對多之間的例項,例如使用者與角色,一個使用者可以擁有多個角色,一個角色亦可以屬於多個使用者,現需完成簡單的使用者介面,實現以下功能:
①實現使用者列表與角色列表之間的轉換;
②實現對使用者介面和角色介面基礎的增刪改查功能;
③實現修改介面對錶單的賦值;
④能夠將多名角色填入表單中;
2、解決思路
①使用者列表與角色列表實現簡單,只需在button上加上相應地址的連結;
②多對多之間的增刪改查相對於一對多要複雜一點,因為他們之間存在關聯表(外碼關聯)
增:先新增使用者表再新增關聯表(先主後從)
刪:先刪除關聯表再刪除使用者表(先從後主)
改:先刪除關聯表再重新全部插入關聯表(這裡採用全刪全插,也可針對某條記錄),再修改使用者表
查:不要忽略,同樣很重要,簡單查詢不再贅述,這裡要注意有些使用者不會因為沒有角色而導致使用者消失,所以查詢時可以
區分主從表(跟上主從不同),主表不會因為從表沒有資料而消失。
③賦值操作是根據checkbox勾選對應使用者,通過使用者id返回相應的資料,值得注意的是多個角色的返回是採用select-2控制元件實現的。
④注意對得到的相應的角色進行拼接。
3、程式碼實現(僅對使用者介面)
專案結構
實體類
User
UserRolepackage 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; } }
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>
使用者介面:
角色介面: