好多天都没更了,这两天在老师的帮助下从零到一完成了一个商城购物后台管理的项目,今天刚刚进行项目发布,完结项目。下面来给大家分享一下项目步骤及知识点,顺带再次自己复习一遍。
由于主攻后端开发的原因,前端页面的搭建只做了解和简单的学习,没有深入去学习,能看懂逻辑即可。
一、模块总览
1.用户登录
用户登录请求数据库进行查询返回标识进行判断是否登陆成功
2.用户管理---用户列表
用户信息
功能属性:id、用户名、电话、邮箱、用户状态、操作(修改、删除)、查找用户、新增用户、翻页跳转功能
3.商品管理---商品分类
商品分类
功能属性:id、分类名称(包含一级分类、二级分类、三级分类)、商品分类状态、标识分类等级、操作(修改、删除)、新增分类(分类名称、父级分类名称)
3.商品管理---商品列表
商品信息
功能属性:id、商品标题、卖点信息、价格、数量、商品状态、操作(修改、删除)、添加商品【(基本信息---商品标题、商品买点、商品价格、商品数量、商品分类信息)、(商品图片---上传图片)、(商品详情---富文本编辑器进行商品的详细描述)】
4.权限管理---shiro框架正在努力学习中
二、用户登录模块
1.数据库的设计
字段:id、username、password、phone、email、status、created、updated
原始数据如图:
密码进行md5算法加密
创建时间以及表的更新时间自动更新
2.实体类的创建
@TableName("user")
@Data
@Accessors(chain = true)
public class User extends BasePojo{
@TableId(type = IdType.AUTO)
private Integer id;
private String username;
private String password;
private String phone;
private String email;
private Boolean status;
@TableField(exist = false) //该属性不存在
private Role role; //定义role角色数据
}
@Data
@Accessors(chain=true)
public class BasePojo implements Serializable{
@TableField(fill = FieldFill.INSERT)
private Date created; //表示入库时需要赋值
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updated; //表示入库/更新时赋值.
}
3.返回前端页面参数类的设计实现
@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class SysResult implements Serializable {
private Integer status;//200业务成功 201业务失败
private String mag;//服务器的提示信息
private Object data;//封装后台返回值
public static SysResult fail(){
return new SysResult(201, "业务执行失败",null);
}
public static SysResult fail2(){
return new SysResult(202, "业务执行失败",null);
}
public static SysResult success(){
return new SysResult(200, "业务执行成功", null);
}
public static SysResult success(Object data){
return new SysResult(200, "业务执行成功", data);
}
public static SysResult success(String msg,Object data){
return new SysResult(200, msg, data);
}
}
4.控制层的实现
4.1登录---controller
@PostMapping("/login")
public SysResult login(@RequestBody User user){
String token = userService.login(user);
if(token == null || token.length()==0){
return SysResult.fail();
}
return SysResult.success(token);
}
思路:去数据库进行数据比对,相同则返回token,否则返回null
4.2登录---service
@Override
public String login(User user) {
//获取明文
String password=user.getPassword();
//加密处理
String md5= DigestUtils.md5DigestAsHex(password.getBytes());
user.setPassword(md5);
//获取数据库对象
User userDB = userMapper.selectOne(new QueryWrapper<User>(user));
//判断登录是否正常
if(userDB==null){
return null;
}
//使用UUID动态生成TOKEN,根据当前毫秒数+随机数利用hash算法生成
//几乎保证不重复2^128
String token = UUID.randomUUID().toString().replace("-", "");
return token;
}
思路:获取对象密码、进行MD5加密之后再次set密码在数据库进行查找,如果没有返回值则登录失败返回null,否则用UUID生成token进行返回
知识点:
- 如果数据库里不存在,而实体类中需要额外添加属性应该加注解 @TableField(exist = false)
- 层架结构新增VO层:封装前后端交互数据的媒介
- MD5:MD5信息摘要算法,一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值,用于确保信息传输完整一致,.理论上MD5不可以被破解的. 只能由明文加密为密文. 不可以反向编译,但是可以用穷举法进行某种意义上的破解
- UUID:使用UUID动态生成TOKEN,根据当前时间毫秒数+随机数利用hash算法生成,几乎可以保证不重复.(有2^128的概率hash碰撞)
三、用户列表模块
1.返回前端页面参数类的设计实现
@Data
@Accessors(chain = true)
public class PageResult implements Serializable {
private String query; 用户查询的数据
private Integer pageNum; 查询页数
private Integer pageSize; 查询条数
private Long total; 查询总记录数
private Object rows; 分页查询的结果
}
2.用户页面展现控制层的实现
2.1用户页面展现---Controller
@GetMapping("list")
public SysResult getUserList(PageResult pageResult){
pageResult=userService.getUserList(pageResult);
return SysResult.success(pageResult);
}
思路:前端传入页数、每页多少条记录、查询关键字,我们添加查询总记录数和分页查询结果进行返回
2.2用户页面展现---service
方法一:手写sql
在mapper里定义抽象方法,在service里进行调用
public interface UserMapper extends BaseMapper<User> {
//只适用于简单sql,和映射文件二选一a
@Select("select * from user limit #{start},#{size}")
List<User> findListByPage(int start, int size);
}
@Override
public PageResult getUserList(PageResult pageResult) {
//1.获取总记录数
long total = userMapper.selectCount(null);
//2.获取分页结果
int size = pageResult.getPageSize();
int start =(pageResult.getPageNum()-1)* size;
List<User> userList=userMapper.findListByPage(start,size);
pageResult.setTotal(total).setRows(userList);
return pageResult;
}
思路:在mapper里定义分页sql语句,在service里通过selectCount获取到总记录数,获取记录条数和页数,调用mapper里的方法传入获取集合分别进行set封装并返回。
方法二:MP实现
@Override
@Transactional
public PageResult getUserList(PageResult pageResult) {
Page<User> page = new Page<>(pageResult.getPageNum(), pageResult.getPageSize());
boolean x=StringUtils.hasLength(pageResult.getQuery());
page = userMapper.selectPage(page, new QueryWrapper<User>().like(x, "username", pageRe