[TOC]


动吧

1. 用户模块列表呈现 1-3
1.1. 服务端呈现 1-3
1.1.1. Controller实现 1-3
1.2. 客户端呈现 1-4
1.2.1. 首页Starter页面异步加载 1-4
1.2.2. 用户列表页面加载分页页面 1-4
2. 用户模块列表数据呈现 2-5
2.1. 服务端实现 2-5
2.1.1. Entity类实现 2-5
2.1.2. Dao接口实现 2-9
2.1.3. Mapper文件实现 2-10
2.1.4. Service接口及实现类 2-12
2.1.5. Controller类实现 2-13
2.2. 客户端实现 2-14
2.2.1. 用户列表页面异步请求加载数据 2-14
2.2.2. 用户列表页面数据异步查询实现 2-16
3. 用户禁用启用操作实现 3-17
3.1. 服务端实现 3-17
3.1.1. Dao接口实现 3-17
3.1.2. Mapper文件实现 3-17
3.1.3. Service接口实现 3-18
3.1.4. Controller类实现 3-19
3.2. 客户端实现 3-19
3.2.1. 用户列表页面禁用按钮事件处理 3-20
4. 用户添加页面呈现 4-21
4.1. 服务端实现 4-21
4.1.1. 用户Controller实现 4-21
4.2. 客户端实现 4-21
4.2.1. 用户列表页面添加按钮事件处理 4-21
5. 用户添加页面角色数据呈现 5-22
5.1. 服务端实现 5-22
5.1.1. Vo对象定义 5-22
5.1.2. Dao接口实现 5-23
5.1.3. Mapper文件实现 5-23
5.1.4. Service接口实现 5-24
5.1.5. Controller实现 5-24
5.2. 客户端实现 5-25
5.2.1. 用户编辑页面实现 5-25
6. 用户数据保存实现 6-26
6.1. 服务端实现 6-26
6.1.1. Dao 接口实现 6-26
6.1.2. Mapper文件实现 6-27
6.1.3. 用户Service实现 6-28
6.1.4. 用户Controller实现 6-29
6.2. 客户端实现 6-30
6.2.1. 用户所属部门信息呈现 6-30
6.2.2. 用户编辑页面事件处理 6-31
7. 用户页面修改呈现 7-33
7.1. 服务端实现 7-33
7.1.1. 用户DAO实现 7-33
7.1.2. 用户Mapper实现 7-34
7.1.3. 用户Service实现 7-35
7.1.4. 用户Controller实现 7-35
7.2. 客户端实现 7-36
7.2.1. 用户列表页面业务实现 7-36
7.2.2. 用户编辑页面数据初始化 7-37
8. 用户编辑页面数据更新 8-39
8.1. 服务端实现 8-39
8.1.1. Dao实现 8-39
8.1.2. Mapper实现 8-40
8.1.3. 用户角色Mapper实现 8-41
8.1.4. 用户Service实现 8-41
8.1.5. 用户Controller实现 8-42
8.2. 客户端实现 8-43
8.2.1. 用户编辑页面事件处理. 8-43
9. 总结 9-44
9.1. 重点和难点分析 9-44
9.2. 常见FAQ 9-44

用户模块列表呈现

服务端呈现

Controller实现

业务描述
创建一个Controller并定义一个方法,此方法直接返回用户列表页面.

类的定义

  1. 包名:com.db.sys.controller

  2. 类名:SysUserController

  3. 映射:@RequestMapping(“/user/“)

类中方法定义

  1. 方法名 doUserListUI

  2. 参数列表()

  3. 返回值 String

  4. 映射 @RequestMapping(“doUserListUI”)

代码实现:

@Controller
@RequestMapping(“/user/“)
public class SysUserController {
@RequestMapping(“doUserListUI”)
public String doUserListUI(){
return “sys/user_list”;
}
}

客户端呈现

首页Starter页面异步加载

业务描述
点击用户管理时,启动异步加载操作,将服务端返回页面,
添加到starter页面的div中.

代码实现:

用户列表页面加载分页页面

业务描述
用户列表页面加载完成,异步加载分页页面.
代码实现

