第二步:在SysRoleService接口中添加findObjects方法实现。关键代码如下:
@Override
public List findObjects() {
return sysRoleDao.findObjects();
}
- Controller类实现
- 业务描述与设计实现
在角色控制层对象中添加查询角色id,name相关信息的业务方法。
- 关键代码设计与实现
在SysRoleController中添加doFindRoles方法。关键代码如下:
@RequestMapping(“doFindRoles”)
public JsonResult doFindRoles() {
return new JsonResult(sysRoleService.findObjects());
}
-
客户端关键业务及代码实现
-
用户编辑页面实现
- 业务描述与设计实现
在用户编辑页面加载完成以后,异步加载角色信息,并在页面上进行呈现。
- 关键代码设计与实现
第一步:页面加载完成以后,异步加载角色相关信息。关键代码如下:
$(document).ready(function(){
doLoadSysRoles();
}
第二步:定义异步加载角色信息的方法。关键代码如下:
function doLoadSysRoles(){
var url=“role/doFindObjects”;
$.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));
}
}
-
用户数据添加实现
-
核心业务分析
用户在编辑页面点击保存按钮时,获取编辑页面用户输入的基本信息异步提交到服务端,实现用户数据的持久化操作。其时序分析,如图-13所示:
-
服务端关键业务及代码实现
-
Pojo类定义
- 业务描述与设计实现
负责封装用户的基本信息,然后由数据层持久化到数据库。
- 关键代码设计与实现
定义SysUser类,并通过相关数据封装用户基本信息,关键代码如下:
package com.cy.pj.sys.pojo;
@Date
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;
- DAO接口定义
- 业务描述与设计实现
负责将用户提交的用户基本信息,持久化到数据库。
- 关键代码设计与实现
在SysUserDao接口中定义数据持久化方法:
int insertObject(SysUser entity);
在SysUserRoleDao接口中方法定义(不存在则创建)
int insertObjects(Integer userId,Integer[] roleIds);
- Mapper映射文件定义
- 业务描述与设计实现
基于SysUserDao中方法的定义,在对应的映射文件中添加的对应SQL元素。用于将用户信息添加到数据库。
- 关键代码设计与实现
第一步:在SysUserMapper.xml中添加insertObject元素,用于写入用户信息。关键代码如下:
<insert id=“insertObject”
parameterType=“com.cy.pj.sys.pojo.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 sys_user_roles
(user_id,role_id)
values
(#{userId},#{roleId})
- Service接口定义及实现
- 业务描述与设计实现
基于控制层请求,调用数据层对象将用户以及对应的角色信息写入到数据库中。
- 关键代码设计与实现
第一步:在SysUserService接口中,添加用于保存用户对象的方法。关键代码如下:
int saveObject(SysUser entity,Integer[]roleIds);
第二步:在SysUserServiceImpl类中,实现用户保存操作。关键代码如下:
@Override
public int saveObject(SysUser entity, Integer[] roleIds) {
long start=System.currentTimeMillis();
log.info(“start:”+start);
//1.参数校验
if(entity==null)
throw new IllegalArgumentException(“保存对象不能为空”);
if(StringUtils.isEmpty(entity.getUsername()))
throw new IllegalArgumentException(“用户名不能为空”);
if(StringUtils.isEmpty(entity.getPassword()))
throw new IllegalArgumentException(“密码不能为空”);
if(roleIdsnull || roleIds.length0)
throw new IllegalArgumentException(“至少要为用户分配角色”);
//2.保存用户自身信息
//2.1对密码进行加密
String source=entity.getPassword();
String salt=UUID.randomUUID().toString();
SimpleHash sh=new SimpleHash(//Shiro框架
“MD5”,//algorithmName 算法
source,//原密码
salt, //盐值
1);//hashIterations表示加密次数
entity.setSalt(salt);
entity.setPassword(sh.toHex());
int rows=sysUserDao.insertObject(entity);
//3.保存用户角色关系数据
sysUserRoleDao.insertObjects(entity.getId(), roleIds);
long end=System.currentTimeMillis();
log.info(“end:”+end);
log.info(“total time :”+(end-start));
//4.返回结果
return rows;
}
说明:使用SimpleHash时,要添加一个shiro框架依赖
org.apache.shiro
shiro-spring
1.7.0
- Controller类定义
- 业务描述与设计实现
接收客户端提交的用户相关数据,并对其进行封装,然后调用业务层对象进行业务处理,最后将业务层处理结果响应到客户端。
- 关键代码设计与实现
定义Controller方法,借助此方法处理保存用户数据的请求和响应逻辑。关键代码如下:
@RequestMapping(“doSaveObject”)
public JsonResult doSaveObject(SysUser entity,Integer[] roleIds){
sysUserService.saveObject(entity,roleIds);
return new JsonResult(“保存成功”);
}
-
客户端关键业务及代码实现
-
用户编辑页面部门信息呈现
- 业务描述与设计实现
用户点击所属部门时,异步加载部门信息并以zTree结构进行呈现,然后用户可以选择对应的部门,将部门相关信息更新到页面上。
- 关键代码设计与实现
第一步:在所有部门相关dom元素上进行事件注册,关键代码如下:
$(“.form-horizontal”)
.on(“click”,“.load-sys-dept”,doLoadZTreeNodes);
第二步:定义事件处理函数,用户呈现部门信息,关键代码如下:
function doLoadZTreeNodes(){
var url=“dept/doFindZTreeNodes”;
$(“#treeLayer”).css(“display”,“block”);
$.getJSON(url,function(result){
if(result.state==1){
zTree = . f n . z T r e e . i n i t ( .fn.zTree.init( .fn.zTree.init((“#zTreeId”),setting,result.data);
}else{
alert(result.message);
}
});
}
第三步:部门div容器中注册,确定和取消事件,关键代码如下:
$(“#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();
}
取消按钮事件处理函数定义:
function doHideTree(){
$(“#treeLayer”).css(“display”,“none”);
}
- 页面cancel按钮事件处理
- 业务描述与设计实现
点击页面cancel按钮时,加载菜单那列表页面。
- 关键代码设计与实现
第一步:事件注册(页面加载完成以后)
$(“.box-footer”)
.on(“click”,“.btn-cancel”,doCancel)
第二步:事件处理函数定义
function doCancel(){
$(“#mainContentId”).removeData(“rowData”);
$(“#mainContentId”).load(“user/user_list”);
}
- 页面Save按钮事件处理
- 业务描述与设计实现
点击页面save按钮时,将页面上输入的菜单信息提交到服务端。
- 关键代码设计与实现
第一步:事件注册(页面加载完成以后)。
$(“.box-footer”)
.on(“click”,“.btn-save”,doSaveOrUpdate)
第二步:Save按钮事件处理函数定义。关键代码如下:
function doSaveOrUpdate(){
//1.url
var insertUrl=“user/doSaveObject”;
//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;
}
-
用户修改页面数据呈现
-
核心业务分析
基于用户id查询用户以及用户对应的部门和角色信息,并将其对应的信息呈现在用户编辑页面上,其时序图分析如图-14所示:
-
服务端关键业务及代码实现
-
DAO接口定义
- 业务描述与设计实现
负责基于id执行用户和角色信息数据的查询操作。
- 关键代码设计与实现
在SysUserDao接口中定义基于用户id查询用户相关信息的方法,关键代码如下:
SysUserDept findObjectById(Integer id);
在SysUserRoleDao接口中定义基于用户id查询角色id信息的方法,关键代码如下:
List findRoleIdsByUserId(Integer id);
- Mapper文件定义
- 业务描述与设计实现
基于SysUserDao,SysUserRoleDao中方法的定义,在映射文件中添加对应的用户查询元素。
- 关键代码设计与实现
第一步:在SysUserMapper.xml中添加id为findObjectById的select元素,关键代码如下:
<select id="findObjectById"parameterType="int"resultMap=“sysUserDept”>
select *
from sys_users
where id=#{id}
第二步:在SysUserRoleMapper.xml中添加id为findRoleIdsByUserId的select元素,关键代码如下:
<select id="findRoleIdsByUserId"resultType=“int”>
select role_id
from sys_user_roles
where user_id=#{id}
- Service接口定义及实现
- 业务描述与设计实现
基于控制层请求,调用数据层方法,查询对应的用户及相关信息。
- 关键代码设计与实现
第一步:在SysUserService接口中,添加基于id查询用户及相关信息的方法。关键代码如下:
Map<String,Object> findObjectById(Integer userId) ;
第二步:在SysUserService接口对应的实现类SysUserServiceImpl中添加findObjectById的具体实现。关键代码如下:
@Override
public Map<String, Object> findObjectById(Integer userId) {
//1.合法性验证
if(userId==null||userId<=0)throw new IllegalArgumentException(
“参数数据不合法,userId=”+userId);
//2.业务查询
SysUserDept user=sysUserDao.findObjectById(userId);
if(user==null)
throw new ServiceException(“此用户已经不存在”);
List roleIds=sysUserRoleDao.findRoleIdsByUserId(userId);
//3.数据封装
Map<String,Object> map=new HashMap<>();
map.put(“user”, user);
map.put(“roleIds”, roleIds);
return map;
}
- Controller类定义
- 业务描述与设计实现
基于客户端请求,调用业务层方法,查询对应的用户及相关信息。
- 关键代码设计与实现
在SysUserController类中定义基于用户ID查询用户的相关方法。关键代码如下:
@RequestMapping(“doFindObjectById”)
public JsonResult doFindObjectById(Integer id){
Map<String,Object> map=sysUserService.findObjectById(id);
return new JsonResult(map);
}
-
客户端关键业务及代码实现
-
列表页面修改按钮事件处理
- 业务描述与设计实现
在用户列表修改按钮上进行事件注册,点击页面修改按钮时,基于用户id向服务端发起异步请求获取用户相关数据,然后加载修改页面。
- 关键代码设计与实现
第一步:页面加载完成,进行修改按钮事件注册,关键代码如下:
$(function(){
//假如是修改
$(“.input-group-btn”)
.on(“click”,“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=$(“tbody input[name=‘radioId’]:checked”).val();
console.log(“id=”+id)
if(!id){
alert(“请先选择”);
return;
}
//基于id进行查询并加载编辑页面
doFindObjectById(id,title);
}
}
第三步:定义或修改加载编辑页面的方法。关键代码如下:
function doLoadPage(title){
var url=“user/user_edit”
$(“#mainContentId”).load(url,function(){
$(“.box-title”).html(title);
})
}
第四步:定义基于id查询用户信息的方法。关键代码如下:
function doFindObjectById(id,title){
//1.params
var params={“id”:id};
//2.url
var url=“user/doFindObjectById”;
//3.ajax request
$.getJSON(url,params,function(result){//JsonResult
if(result.state==1){
$(“#mainContentId”).data(“rowData”,result.data);
doLoadPage(title);
}else{
alert(result.message);
}
});
}
- 编辑页面角色数据呈现
- 业务描述与设计实现
页面加载完成,获取编辑页面数据,然后在页面指定位置进行数据呈现数据。
- 关键代码设计与实现
第一步:在用户编辑页面中,角色数据加载完成以后,获取用户编辑页面中需要的表单数据,然后进行页面数据初始化。关键代码如下:
function doLoadRoles(){
var url=“role/doFindRoles”
$.getJSON(url,function(result){
if(result.state==1){
doInitPageRoles(result.data);
doInitFormData();//修改时!
}else{
alert(result.message);
}
})
}
第三步:定义编辑页面数据初始化方法。关键代码如下:
function doInitFormData(){
var data=$(“#mainContentId”).data(“rowData”);
if(!data)return;
$(“#pwdDiv”).remove();
console.log(data);
//初始化用户信息
$(“#usernameId”).val(data.user.username);
$(“#deptId”).val(data.user.sysDept?data.user.sysDept.name:‘’);
$(“#deptId”).data(“deptId”,data.user.sysDept?data.user.sysDept.id:‘’);
$(“#emailId”).val(data.user.email);
$(“#phoneId”).val(data.user.mobile);
//初始化用户角色信息
var ids=data.roleIds;
for(var i in ids){
$(“#rolesId input[value='”+ids[i]+“']”)
.prop(“checked”,true);
}
}
-
用户数据更新实现
-
核心业务分析
在用户编辑页面点击更新按钮时,异步提交数据到服务端,服务端要更新用户自身信息以及用户和角色关系数据,其时序图分析,如图-15所示:
-
服务端关键业务及代码实现
-
DAO接口实现
- 业务描述与设计实现
获取用户编辑页面数据,然后异步提交到服务端,将用户信息以及用户对应的角色关系数据更新到数据库。
- 关键代码设计与实现
第一步:在SysUserDao接口中添加数据更新方法,关键代码如下:
int updateObject(SysUser entity);
第二步:在SysUserRoleDao接口中添加基于用户id删除关系数据的方法,关键代码如下:
int deleteObjectsByUserId(Integer userId);
- Mapper文件定义
- 业务描述与设计实现
基于SysUserDao,SysUserRoleDao中方法的定义,编写用于实现用户更新的SQL元素。
- 关键代码设计与实现
第一步:在SysUserMapper.xml中添加updateObject元素,用于更新菜单信息。关键代码如下:
<update id="updateObject"parameterType=“com.cy.pj.sys.pojo.SysUser”>
update sys_users
set username=#{username},
mobile=#{mobile},
email=#{email},
deptId=#{deptId},
modifiedTime=now(),
modifiedUser=#{modifiedUser}
where id=#{id}
第二步:在SysUserRoleMapper.xml文件中添加基于用户id删除关系数据的元素,关键代码如下:
<delete id="deleteObjectsByUserId"parameterType=“int”>
delete from sys_user_roles
where user_id=#{userId}
- Service接口及实现
- 业务描述与设计实现
基于控制层请求,对数据进行校验并调用数据层对象将角色信息以及角色菜单关系数据更新到数据库中。
- 关键代码设计与实现
第一步:在SysUserService接口中,添加用于更新角色对象的方法。关键代码如下:
int updateObject(SysUser entity,Integer[] roleIds);
第二步:在SysUserServiceImpl类中,实现更新角色操作。关键代码如下:
@Override
public int updateObject(SysUser entity,Integer[] roleIds) {
//1.参数有效性验证
if(entity==null)
throw new IllegalArgumentException(“保存对象不能为空”);
if(StringUtils.isEmpty(entity.getUsername()))
throw new IllegalArgumentException(“用户名不能为空”);
if(roleIdsnull||roleIds.length0)
throw new IllegalArgumentException(“必须为其指定角色”);
//其它验证自己实现,例如用户名已经存在,密码长度,…
//2.更新用户自身信息
int rows=sysUserDao.updateObject(entity);
//3.保存用户与角色关系数据
sysUserRoleDao.deleteObjectsByUserId(entity.getId());
sysUserRoleDao.insertObjects(entity.getId(),roleIds);
//4.返回结果
return rows;
}
- Controller类定义
- 业务描述与设计实现
首先接收客户端提交的用户数据,并对其进行封装,然后调用业务层对象对角色信息进行更行更新,最后将业务层处理结果响应到客户端。* 关键代码设计与实现
在SysUserController类中定义更新角色的方法。关键代码如下:
@RequestMapping(“doUpdateObject”)
public JsonResult doUpdateObject(
SysUser entity,Integer[] roleIds){
sysUserService.updateObject(entity,roleIds);
return new JsonResult(“更新成功”);
}
-
客户端关键业务及代码实现
-
编辑页面更新按钮事件处理
- 业务描述与设计实现
点击页面save按钮时,将页面上输入的用户编辑信息异步提交到服务端进行更新。
- 关键代码设计与实现
修改用户编辑页面中保存表单数据的JS函数,关键代码如下:
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”;
var updateUrl=“user/doUpdateObject”;
var url=rowData?updateUrl:insertUrl;
//2.获取表单数据
//3.发起异步请求
$.post(url,params,function(result){
if(result.state==1){
alert(result.message);
doCancel();
}else{
alert(result.message);
}
})
}
-
修改密码页面呈现
-
服务端关键业务设计及实现
检查PageController中是否有返回UI页面的方法,有则无需添加。例如:
@RequestMapping(“{module}/{moduleUI}”)
public String doModuleUI(@PathVariable String moduleUI) {
return “sys/”+moduleUI;
}
-
客户端关键业务设计及实现
-
准备密码编辑页面
准备密码编辑页面(/templates/pages/sys/pwd_edit.html)
- 密码编辑页面呈现
- 业务描述与设计实现
在系统首页左侧操作菜单中点击修改密码时,呈现密码编辑页面。
- 关键代码设计与实现
在starter.html页面尾部的页面加载完成的事件处理函数中添加事件处理,关键代码如下:
$(function(){
doLoadUI(“load-user-id”,“user/user_list”)
function doLoadUI(id,url){
$(“#”+id).click(function(){
$(“#mainContentId”).load(url);
});
}
-
密码修改页面数据持久化实现
-
服务端关键业务设计及实现
-
DAO接口定义
- 业务描述及设计实现
基于用户id,修改用户密码和盐值。
- 关键代码设计及实现:
在创建SysUserDao中添加修改用户密码信息的方法。关键代码如下:
int updatePassword(String password,String salt,Integer id);
- Mapper映射文件定义
- 业务描述及设计实现
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
最后
现在其实从大厂招聘需求可见,在招聘要求上有高并发经验优先,包括很多朋友之前都是做传统行业或者外包项目,一直在小公司,技术搞的比较简单,没有怎么搞过分布式系统,但是现在互联网公司一般都是做分布式系统。
所以说,如果你想进大厂,想脱离传统行业,这些技术知识都是你必备的,下面自己手打了一份Java并发体系思维导图,希望对你有所帮助。
r中是否有返回UI页面的方法,有则无需添加。例如:
@RequestMapping(“{module}/{moduleUI}”)
public String doModuleUI(@PathVariable String moduleUI) {
return “sys/”+moduleUI;
}
-
客户端关键业务设计及实现
-
准备密码编辑页面
准备密码编辑页面(/templates/pages/sys/pwd_edit.html)
- 密码编辑页面呈现
- 业务描述与设计实现
在系统首页左侧操作菜单中点击修改密码时,呈现密码编辑页面。
- 关键代码设计与实现
在starter.html页面尾部的页面加载完成的事件处理函数中添加事件处理,关键代码如下:
$(function(){
doLoadUI(“load-user-id”,“user/user_list”)
function doLoadUI(id,url){
$(“#”+id).click(function(){
$(“#mainContentId”).load(url);
});
}
-
密码修改页面数据持久化实现
-
服务端关键业务设计及实现
-
DAO接口定义
- 业务描述及设计实现
基于用户id,修改用户密码和盐值。
- 关键代码设计及实现:
在创建SysUserDao中添加修改用户密码信息的方法。关键代码如下:
int updatePassword(String password,String salt,Integer id);
- Mapper映射文件定义
- 业务描述及设计实现
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-HCkQGMiD-1710759107958)]
[外链图片转存中…(img-R5QI2KRv-1710759107958)]
[外链图片转存中…(img-GiAQaWQI-1710759107958)]
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
[外链图片转存中…(img-lreO8JSY-1710759107959)]
最后
现在其实从大厂招聘需求可见,在招聘要求上有高并发经验优先,包括很多朋友之前都是做传统行业或者外包项目,一直在小公司,技术搞的比较简单,没有怎么搞过分布式系统,但是现在互联网公司一般都是做分布式系统。
所以说,如果你想进大厂,想脱离传统行业,这些技术知识都是你必备的,下面自己手打了一份Java并发体系思维导图,希望对你有所帮助。
[外链图片转存中…(img-GiD1hRpQ-1710759107959)]