一.项目分析:
1.1前端的请求发送,会涉及到的技术Vue,Ajax,Axios
1.2后端的服务器接受和响应,会涉及到SpringBoot+SSM
1.3数据库的表设计及SQL的分析,废话不多说咱们直接上代码
二.项目实现:
2.1框架雏形搭建:
2.1.1前端页面实现:
2.1.2后端框架项目结构
解释一下:
aop包配置全局异常处理机制,面向切面编程
config包存放特殊定制的对象,以及存放每次触发事件时,更新数据库时间
controller包接受请求和反馈请求
mapper包连接数据库的映射位置
pojo包存放创建的实体类
service包业务逻辑处理层
vo包根据前端需求返回请求类型
RunApp启动类
pom.xml文件和resources文件可以查看我前文的内容,有具体解释和用法
2.1.3登录实现:
登录接口文档需求分析:
- 请求路径: /user/login
- 请求方式: POST
- 请求参数:user对象
- 返回值类型:SysResult 对象
2.1.4在vo包下创建SysResult类实现Serializable接口
@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class SysResult implements Serializable {
private Integer status;//200业务成功/201业务执行失败
private String msg;//服务器的提示信息
private Object data;//封装后台返回值
public static SysResult fail(){
return new SysResult(200,"业务执行失败",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);
}
}
2.1.5在Controller层创建UserController类接受前端控制器发送的请求
@RestController
@CrossOrigin
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
/**
* 业务说明: 实现用户登录
* 思想: 根据参数,查询数据库
* 有值: 用户名和密码正确
* 没有值: 用户名和密码错误
*
* URL:/user/login
* 参数: username/password json
* 类型: post
* 返回值: SysResult对象(token)
*/
@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);
}
2.1.6在Service层创建实现类UserServiceImpl实现UserService接口
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
@Transactional
public String login(User user) {
//1.获取明文
String password = user.getPassword();
//2.加密处理
String md5 = DigestUtils.md5DigestAsHex(password.getBytes());
user.setPassword(md5);
QueryWrapper<User> queryWrapper = new QueryWrapper<>(user);
User userDB = userMapper.selectOne(queryWrapper);
if (userDB == null) {
return null;
}
String token = UUID.randomUUID().toString()
.replace("-", "");
return token;
}
业务逻辑解释:只要后端查询数据库为空返回到控制层null值,controller层接收到null值返回给前端201的状态信息,反之生成token密钥通行证,方便用户后续的CRUD操作
实现如下:
后台界面:
2.2左侧菜单显示:
2.2.1项目分析:
前端页面实现跳转,且后端数据返回一个有等级的LIst集合
2.2.2接口文档:
请求路径 rights/getRightsList/3'
请求类型 GET
请求参数 无
响应数据 SysResult对象
2.2.3编辑RightsController:
@RestController
@RequestMapping("/rights")
@CrossOrigin
public class RightsController {
@Autowired
private RightsService rightsService;
/*
*请求路径 rights/getRightsList/3'
*请求类型 GET
*请求参数 无
*响应数据 SysResult对象
* */
@GetMapping("/getRightsList/{level}")
public SysResult getRightsList(@PathVariable Integer level){
List<Rights> rights= rightsService.getRightsList();
return SysResult.success(rights);
}
}
2.2.4编辑RightsService类,业务方法
@Service
public class RightsServiceImpl implements RightsService{
@Autowired
private RightsMapper rightsMapper;
@Override
public List<Rights> getRightsList() {
//查询一级菜单,parent_id,0
QueryWrapper<Rights> wrapper = new QueryWrapper<>();
wrapper.eq("parent_id", 0);
List<Rights> oneList = rightsMapper.selectList(wrapper);
for (Rights oneRights: oneList){
wrapper.clear();
//根据一级查询二级
wrapper.eq("parent_id", oneRights.getId());
List<Rights> twoList = rightsMapper.selectList(wrapper);
//将二级结果放入一级菜单
oneRights.setChildren(twoList);
}
//将查询结果返回
return oneList;
}
}
2.2.5效果如下
2.3用户列表展示实现:
2.3.1前端路由设置:
2.3.2接口文档:
请求路径:/user/List
请求类型:GET
请求参数:后台使用PageResult对象接收
响应数据:SysResult(pageResult)对象
2.3.3编辑VO类PageResult:
@Data
@Accessors(chain = true)
public class PageResult {
private String query;//用户查询数据
private Integer pageNum;//页数
private Integer PageSize;//每页的条数
private Long total;//总记录数
private Object rows;//分页后的结果
}
2.3.4编辑UserController:
/*请求路径: /user/list
请求类型: GET
请求参数: 后台使用PageResult对象接收
请求案例: http://localhost:8091/user/list?
query=查询关键字&pageNum=1&pageSize=10
* */
@GetMapping("/list")
public SysResult getUserList(PageResult pageResult){
pageResult = userService.getUserList(pageResult);
return SysResult.success(pageResult);
}
2.3.5编辑UserServiceImpl:
两种方式,二选一就好,由于是单表查询,我选择的是第二种方式,第一种方式适用于多表查询
@Override
public PageResult getUserList(PageResult pageResult) {
/*分页sql:
* 语法:select *from user limit 起始位置,每页条数
* 规则:数组 含头不含尾
* 查询第一页:
* select *from user limit 0,10
* 查询第二页:
* select * from user limit 10,10
* 查询第三页:
* select * from user limit 20,30
* 查询第n页:
* select * from user limit(n-1)*10,10
* */
//这是利用mapper映射实现用户页面查询
// long total = userMapper.selectCount(null);
// //定义每页条数
// int size= pageResult.getPageSize();
// //定义起始位置
// int start = (pageResult.getPageNum()-1)*size;
// //在mapper层定义方法查询sql
// List<User> userList = userMapper.findListByPage(start,size);
// //查询结果set到pageResult对象中
// pageResult.setTotal(total)
// .setRows(userList);
// return pageResult;
/* 业务说明: 利用MP方式查询数据库.
* 步骤梳理:
* 1.构建MP的分页对象
* 2.根据分页对象查询数据.
* 3.从分页对象中获取数据
* 4.封装PageResult对象
* 5.编辑配置类 封装分页拦截器
*/
//1.定义分页对象
IPage<User> page = new Page<>(pageResult.getPageNum(),
pageResult.getPageSize());
//2.定义条件构造器,指定动态查询sql
boolean flag = StringUtils.hasLength(pageResult.getQuery());
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.like(flag, "username", pageResult.getQuery());
//3.进行分页查询
page = userMapper.selectPage(page, queryWrapper);
//4.从封装后的分页对象中获取数据
pageResult.setTotal(page.getTotal())
.setRows(page.getRecords());
return pageResult;
}
2.3.6编辑UserMapper:
第一种方式:利用注解方式实现分页查询用户信息
public interface UserMapper extends BaseMapper<User> {
//说明: 利用注解实现Sql查询, 映射文件和注解标签二选一 不能同时使用
@Select("select * from user limit #{start},#{size}")
List<User> findListByPage(int start, int size);
}
2.3.7编辑config包下的MybatisPlusConfig类
第二种方式:利用配置类方式,相当于专属定制
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MARIADB));//数据库类型
return interceptor;
}
}
2.3.8效果如下:
2.4用户状态信息的修改
2.4.1JS前端页面分析:
2.4.2 接口文档分析:
请求路径 /user/status/{id}/{status} 请求类型 PUT 请求参数: 用户ID/状态值数据 返回值类型: SysResult对象
2.4.3编辑UserController
/*请求路径 /user/status/{id}/{status}
请求类型 PUT
请求参数: 用户ID/状态值数据
返回值类型: SysResult对象* */
@PutMapping("/status/{id}/{status}")
public SysResult updateStatus( User user){
userService.updateStatus(user);
return SysResult.success();
}
2.4.4编辑UserServiceImpl
@Override
@Transactional
public void updateStatus(User user) {
userMapper.updateById(user);
}
2.4.5效果如下:
修改后:
2.5用户新增功能
2.5.1JS页面分析:
2.5.2接口文档分析:
请求路径 /user/addUser 请求类型 POST 请求参数: 整个form表单数据 返回值类型:SysResult对象可以为null
2.5.3编辑UserController类
/*
请求路径 /user/addUser
请求类型 POST
请求参数: 整个form表单数据
返回值类型:SysResult对象可以为null* */
@PostMapping("/addUser")
public SysResult addUser(@RequestBody User user){
userService.addUser(user);
return SysResult.success();
}
2.5.4编辑UserServiceImpl
@Override
@Transactional
public void addUser(User user) {
String password = user.getPassword();
//加密处理
password = DigestUtils.md5DigestAsHex(password.getBytes());
user.setPassword(password)
.setStatus(true);
userMapper.insert(user);
}
2.5.5效果如下:
2.6用户删除功能
2.6.1JS页面实现:
2.6.2需求分析:
当用户点击删除时,不仅前端页面刷新时不存在,同时数据库也要及时更新,我们可以ID的方式来确定用户删除的确定值
2.6.3编辑UserController类:
/*请求路径: /user/{id}
请求类型: delete
请求参数: id
返回值类型:SysResult对象
* */
@DeleteMapping("/{id}")
public SysResult deleteById(@PathVariable Integer id){
userService.deleteById(id);
return SysResult.success();
}
2.6.4编辑UserServiceImpl
@Override
@Transactional
public void deleteById(Integer id) {
userMapper.deleteById(id);
}
2.6.5效果实现如下:
2.7用户数据更新功能实现:
2.7.1JS页面实现:
2.7.2需求分析:
用户在更新数据时,根据作用域插槽的功能,使用户在点击修改按钮后,数据回显
2.7.3编辑UserController类:
/*请求路径: /user/{id}
请求类型: GET
返回值: SysResult对象
* */
@GetMapping("/{id}")
public SysResult findUser(@PathVariable Integer id){
User user = userService.findUser(id);
return SysResult.success(user);
}
/*请求路径: /user/updateUser
请求类型: PUT
请求参数: User对象结构
返回值:SysResult对象
* */
@PutMapping("/updateUser")
public SysResult updateUser(@RequestBody User user){
userService.updateUser(user);
return SysResult.success();
}
2.7.4编辑UserServiceImpl
@Override
public User findUser(Integer id) {
return userMapper.selectById(id);
}
@Override
@Transactional
public void updateUser(User user) {
userMapper.updateById(user);
}
2.7.5效果如下:
结语:
最近这段时间项目越来越多,本次更新的东西也有很多不足之处,后面还有商品管理,权限管理,数据统计,有时间就更新吧