$(document).ready(function(){
$(“#pageId”).load(“doPageUI.do”);
});

用户模块列表数据呈现

服务端实现

Entity类实现

业务描述

  1. 定义实体对象实现与sys_users表的映射

  2. 定义值对象封装查询时获取的用户与部门相关信息

业务实现

  1. 构建实体对象,属性与表中字段有映射关系.

  2. 提供set/get,无参构造方法,重写toString方法

  3. 实现序列化接口,添加序列化版本id

  1. 实体对象类的定义

  2. 包名 com.db.sys.entity

  3. 类名 SysUser (实现序列化接口并添加序列化ID)

  4. 属性 与sys_users表中字段对应

  5. 方法 提供set/get方法

代码实现:
实体类定义(后续添加和修改时可以用于在控制层接收客户端数据)
public class SysUser implements Serializable{
private static final long serialVersionUID = 177030063138338860L;
private Integer id;
private String username;
private String password;
private String salt;//盐值
private String email;
private String mobile;
private Integer valid=1;
private Integer deptId;
private Date createdTime;
private Date modifiedTime;
private String createdUser;
private String modifiedUser;

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 getSalt() {
return salt;
}
public void setSalt(String salt) {
this.salt = salt;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public Integer getValid() {
return valid;
}
public void setValid(Integer valid) {
this.valid = valid;
}
public Date getCreatedTime() {
return createdTime;
}
public void setCreatedTime(Date createdTime) {
this.createdTime = createdTime;
}
public Date getModifiedTime() {
return modifiedTime;
}
public void setModifiedTime(Date modifiedTime) {
this.modifiedTime = modifiedTime;
}
public String getCreatedUser() {
return createdUser;
}
public void setCreatedUser(String createdUser) {
this.createdUser = createdUser;
}
public String getModifiedUser() {
return modifiedUser;
}
public void setModifiedUser(String modifiedUser) {
this.modifiedUser = modifiedUser;
}

}

值对象定义(封装用户信息与其关联的部门信息的查询结果)

public class SysUserDeptResult implements Serializable{
private static final long serialVersionUID = 5477389876913514595L;
private Integer id;
private String username;
private String password;//md5
private String salt;
private String email;
private String mobile;
private Integer valid=1;
private SysDept sysDept; //private Integer deptId;
private Date createdTime;
private Date modifiedTime;
private String createdUser;
private String modifiedUser;

public Integer getValid() {
return valid;
}
public void setValid(Integer valid) {
this.valid = valid;
}
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 getSalt() {
return salt;
}
public void setSalt(String salt) {
this.salt = salt;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}

public SysDept getSysDept() {
return sysDept;
}
public void setSysDept(SysDept sysDept) {
this.sysDept = sysDept;
}
public Date getCreatedTime() {
return createdTime;
}
public void setCreatedTime(Date createdTime) {
this.createdTime = createdTime;
}
public Date getModifiedTime() {
return modifiedTime;
}
public void setModifiedTime(Date modifiedTime) {
this.modifiedTime = modifiedTime;
}
public String getCreatedUser() {
return createdUser;
}
public void setCreatedUser(String createdUser) {
this.createdUser = createdUser;
}
public String getModifiedUser() {
return modifiedUser;
}
public void setModifiedUser(String modifiedUser) {
this.modifiedUser = modifiedUser;
}
}

Dao接口实现

业务描述
创建用户持久层接口并定义查询方法获取表中用户信息.
接口定义

  1. 包: com.db.sys.dao

  2. 接口名:SysUserDao

接口中方法定义(依据查询当前页数据)

  1. 方法名 findPageObjects

  2. 参数列表(String username,Integer startIndex,Integer pageSize)

  3. 返回值List

接口中方法定义(依据条件查询总记录数)

  1. 方法名 getRowCount

  2. 参数列表(String username)

  3. 返回值int

代码实现:

public interface SysUserDao {

List findPageObjects(
@Param(“username”) String username,
@Param(“startIndex”)Integer startIndex,
@Param(“pageSize”)Integer pageSize);

int getRowCount(@Param(“username”) String username);

}

Mapper文件实现

业务描述
1)依据SysUserDao接口及方法定义SysUserMapper文件和mapper元素。

业务实现:

  1. 创建映射文件

  2. 包名:mapper.sys

  3. 文件名:SysUserMapper.xml

  4. 命名空间 com.db.sys.dao.SysUserDao

  1. 在SysDeptMapper文件中定义基于id查询部门信息的元素

  2. 元素名 select

  3. 元素id findById

  4. 参数类型 (不写)

  5. 结果映射 com.db.sys.entity.SysDept

  6. SQL定义 select * from sys_depts where id=?

  1. 在SysUserMapper文件中创建映射元素实现分页查询操作

  2. 元素名 select

  3. 元素id findPageObjects

  4. 参数类型 (不写)

  5. 结果映射 resultMap=sysUserMap

  6. SQL定义 select * from sys_users where username like ? limit …

  1. 在SysUserMapper文件中创建映射元素实现查询统计操作

  2. 元素名 select

  3. 元素id getRowCount

  4. 参数类型 (不写)

  5. 结果类型 int

  6. SQL定义 select count(*) from sys_users where username like ?

代码实现

SysDeptMapper文件中元素定义

resultType=“com.db.sys.entity.SysDept”>
select *
from sys_depts
where id=#{id}

SysUserMapper文件中元素定义
<?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">

type=“com.db.sys.vo.SysUserDeptResult”>

column=“deptId”
select=“com.db.sys.dao.SysDeptDao.findById”>


resultMap=“sysUserMap”>
select from sysusers
<include refid=
“queryWhereId”/>
limit #{startIndex},#{pageSize}

<select id=
“getRowCount”
resultType=
“int”_>
select count(
) from sysusers
<include refid=
“queryWhereId”/>

<sql id=
“queryWhereId”>

<if test=
“username!=null and username!=’’”_>
username like concat(“%”,#{username},”%”)



Service接口及实现类

业务描述

  1. 接收控制层数据,并对数据进行合法验证.

  2. 调用dao层方法,依据条件获取当前数据以及总记录数

  3. 封装数据并返回.

业务实现

业务层接口定义

  1. 包名 com.db.sys.service

  2. 接口名 SysUserService

接口方法定义

  1. 方法名 findPageObjects

  2. 参数列表(String username,Integer pageCurrent)

  3. 返回值 PageObject

接口实现类定义

  1. 包名 com.db.sys.service.impl

  2. 类名 SysUserServiceImpl

代码实现

接口定义
public interface SysUserService {
PageObject findPageObjects(
String username,
Integer pageCurrent);
}

接口实现类及方法定义

@Service
public class SysUserServiceImpl implements SysUserService {

@Resource<br />    **private** SysUserDao sysUserDao;<br />@Override<br />    **public** PageObject<SysUserDeptResult> findPageObjects(String username, <br />            Integer pageCurrent) {<br />        //1.数据合法性验证<br />        **if**(pageCurrent==**null**||pageCurrent<=0)<br />        **throw** **new** ServiceException("参数不合法");<br />//2.依据条件获取总记录数<br />        **int** rowCount=sysUserDao.getRowCount(username);<br />       **if**(rowCount==0)<br />        **throw** **new** ServiceException("记录不存在");<br />        //3.计算startIndex的值<br />        **int** pageSize=3;<br />        **int** startIndex=(pageCurrent-1)*pageSize;<br />        //4.依据条件获取当前页数据<br />        List<SysUserDeptResult> records=<br />            sysUserDao.findPageObjects(<br />        username, startIndex, pageSize);<br />        //5.封装数据<br />        PageObject<SysUserDeptResult> pageObject=**new** PageObject<>();<br />        pageObject.setPageCurrent(pageCurrent);<br />        pageObject.setRowCount(rowCount);<br />        pageObject.setPageSize(pageSize);<br />        pageObject.setRecords(records);<br />        **return** pageObject;<br />    }

}

Controller类实现

业务描述

  1. 接收客户端请求数据

  2. 调用业务方法处理请求

  3. 封装响应数据并返回

业务实现(控制层SysUserController类中方法定义)

  1. 方法名 doFindPageObjects

  2. 参数列表(String username,Integer pageCurrent)

  3. 返回值 JsonResult

  4. 映射 @RequestMapping(“doFindPageObjects”)

代码实现:

在SysUserController类添加方法。
@RequestMapping(“doFindPageObjects”)
@ResponseBody
public JsonResult doFindPageObjects(
String username,Integer pageCurrent){
PageObject pageObject=
sysUserService.findPageObjects(username,
pageCurrent);
return new JsonResult(pageObject);
}

客户端实现

用户列表页面异步请求加载数据

业务描述

  1. 分页div加载完成,异步加载数据.

  2. 将数据更新到页面.

业务实现(异步请求方法定义)

  1. 方法名 doGetObjects

  2. 参数列表()

$(document).ready(function(){
$(“#pageId”).load(“doPageUI.do”,doGetObjects);
});

function doGetObjects(){
//url
var url=”user/doFindPageObjects.do”;
//获取参数数据
var pageCurrent=$(“#pageId”).data(“pageCurrent”);
if(!pageCurrent)pageCurrent=1;
var params={“pageCurrent”:pageCurrent}
//获取查询参数username的值(此步骤在查询时使用)
var username=$(“#searchNameId”).val();
if(username)params.username=username;
//发送异步请求
$.getJSON(url,params,function(result){
doHandleResponseResult(result);
});
}

function doHandleResponseResult(result){
if(result.state==1){
doSetTableBodyRows(result.data.records);
doSetPagination(result.data);
}else{
alert(result.message);
}
}

function doSetTableBodyRows(records){
//1.获取body对象,并清空内容
var tBody=$(“#tbodyId”);
tBody.empty();
//2.迭代records元素,将内容添加到body
for(var i in records){
//2.1.创建tr对象
var tr=$(““);
tr.data(“rowData”,records[i]);
//2.2创建td元素
var tds=doCreateTds(records[i]);
//2.3将tr追加到tr中
tr.append(tds);
//2.4将tr追加到tbody中
tBody.append(tr);
}
}

function doCreateTds(data){
console.log(“data.id=”+data.id);
var tds=
“+
““+data.username+”“+
““+data.email+”“+
““+data.mobile+”“+
““+(data.valid?’启用’:’禁用’)+”“+
““+data.createdTime+”“+
““+data.modifiedTime+”“+
“;
return tds;
}

用户列表页面数据异步查询实现

业务描述

  1. 查询按钮事件注册

  2. 查询按钮事件处理函数定义(执行查询操作,重用doGetObjects函数)

  3. 初始化当前页码

  4. 获取表单参数

  5. 异步提交请求.

代码实现:
$(document).ready(function(){
$(“#pageId”).load(“doPageUI.do”,doGetObjects);
$(“.input-group-btn”)
.on(“click”,”.btn-search”,doQueryObjects)
});

function doQueryObjects(){
//1.初始化分页pageCurrent的值
$(“#pageId”).data(“pageCurrent”,1);
//2.异步查询
doGetObjects();
}

用户禁用启用操作实现

服务端实现

Dao接口实现

业务描述

定义一个方法,根据业务层传入的数据,对用户信息执行禁用或启用操作.

业务实现(在SysUserDao中定义禁用启用方法)

  1. 方法名 validById

  2. 参数列表(Integer id,Integer valid,String modifiedUser)

  3. 返回值 int

代码实现:

**int** validById(<br />            @Param("id")Integer id,<br />            @Param("valid")Integer valid,<br />            @Param("modifiedUser")String modifiedUser);

Mapper文件实现

业务描述
在SysUserMapper中定义与SysUserDao中方法对应的禁用启用元素
元素定义

  1. 元素名 update

  2. 元素id validById

  3. 元素参数(不写)

  4. SQL (update sys_users set … where ….)

代码实现:



update sys_users
set valid=#{valid},
modifiedUser=#{modifiedUser},
modifiedTime=now()
where id=#{id}

Service接口实现

业务描述

  1. 接收控制层数据(id,valid,modifiedUser)

  2. 对数据进行合法性验证

  3. 调用dao层方法执行更新操作(禁用或启用)

  4. 对结果进行验证,并返回.

业务实现(在SysUserService接口及实现类定义禁用启用方法)

  1. 方法名 validById

  2. 方法参数列表(Integer id,Integer valid,String modifiedUser)

  3. 返回值int

代码实现

接口实现类中方法的实现。
@Override
public int validById(Integer id,
Integer valid,
String modifiedUser) {
//1.合法性验证
if(id==null||id<=0)
throw new ServiceException(“参数不合法,id=”+id);
if(valid!=1&&valid!=0)
throw new ServiceException(“参数不合法,valie=”+valid);
if(StringUtils.isEmpty(modifiedUser))
throw new ServiceException(“修改用户不能为空”);
//2.执行禁用或启用操作
int rows=0;
try{
rows=sysUserDao.validById(id, valid, modifiedUser);
}catch(Throwable e){
e.printStackTrace();
//报警,给维护人员发短信
throw new ServiceException(“底层正在维护”);
}
//3.判定结果,并返回
if(rows==0)
throw new ServiceException(“此记录可能已经不存在”);
return rows;
}

Controller类实现

业务描述

  1. 接收客户端请求数据(id,valid)

  2. 调用业务层对应方法执行禁用启用操作

  3. 封装响应数据,并返回

业务实现(SysUserController类中定义禁用启用方法)

  1. 方法名 doValidById

  2. 方法参数 (Integer id,Integer valid)

  3. 方法返回值 JsonResult

  4. 方法映射@RequestMapping(“doValidById”)

代码实现

@RequestMapping(“doValidById”)
@ResponseBody
public JsonResult doValidById(
Integer id,
Integer valid){
sysUserService.validById(
id,
valid,
“admin”);//“admin”用户将来是登陆用户
return new JsonResult(“update ok”);
}

客户端实现

用户列表页面禁用按钮事件处理

业务描述

  1. 按钮事件注册(btn-valid)

  2. 按钮事件处理函数定义(doValidById)

代码实现

$(document).ready(function(){

$(“#tbodyId”)
.on(“click”,”.btn-valid”,doValidById)
});

function doValidById(){
//1.获取对象id,validId的值
var btn=$(this);//this执行调用dom对象
var user=btn.parents(“tr”).data(“rowData”);
var id=user.id;
var valid=user.valid;
//2.构建url,参数对象
var url=”user/doValidById.do”;
var params={“id”:id,”valid”:valid?0:1}
//3.发送异步请求,更新数据
$.post(url,params,function(result){
if(result.state==1){
alert(result.message);
//doGetObjects();//一种刷新方式
doEditRow(btn,valid?0:1);//一种局部刷新方式
}else{
alert(result.message);
}
})
}

局部刷新(扩展实现)
function doEditRow(btn,valid){
//1.修改按钮上内容
btn.html(valid?”禁用”:”启用”);
//2.修改td中元素内容
var tr=btn.parents(“tr”);
tr.find(“td:eq(5)”).html(valid?”启用”:”禁用”);
//3.修改并重新绑定数据
var sysUser=tr.data(“sysUser”);
sysUser.valid=valid;
tr.data(“sysUser”,sysUser);
}

用户添加页面呈现

服务端实现

Controller实现

业务描述
在SysUserController对象中添加一个方法,返回编辑页面

业务实现(方法定义)

  1. 方法名 editUI

  2. 返回值 String

  3. 参数列表()

  4. 方法映射 @RequestMapping(“doUserEditUI”)

代码实现:

@RequestMapping(“doUserEditUI”)
public String doUserEditUI(){
return “sys/user_edit”;
}

客户端实现

用户列表页面添加按钮事件处理

业务描述

  1. 添加按钮事件注册

  2. 添加按钮事件处理(核心是异步加载页面)

代码实现

$(document).ready(function(){
$(“.input-group-btn”)
.on(“click”,”.btn-add “,doLoadEditUI)
});

定义页面加载方法,后续修改时也调用此方法,然后进行修改完善。
function doLoadEditUI(){
//1.定义标题(添加或修改)
var title;
if($(this).hasClass(“btn-add”)){
title=”用户添加”;
}else{
title=”用户修改”;
}
//2.异步加载页面
var url=”user/doUserEditUI.do”;
$(“#mainContentId”).load(url,function(){
$(“.box-title”).html(title);
});
};

用户添加页面角色数据呈现

核心业务
页面加载完成以后,启动异步请求从服务端获取角色信息初始化到页面上。

服务端实现

Vo对象定义

业务描述
借助此对象封装角色id,角色名称.
业务实现(定义类并实现序列化接口,添加版本id,提供set/get)

  1. 包名 com.db.common.vo

  2. 类名 CheckBox

  3. 字段 (Integer id,String name)

代码实现:

public class CheckBox implements Serializable{
private static final long serialVersionUID = 2031967811425337153L;
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return “CheckBox [id=” + id + “, name=” + name + “]”;
}
}

Dao接口实现

业务描述
在SysRoleDao接口中添加一个查询角色ID,角色名的方法

业务实现(方法定义)

  1. 方法名 findObjects

  2. 方法参数()

  3. 方法返回值 List

代码实现:

List<CheckBox> findObjects();

Mapper文件实现

业务描述
在SysRoleMapper文件中添加查询角色id和名字的元素
业务实现

  1. 元素名 select

  2. 元素id findObjects

  3. 结果类型 com.db.common.vo.CheckBox

  4. SQL (select id,name from sys_roles)

代码实现

resultType=“com.db.common.vo.CheckBox”>

select id,name
from sys_roles

Service接口实现

业务描述
通过SysRoleService中的方法获取所有的角色id,角色名
业务实现(在SysRoleService接口及实现中定义方法)

  1. 方法名 findObjects

  2. 参数列表 ()

  3. 返回值 List

代码实现:

@Override
public List findObjects() {
return sysRoleDao.findObjects();
}

Controller实现

业务描述
1)依据请求获取角色id和角色名
2)封装数据,并返回.
业务实现(在角色控制层对象SysRoleController中的方法定义)

  1. 方法名 doFindObjects

  2. 参数列表()

  3. 返回值 JsonResult

  4. 方法映射 @RequestMapping(“doFindObjects”)

代码实现:

@RequestMapping(“doFindObjects”)
@ResponseBody
public JsonResult doFindObjects(){
return new JsonResult(sysRoleService.findObjects());
}

客户端实现

用户编辑页面实现

业务描述

页面加载完成,启动异步任务加载角色信息,初始化页面角色内容.

代码实现

$(document).ready(function(){
doLoadSysRoles();
}

//页面加载完成,加载角色信息
function doLoadSysRoles(){
var url=”role/doFindObjects.do”;
$.getJSON(url,function(result){
if(result.state==1){
//初始化角色信息
doInitDivSysRoles(result.data);
}else{
alert(result.message);
}
})
};

//初始化表单角色数据
function doInitDivSysRoles(data){
var div=$(“#rolesId”);
var checkBox=
[name]”;
for(var i in data){
div.append(
checkBox.replace(“[id]”,data[i].id)
.replace(“[name]”,data[i].name));
}
}

用户数据保存实现

服务端实现

Dao 接口实现

业务描述

  1. 接收业务层数据(SysUser),并将实体对象数据保存到数据库

  2. 接收用户和角色的关系数据,并将数据写入到中间关系表中.

业务实现
1)在SysUserDao中添加插入方法

  1. 方法名 insertObject

  2. 参数列表(SysUser entity)

  3. 返回值 int

2)在SysUserRoleDao接口中定义方法

  1. 方法名 insertObject

  2. 参数列表(Integer userId,Integer[] roleIds)

  3. 返回值 int

代码实现

/
负责将用户信息写入到数据库
@param entity
*
@return
*/
int** insertObject(SysUser entity);

/**<br />     * 负责将用户与角色的关系数据写入到数据库<br />     * **@param** userId 用户id<br />     * **@param** roleIds 多个角色id<br />     * **@return**<br />     */<br />    **int** insertObject(<br />            @Param("userId")Integer userId,<br />            @Param("roleIds")Integer[]roleIds);

Mapper文件实现

业务描述

  1. 基于SysUserDao中insertObject方法定义SQL映射元素

  2. 基于SysUserRoleDao中insertObject方法定义SQL映射元素

业务实现:

  1. 在SysUserMapper中定义insert元素,实现向对应表中写入数据

  2. 元素名 insert

  3. 元素id insertObject

  4. 参数类型 com.db.sys.entity.SysUser

  5. SQL (insert into sys_users (…) values (…));

  1. 在SysUserRoleMapper中定义insert元素,实现向对应表中写入数据

  2. 元素名 insert

  3. 元素id insertObject

  4. SQL (insert into sys_user_roles (…) values (…));

代码实现
SysUserMapper中元素定义
parameterType=“com.db.sys.entity.SysUser”
useGeneratedKeys=“true”
keyProperty=“id”>
insert into sys_users
(username,password,deptId,email,mobile,salt,valid,
createdTime,modifiedTime,createdUser,modifiedUser)
values
(#{username},#{password},#{deptId},#{email},#{mobile},#{salt},#{valid},
now(),now(),#{createdUser},#{modifiedUser})

SysUserRoleMapper中元素定义

insert into sysuser_roles
(user_id,role_id)
values
<foreach collection=
“roleIds” separator=“,” item=“item”_>
(#{userId},#{item})

用户Service实现

业务描述

  1. 接收客户端数据,并进行合法验证

  2. 将数据保存到数据库(用户信息,用户角色关系信息)

  3. 验证结果,并返回.

业务实现
在SysUserService接口及实现类定义方法

  1. 方法名 saveObject

  2. 参数列表(SysUser entity,Integer[] roleIds)

  3. 返回值int

代码实现

@Override
public int saveObject(SysUser entity, Integer[] roleIds) {
//1.验证数据合法性
if(entity==null)
throw new ServiceException(“保存对象不能为空”);
if(StringUtils.isEmpty(entity.getUsername()))
throw new ServiceException(“用户名不能为空”);
if(StringUtils.isEmpty(entity.getPassword()))
throw new ServiceException(“密码不能为空”);
if(roleIds==null || roleIds.length==0)
throw new ServiceException(“至少要为用户分配角色”);

    //2.将数据写入数据库<br />        String salt=UUID._randomUUID_().toString();<br />        entity.setSalt(salt);<br />        //加密(先了解,讲shiro时再说)<br />        SimpleHash sHash=<br />        **new** SimpleHash("MD5",entity.getPassword(), salt);<br />        entity.setPassword(sHash.toString());

    **int** rows=sysUserDao.insertObject(entity);<br />        sysUserRoleDao.insertObject(<br />                entity.getId(),<br />                roleIds);//"1,2,3,4";<br />        //3.返回结果<br />        **return** rows;<br />    }

说明:使用SimpleHash时,要添加一个shiro框架依赖


org.apache.shiro
shiro-spring
1.3.2

用户Controller实现

业务实现

  1. 获取请求数据(用户信息,关系数据)

  2. 调用业务层方法将数据写入到数据库

  3. 封装数据,并返回

业务实现

  1. 方法名 doSaveObject

  2. 参数名(SysUser entity,String roleIds)

  3. 返回值 JsonResult

  4. 映射 @RequestMapping(“doSaveObject”);

代码实现:

@RequestMapping("doSaveObject")<br />    @ResponseBody<br />    **public** JsonResult doSaveObject(<br />            SysUser entity,<br />            Integer[] roleIds){<br />        sysUserService.saveObject(entity,roleIds);<br />        **return** **new** JsonResult("save ok");<br />    }

客户端实现

用户所属部门信息呈现

step01:
用户编辑页面加载完成以后,在部门选择对应的文本框对象上注册事件监听.

$(“.form-horizontal”)
.on(“click”,”.load-sys-dept”,doLoadZTreeNodes);

step02:
定义事件处理函数,通过此函数异步加载部门信息,并将部门信息以zTree结构进行呈现.

function doLoadZTreeNodes(){
var url=”dept/doFindZTreeNodes.do”;
$(“#treeLayer”).css(“display”,”block”);
$.getJSON(url,function(result){
if(result.state==1){
zTree = $.fn.zTree.init($(“#zTreeId”),setting,result.data);
}else{
alert(result.message);
}
});
}

step03:
选择部门,并将选择的部门名字进行呈现,部门id进行数据绑定.

zTree按钮按钮事件注册(页面加载完成以后)

$(“#treeLayer”)
.on(“click”,”.btn-cancel”,doHideTree)
.on(“click”,”.btn-confirm”,doConfirm);

确定按钮事件处理
//确定按钮
function doConfirm(){
//1.获取选中的记录(id,name);
var selectedNodes=zTree.getSelectedNodes();
var node=selectedNodes[0];
//2.将id和name填写或绑定在具体对象上
$(“#deptId”).val(node.name);
$(“#deptId”).data(“deptId”,node.id)
//3.隐藏zTree对应的Div
doHideTree();
}

cancel按钮事件处理
function doHideTree(){
$(“#treeLayer”).css(“display”,”none”);
}

用户编辑页面事件处理

业务描述

  1. cancel事件处理(点击cancel按钮退出编辑页面加载列表页面)

  2. save 事件处理(将业务数据提交到服务端,并关闭当页面,加载列表页面)

代码实现:

Cancel按钮事件处理
function doCancel(){
$(“#mainContentId”).load(“user/doUserListUI.do”,function(){
$(“#mainContentId”).removeData();
});
}

save按钮事件处理

function doSaveOrUpdate(){
//1.url
var insertUrl=”user/doSaveObject.do”;
//2.获取表单数据
var params=doGetEditFormData();
//3.发起异步请求
$.post(insertUrl,params,function(result){
if(result.state==1){
alert(result.message);
doCancel();
}else{
alert(result.message);
}
})
}

获取页面表单数据
function doGetEditFormData(){
var params={
“username”:$(“#usernameId”).val(),
“password”:$(“#passwordId”).val(),
“email”:$(“#emailId”).val(),
“mobile”:$(“#phoneId”).val(),
“deptId”:$(“#deptId”).data(“deptId”),
}
var roleIds=new Array();
$(“#rolesId input[type=’checkbox’]”)
.each(function(){
if($(this).prop(“checked”)){
roleIds.push($(this).val())
}
});
params.roleIds=roleIds.toString();
console.log(params);
return params;

}

用户修改页面数据呈现

核心业务:

  1. 根据用户id查找用户,部门以及对应的角色信息

  2. 验证此用户信息是否还存在

  3. 假如存在则将信息呈现在编辑页面上.

服务端实现

DAO实现

业务描述

  1. 根据用户id查询用户以及部门信息

  2. 根据用户id查询角色id(可能是多个)

业务实现(在SysUserDao中定义根据id查询用户以及部门的方法)

  1. 方法名: findObjectById

  2. 参数列表:Integer id

  3. 返回值: SysUserDeptResult

业务实现(在SysUserRoleDao中定义根据用户id查询角色ID方法)

  1. 方法名: findRoleIdsByUserId

  2. 参数列表:Integer userId

  3. 返回值: List

代码实现

SysUserDao方法定义
SysUserDeptResult findObjectById(Integer id);

SysUserRoleDao方法定义
List findRoleIdsByUserId(Integer id);

Mapper实现

业务描述
1)在SysUserMapper中添加根据用户id进行用户信息查找的相关元素
2)在SysUserRoleMapper中定义基于用户id查找角色id的相关元素

业务实现(在SysUserMapper中添加根据id进行用户信息查找的相关元素)

  1. 元素名 select

  2. 元素id findObjectById

  3. 参数类型 int

  4. 结果映射 com.db.sys.vo.SysUserDeptResult

  5. sql定义 (select * from from sys_users where user_id=?)

业务实现
在SysUserRoleMapper中定义基于用户id查找角色id的相关元素

  1. 元素名 select

  2. 参数列表 int

  3. 结果类型 int

  4. SQL语句 (select role_id from sys_user_roles where user_id=?)

代码实现:
SysUserMapper 中元素定义
parameterType=“int”
resultMap=“sysUserResult”>
select *
from sysusers
where id=#{id}

说明:假如resultMap对应的元素已经存在,无需再写.
SysUserRoleMapper中元素定义
<select id=
“findRoleIdsByUserId”
resultType=
“int”_>
select role_id
from sys_user_roles
where user_id=#{id}

Service实现

业务描述

  1. 获取控制层数据(userId),并对其进行合法性验证

  2. 调用dao方法根据用户id查询用户信息,部门信息以及对应的角色信息

  3. 对查询到的结果数据进行封装,并返回.

业务实现(在SysUserService接口及实现类中定义相关方法)

  1. 方法名 findObjectById

  2. 参数列表(Integer userId)

  3. 返回值 Map

代码实现:

@Override
public Map findObjectById(
Integer userId) {
//1.合法性验证
if(userId==null||userId<=0)
throw new ServiceException(
“参数数据不合法,userId=”+userId);
//2.业务查询
SysUserDeptResult user=
sysUserDao.findObjectById(userId);
if(user==null)
throw new ServiceException(“此用户已经不存在”);
List roleIds=
sysUserRoleDao.findRoleIdsByUserId(userId);
//3.数据封装
Map map=new HashMap<>();
map.put(“user”, user);
map.put(“roleIds”, roleIds);
return map;
}

Controller实现

业务描述

  1. 接收客户端请求数据 (userId)

  2. 调用业务方法查询用户,部门以及对应角色信息

  3. 封装查询数据,并返回

业务实现(在SysUserController中定义相关方法)

  1. 方法名 doFindObjectById

  2. 参数列表 (Integer id)

  3. 返回值 JsonResult

  4. 映射 @RequestMapping(“doFindObjectById”);

代码实现
@RequestMapping(“doFindObjectById”)
@ResponseBody
public JsonResult doFindObjectById(
Integer id){
Map map=
sysUserService.findObjectById(userId);
return new JsonResult(map);
}

客户端实现

核心业务

  1. 点击修改时加载编辑页面

  2. 在编辑页面上呈现用户以及对应的额角色信息

用户列表页面业务实现

业务描述

  1. 修改按钮事件注册

  2. 定义事件处理函数(获取id,根据id执行查询,绑定结果)

  3. 异步加载编辑页面.

代码实现:

$(document).ready(function(){
$(“.input-group-btn”)
.on(“click”,”.btn-add,.btn-update”,doLoadEditUI)
});

方案一:异步方式实现

function doLoadEditUI(){
//1.判定点击的对象
var title;
if($(this).hasClass(“btn-add”)){
title=”添加用户”;
doLoadPage(title);
}else if($(this).hasClass(“btn-update”)){
title=”修改用户”;
var id=doGetCheckedId();
console.log(“id=”+id)
if(!id){
alert(“请先选择”);
return;
}
//基于id进行查询并加载编辑页面
doFindObjectById(id,title);
}
}

function doGetCheckedId(){
return $(“tbody input[name=’radioId’]:checked”).val();
}

function doLoadPage(title){
var url=”user/doUserEditUI.do”
$(“#mainContentId”).load(url,function(){
$(“.box-title”).html(title);
})
}

方案二:同步方式实现
function doLoadEditUI(){
var flag=true;
//1.定义标题(添加或修改)
var title;
if($(this).hasClass(“btn-add”)){
title=”用户添加”;
}else{
title=”用户修改”;
var id=doGetCheckedId();
if (!id){alert(“请先选择”);}
flag=doFindObjectById(id);
}
if(!flag)return;
//2.异步加载页面
var url=”user/doUserEditUI.do”;
$(“#mainContentId”).load(url,function(){
$(“.box-title”).html(title);
});
};

function doGetCheckedId(){
return $(“tbody input[name=’radioId’]:checked”).val();
}

function doFindObjectById(id){
var flag=true;
var url=”user/doFindObjectById.do”;
//获取用户选择的id
var params={“id”:id};
//根据id执行查询操作
$.ajax({url:url ,data:params,async:false,
success:function(result){
if(result.state==1){
$(“#mainContentId”).data(“rowData”,result.data);
}else{
alert(result.message);
flag=false;
}
}
});
return flag;
}

用户编辑页面数据初始化

页面描述

  1. 呈现页面,加载角色信息.

  2. 角色信息呈现结束,获取页面绑定的数据,通过数据初始化页面.

代码实现:

$(document).ready(function(){
doLoadSysRoles();
}

页面加载完成,加载角色信息
function doLoadSysRoles(){
var url=”role/doFindObjects.do”;
$.getJSON(url,function(result){
if(result.state==1){
//初始化角色信息
doInitDivSysRoles(result.data);
//初始化用户信息(修改时)
doInitEditPageData();
}else{
alert(result.message);
}
})
};

修改时通过此方法初始化数据
function doInitEditPageData(){
//1.获取div容器中绑定的数据
var rowData=$(“#mainContentId”).data(“rowData”);
//2.判定是否有绑定的数据
if(!rowData)return;
//3.假如有数据,则通过数据初始化页面.
//3.1初始化用户自身信息
$(“#usernameId”).val(rowData.user.username);
$(“#deptId”).val(rowData.user.sysDept.name);
$(“#deptId “).data(“deptId”,rowData.user.sysDept.id);
$(“#emailId”).val(rowData.user.email);
$(“#phoneId”).val(rowData.user.mobile);
//3.2初始化用户对应角色信息
var roleIds=rowData.roleIds;
console.log(“roleIds=”+roleIds);
//方案1:
/ for(var i in roleIds)
$(“#rolesId input[type=’checkbox’]”)
.each(function(){
if($(this).val()==roleIds[i]){
$(this).prop(“checked”,true);
}
})
/
//方案2
for(var i in roleIds){
$(“#rolesId input[value=’”+roleIds[i]+”‘]”)
.prop(“checked”,true);
}

}

用户编辑页面数据更新

核心业务

  1. 获取用户表单数据

  2. 将表单数据更新到数据库.

服务端实现

Dao实现

业务描述

  1. 接收业务层数据(SysUser),将用户数据持久化到数据库.

  2. 基于用户的id删除用户和角色表中的关系数据

  3. 接收业务层数据(roleIds),将用户角色关系数据更新到数据库

业务实现(在SysUserDao中添加更新用户自身数据的方法)

  1. 方法名 updateObject

  2. 参数列表 (SysUser user)

  3. 返回值 int

业务实现(在SysUserRoleDao中定义删除方法,先删除关系数据再添加)

  1. 方法名: deleteObjectsByUserId;

  2. 参数列表: (Integer userId);

  3. 返回值: int

业务实现(在SysUserRoleDao中定义插入方法,此方法在添加操作时已完成)

  1. 方法名: insertObjects;

  2. 参数列表: (Integer userId,Integer[] roleIds);

  3. 返回值: int

代码实现:

int updateObject(SysUser entity);

代码实现:

int deleteObjectsByUserId(Integer userId);

Mapper实现

业务描述
1)基于SysUserDao中的更新方法,定义更新元素
2)基于SysUserRoleDao接口中删除方法,定义对应的删除元素.

业务实现(基于SysUserDao中的更新方法,定义更新元素)

  1. 元素名 updateObject

  2. 参数类型 com.db.sys.entity.SysUser

  3. sql 语句(update sys_users set … where id=?)

业务实现(基于SysUserRoleDao接口中删除方法,定义对应的删除元素.)

  1. 元素名: delete

  2. 元素id deleteObjectsByUserId

  3. 参数:int

  4. sql定义: delete from sys_user_roles where user_id=?

代码实现:


update sysusers

<if test=
“username!=null and username!=’’”>
username=#{username},

<if test=
“email!=null and email!=’’”>
email=#{email},

<if test=
“mobile!=null and mobile!=’’”>
mobile=#{mobile},

<if test=
“deptId!=null and deptId!=’’”_>
deptId=#{deptId},

         <if test=_"modifiedUser!=null and modifiedUser!=''"_><br />                modifiedUser=#{modifiedUser},<br />             </if><br />             modifiedTime=now()<br />          </set><br />          where id=#{id}      <br />   </update><br />代码实现:<br />SysUserRoleMapper中元素定义<br />   <delete id=_"deleteObjectsByUserId"_<br />          parameterType=_"int"_><br />   <br />         delete from sys_user_roles<br />         where user_id=#{userId}<br />                 <br />   </delete>

Service实现

业务描述

  1. 获取控制层数据,并进行合法验证.

  2. 更新用户自身信息

  3. 删除用户角色关系数据

  4. 重新添加新的用户角色关系数据

业务实现:(在SysUserService接口及实现类中定义相关方法)

  1. 方法名: updateObject

  2. 参数列表:(SysUser entity,Integer[] roleIds)

  3. 返回值: int

代码实现:

@Override
public int updateObject(SysUser entity,Integer[] roleIds) {
//1.参数有效性验证
if(entity==null)
throw new IllegalArgumentException(“保存对象不能为空”);
if(StringUtils.isEmpty(entity.getUsername()))
throw new IllegalArgumentException(“用户名不能为空”);
if(roleIds==null||roleIds.length==0)
throw new IllegalArgumentException(“必须为其指定角色”);
//其它验证自己实现,例如用户名已经存在,密码长度,…
//2.更新用户自身信息
int rows=sysUserDao.updateObject(entity);
//3.保存用户与角色关系数据
sysUserRoleDao.deleteObjectsByUserId(entity.getId());
sysUserRoleDao.insertObjects(entity.getId(),
roleIds);
//4.返回结果
return rows;
}

Controller实现

业务描述

  1. 接收客户端请求数据

  2. 调用业务层方法,将请求数据更新到数据库

  3. 封装数据并返回.

业务实现:(在SysUserController中定义相关方法)

  1. 方法名 doUpdateObject

  2. 参数列表(SysUser entity,Integer[] roleIds);

  3. 返回值 JsonResult

  4. 映射 @RequestMapping(“doUpdateObject”)

代码实现:

@RequestMapping("doUpdateObject")<br />    @ResponseBody<br />    **public** JsonResult doUpdateObject(<br />        SysUser entity,Integer[] roleIds){<br />        sysUserService.updateObject(entity,<br />                roleIds);<br />        **return** **new** JsonResult("update ok");<br />    }

客户端实现

核心业务
点击保存按钮时,将用户输入的表单数据,更新到数据库.

用户编辑页面事件处理.

业务描述
1)添加和更新操作共用一个页面.
2)点击保存按钮将数据更新到服务端.

代码实现.

function doSaveOrUpdate(){
//1.params
var rowData=$(“#mainContentId”).data(“rowData”);
var params=doGetEditFormData();
if(rowData){
params.id=rowData.user.id;
}
//1.url
var insertUrl=”user/doSaveObject.do”;
var updateUrl=”user/doUpdateObject.do”;
var url=rowData?updateUrl:insertUrl;
//2.获取表单数据
//3.发起异步请求
$.post(url,params,function(result){
if(result.state==1){
alert(result.message);
doCancel();
}else{
alert(result.message);
}
})
}

总结

重点和难点分析

1.用户与角色关系数据的插入
2.用户与角色关系数据的更新
3.用户禁用启用操作的局部刷新实现
3.用户密码的加密设置及原理分析

用户管理 - 图1

常见FAQ

  1. 用户模块与部门模块的关系设计与实现?

  2. 用户模块与角色模块的关系设计与实现?