京淘项目搭建
一、用户管理实现
1、用户管理后台搭建
1.1)表设计
1.2)User的POJO设计
package com.jt.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;
@TableName("user") //对象与表一一对应 注意大小写问题
@Data //动态生成get/set方法
@Accessors(chain = true) //链式加载结构
public class User extends BasePojo {
@TableId(type = IdType.AUTO)
private Integer id; //ID主键自增
private String username;
private String password;
private String phone;
private String email;
private Boolean status;
@TableField(exist = false) //该属性不存在
private Role role; //定义role角色数据
}
1.3)页面调用JS流程
1.3.1)生命周期函数
1.3.2)getUserList()函数定义
async getUserList(){
const {data: result} = await this.$http.get('/user/list',{
params: this.queryInfo
})
if(result.status !== 200) return this.$message.error("用户列表查询失败")
this.userList = result.data.rows
this.total = result.data.total
console.log("总记录数:"+this.total)
},
1.4)用户查询的业务接口文档
请求路径:/user/list
请求类型:GET
请求参数:后台使用PageResult对象接收
请求案例:http://localhost:8091/user/list?query=查询关键字&pageNum=1&pageSize=10
参数名称 | 参数说明 | 备注信息 |
---|---|---|
query | 用户查询的数据 | 可以为null |
pageNum | 分页查询的页数 | 必须赋值不能为null |
pageSize | 分页查询的条数 | 必须赋值不能为null |
响应参数: SysResult对象 需要携带分页对象 PageResult
参数名称 | 参数说明 | 备注信息 |
---|---|---|
status | 状态信息 | 200表示服务器请求成功 201表示服务器异常 |
msg | 服务器返回的提示信息 | 可以为null |
data | 服务器返回的业务数据 | 返回值PageResult对象 |
PageResult 对象介绍
参数名称 | 参数类型 | 参数说明 | 备注信息 |
---|---|---|---|
query | String | 用户查询的数据 | 可以为null |
pageNum | Integer | 查询页数 | 不能为null |
pageSize | Integer | 查询条数 | 不能为null |
total | Long | 查询总记录数 | 不能为null |
rows | Object | 分页查询的结果 | 不能为null |
返回值效果
{"status":200,
"msg":"服务器调用成功!",
"data":
{"query":"",
"pageNum":1,
"pageSize":2,
"total":4,
"rows":[
{"created":"2021-02-18T11:17:23.000+00:00",
"updated":"2021-03-26T06:47:20.000+00:00",
"id":1,
"username":"admin",
"password":"a66abb5684c45962d887564f08346e8d",
"phone":"13111112222",
"email":"1235678@qq.com",
"status":true,
"role":null
},
{"created":"2021-02-18T11:17:23.000+00:00",
"updated":"2021-03-13T08:50:30.000+00:00",
"id":2,
"username":"admin123",
"password":"a66abb5684c45962d887564f08346e8d",
"phone":"13111112223",
"email":"1235678@qq.com",
"status":false,
"role":null
}
]
}
}
1.5 )封装PageResult
说明:该对象主要的作用,封装分页后的结果,其中的数据需要在业务层 赋值,最后由SysResult对象携带返回给用户。
@Data
@Accessors(chain = true)
public class PageResult {
private String query; //用户查询的数据
private Integer pageNum; //页数
private Integer pageSize;//每页的条数
private Long total; //总记录数
private Object rows; //分页后的结果
}
1.6)编辑UserController
/**
* 业务: 实现用户列表的分页查询
* 类型: GET
* URL: /user/list
* 参数: PageResult对象进行接收 传递了3个参数
* 返回值: SysResult对象(PageResult对象) 返回5个
*/
@GetMapping("/list")
public SysResult getUserList(PageResult pageResult){//3个
//通过业务处理 获取总数/分页后的结果
pageResult = userService.getUserList(pageResult);
return SysResult.success(pageResult); //5个
}
1.6)编辑编辑UserServicImpl
/**
* 需求: 进行分页查询 总数 分页后的结果
* 知识铺垫: 每页20条
* Sql: select * from user limit 起始位置,每页条数
* 第一页:
* select * from user limit 0,20 下标[0-19]
* 第二页:
* select * from user limit 20,20 下标[20-39]
* 第三页:
* select * from user limit 40,20 下标[40-59]
* 第N页:
* select * from user limit (n-1)*rows,rows
* @param pageResult
* @return
* 方法实现:
* 1.手写Sql
* 2.利用MP方式实现
*/
@Override
public PageResult getUserList(PageResult pageResult) {
//起始位置
//根据参数动态的执行分页查询!!!!
int start = (pageResult.getPageNum()-1) * pageResult.getPageSize();
//每页条数
int size = pageResult.getPageSize();
//分页结果
List<User> userList = userMapper.findUserListByPage(start,size);
//获取全部记录的总数 利用java 自动拆装箱的规范, 暂时不需要where条件.
long total = userMapper.selectCount(null);
//封装数据实现返回
pageResult.setTotal(total).setRows(userList)
return pageResult;
}
1.8)编辑UserMapper
public interface UserMapper extends BaseMapper<User> {
/**
* 如果Sql语句比较简单,可以通过直接注解开发.
* @Select("Sql!!!!!")
* @Insert("sql")
* @Update("sql")
* @Delete("sql")
* @param start
* @param size
* @return
*/
@Select("select * from user limit #{start},#{size}")
List<User> findUserListByPage(Integer start, Integer size);
}
2、MP方式实现分页查询(API调用!!!)
2.1)编辑UserServiceImpl
/**
* 以MP的方式分页查询
* 需求:
* 1.分页查询 List<user>
* 2.获取记录总数 封装pageResult对象
*
* @param pageResult
* @return
*/
@Override
public PageResult getUserList(PageResult pageResult) {
//第一部分 实现数据的封装!!!
int pageNum = pageResult.getPageNum(); //获取页面,页数(几页)
int pageSize = pageResult.getPageSize();//获取条件,页面条数(几条)
//参数1: page分页对象
Page<User> page = new Page(pageNum,pageSize);
//参数2: 分页的查询条件 username模糊查询
//问题: 如果用户没有传递query like关键字 拼接参数
//动态拼接: 传参拼接like condition:true 拼接like条件
// false 不拼接 like关键字
//新建一个条件传输器
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//判断用户是否传参 如果传参 返回true 反之 返回false
boolean flag = StringUtils.hasLength(pageResult.getQuery());
//设置条件传输器的条件
queryWrapper.like(flag,"username",pageResult.getQuery());
//规则: page2个参数 根据分页查询返回 total/分页后的记录 4个参数
page = userMapper.selectPage(page,queryWrapper);
//根据分页对象,获取想要的结果
List<User> userList = page.getRecords();
long total = page.getTotal();
pageResult.setTotal(total).setRows(userList);
return pageResult;
}
2.2)编辑配置类
包路径:com.jt.config
说明: MP如果需要进行分页的查询,则必须添加配置类,否则分页不能正常执行.
关于配置类的说明:
SpringBoot整合第三方框架时,提供了配置类的机制,通过这种机制,第三方框架可以实现定制化的对象的创建
//1.表示这个类 是一个配置类 目的: 封装对象-交给Spring容器管理
@Configuration
public class MybatisPlusConfig {
// @Bean 将方法的返回值对象,交给Spring容器管理
//MP分页机制 Mysql分页语句/Oracle分页语句 为了实现功能复用 需要手动配置
//根据数据库类型不同 之后动态的生成Sql MP才能调用分页对象
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
//定义分页拦截器对象
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MARIADB));
return interceptor;
}
}
2.3)分页后的结果
3、用户状态修改
3.1)业务接口文档
说明: 用户通过开关控制状态true/false,在数据库中存储true 用1, 存储false用0
请求路径:/user’status/{id{status}
请求类型:PUT
请求参数:用户ID/状态值数据
参数名称 | 参数类型 | 参数说明 | 备注信息 |
---|---|---|---|
id | Integer | 用户id号 | 不能为null |
status | boolean | 参数状态信息 | 不能为null |
返回值结果:SysResult对象
{"status" : 200 , "msg":""服务器调用成功! ", "data" :null)
3.2)页面JS分析(了解)
说明:如果修改状态信息,则必须获取当前行的数据,id/status
作用域插槽:一般在表格循环遍历时,如果需要获取当前行数据,则采用作用域插槽的方式。
作用域插槽用法:
:data,等价于v-for
发起Ajax请求:
async updateStatus(user){
//实现用户状态修改 注意使用模版字符串 ES6中提出的新用法 ${key}
//const {data: result} = await this.$http.put('/user/status/'+user.id+'/'+user.status)
const {data: result} = await this.$http.put(`/user/status/${user.id}/${user.status}`)
if(result.status !== 200) return this.$message.error("用户状态修改失败!")
this.$message.success("用户状态修改成功!")
},
请求路径:
3.3)编辑UserController
/**
* 业务: 修改用户状态
* 类型: put
* URL: /user/status/{id}/{status}
* 参数: id主键 status 状态信息true/false
* 返回值: SysResult对象 没有业务参数
*/
@PutMapping("/status/{id}/{status}")
public SysResult updateStatus(User user){
userService.updateStatus(user);
return SysResult.success();
}
3.4)编辑UserServiceImpl
//user对象的有效数据 id=xxx status=true/false
@Override
public void updateStatus(User user) {
//根据其中不为null的元素当作set条件 id当作唯一的where条件
userMapper.updateById(user);
}
4、用户新增
4.1)用户JS分析(了解)
//校验用户数据
addUserBtn(){
this.$refs.addUserRef.validate(async valid => {
//如果校验失败 则停止数据
if(!valid) return
//console.log(this.addUserModel)
const {data: result} = await this.$http.post('/user/addUser',this.addUserModel)
if(result.status !== 200) return this.$message.error("用户新增失败")
this.$message.success("用户新增成功")
//关闭对话框
this.dialogVisible = false
//重新获取用户列表
this.getUserList()
})
},
async updateUserBtn(user){
this.updateDialogVisible = true
const {data: result} = await this.$http.get("/user/"+user.id)
if(result.status !== 200) return this.$message.error("用户查询失败")
this.updateUserModel = result.data
},
4.2)业务接口文档说明
请求路径:/user/addUser
请求类型:POST
请求参数:整个form表单数据
参数名称 | 参数类型 | 参数说明 | 备注信息 |
---|---|---|---|
username | String | 用户名 | 不能为null |
password | String | 密码 | 不能为null |
phone | String | 电话号码 | 不能为null |
String | 电子邮箱 | 不能为null |
返回值结果:SysResult
{"status" : 200 , "msg":""服务器调用成功! ", "data" :null)
4.3)编辑UserController
/**
* 业务: 实现用户新增
* URL: /user/addUser
* 类型: post类型
* 参数: 整合form表单数据 JSON串 user对象接收
* 返回值: SysResult对象
*/
@PostMapping("/addUser")
public SysResult addUser(@RequestBody User user){
userService.addUser(user);
return SysResult.success();
}
4.3)编辑UserServiceImpl
/**
* 新增入库:
* 1.密码需要加密处理
* 2.应该赋值默认状态 true
* 3.需要添加时间 创建/修改
*/
@Override
public void addUser(User user) {
//1.密码加密
byte[] bytes = user.getPassword().getBytes();
String md5Pass = DigestUtils.md5DigestAsHex(bytes);
user.setPassword(md5Pass);
//2.添加默认状态
user.setStatus(true);
//3.添加时间 目的保证时间统一
Date date = new Date();
user.setCreated(date).setUpdated(date);
//4.实现入库
userMapper.insert(user);
}