Java项目实战跟练day2——springboot + mybatis plus开发

一、登录页面的后端设计
1.根据前端文件初步明确后台需返回的数据:
在这里插入图片描述
2.设计思路
第一步:搭建MVC架构(以员工登录为例)
①创建entity层。通过实体类和数据库中employee表进行映射,每一个属性对应数据库的列,注意命名方式采用驼峰命名法。

application.yml配置开启驼峰命名:

   #在映射实体或者属性时,将数据库中表名和字段名中的下划线去掉,按照驼峰命名法映射
    map-underscore-to-camel-case: true

employee.java文件内容:

/**
 * ClassName:Employee
 * Description:
 *员工实体类
 * @Author:Hyt
 * @Create:2024/1/22 17:16
 * @Version 1.0
 */
@Data
/*
Data:该注解用于替代get、set方法
 */
public class Employee implements Serializable {
    private static final long serialVersionUID = 1L;

    private Long id;

    private String username;

    private String name;

    private String password;

    private String phone;

    private String sex;

    private String idNumber;

    private Integer status;

    private LocalDateTime createTime;

    private LocalDateTime updateTime;

    @TableField(fill = FieldFill.INSERT)
    private Long createUser;

    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Long updateUser;
}

②创建controller层。Controler负责请求转发,接收前端页面传过来的参数,传给Service处理,接到返回值,再传给页面。
EmployeeController.java:

/**
 * ClassName:EmployeeController
 * Description:
 *员工控制层
 * @Author:Hyt
 * @Create:2024/1/22 17:33
 * @Version 1.0
 */
@Slf4j
@RestController
@RequestMapping ("/employee")
public class EmployeeController {
    @Autowired
    private EmployeeService employeeService;
    //员工登录
    /*
    处理逻辑:前端上送密码和用户名-->密码通过MD5加密-->根据用户名查询数据库-->若无结果报失败,有结果-->密码比对是否一致-->
    不一致报失败,一致则-->查看员工状态是否禁用(状态为1则正常状态)-->禁用报失败,未禁用则-->存储员工ID到session中
     */
    /*
    PostMapping:该注解对应前端的请求方式:post
    RequestBody:该注解接收前端上送的数据并转换为后台对象
    HttpServletRequest:该类对象是用于将登录成功的员工id存储在session一份
     */
    @PostMapping("/login")
    public R<Employee> login(HttpServletRequest request, @RequestBody Employee employee){
        //1、将页面提交的密码password进行md5加密处理
        String password = employee.getPassword();

        String password1 = DigestUtils.md5DigestAsHex(password.getBytes());

        //2、根据页面提交的用户名username查询数据库
        LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();//建立查询对象
        queryWrapper.eq(Employee::getUsername,employee.getUsername());
        Employee emp = employeeService.getOne(queryWrapper);

        //3、如果没有查询到则返回登录失败结果
        if(emp==null){
            return R.error("登录失败");
        }

        //4、密码比对,如果不一致则返回登录失败结果
        if(!emp.getPassword().equals(password)){
            return R.error("登录失败");
        }

        //5、查看员工状态,如果为已禁用状态,则返回员工已禁用结果
        if(emp.getStatus()!=1){
            return R.error("账号禁用");
        }
        //6、登录成功,将员工id存入Session并返回登录成功结果
        request.getSession().setAttribute("employee",emp.getId());
        return R.success(emp);
    }
}

!!!note:
特意设计针对controller层返回结果的通用类,应对不同controller处理后返回不同结果。
通用结果类R:

//通过结果返回类,服务端返回的数据最终都会封装为此对象

@Data
public class R<T> {

    private Integer code; //编码:1成功,0和其它数字为失败

    private String msg; //错误信息

    private T data; //数据

    private Map map = new HashMap(); //动态数据

    public static <T> R<T> success(T object) {
        R<T> r = new R<T>();
        r.data = object;
        r.code = 1;
        return r;
    }

    public static <T> R<T> error(String msg) {
        R r = new R();
        r.msg = msg;
        r.code = 0;
        return r;
    }

    public R<T> add(String key, Object value) {
        this.map.put(key, value);
        return this;
    }
}

该R类与前端方法(login.html中的method)结合,利用code的码值判断登录成功与否。

      methods: {
        async handleLogin() {
          this.$refs.loginForm.validate(async (valid) => {
            if (valid) {
              this.loading = true
              let res = await loginApi(this.loginForm)//用res接收后端判断返回的结果
              if (String(res.code) === '1') {//前后端约定:1为登录成功,0为失败
                localStorage.setItem('userInfo',JSON.stringify(res.data))//localStorage将后端返回的结果转化为JSON形式存储在浏览器
                window.location.href= '/backend/index.html'
              } else {
                this.$message.error(res.msg)
                this.loading = false
              }
            }
          })
        }
      }

③创建mapper层。mapper(dao)层,数据访问层,dao和数据库的表是一一对应关系,具体到对某个表进行增删改查。

EmployeeMapper.java:

@Mapper
public interface EmployeeMapper extends BaseMapper<Employee> {
}

④创建service层:对一个或多个dao进行的再次封装,封装成一个服务。service层主要负责业务模块的应用逻辑设计。思路:设计接口–>设计其实现类–>Spring配置文件中配置其实现的关联。service层的业务实现要调用dao层接口,封装service层业务逻辑有利于通用的业务逻辑的独立性。

EmployeeService.java:

@Service
public interface EmployeeService extends IService<Employee>{
}

EmployeeServiceImpl .java:

@Service
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee> implements EmployeeService {
}

搭建完成MVC架构后项目结构如下:
在这里插入图片描述
整个前后端交互的流程可见下:
在这里插入图片描述
第二步:前后端联合验证:
1.断点调试,查看前端传参,后端处理
2.对照login.html文件查看登录数据
login.html:
该方法将controller返回的信息转换为json格式存储在浏览器中:

      methods: {
        async handleLogin() {
          this.$refs.loginForm.validate(async (valid) => {
            if (valid) {
              this.loading = true
              let res = await loginApi(this.loginForm)//用res接收后端判断返回的结果
              if (String(res.code) === '1') {//前后端约定:1为登录成功,0为失败
                localStorage.setItem('userInfo',JSON.stringify(res.data))//localStorage将后端返回的结果转化为JSON形式存储在浏览器
                window.location.href= '/backend/index.html'
              } else {
                this.$message.error(res.msg)
                this.loading = false
              }
            }
          })
        }
      }

前端可查询到存储的用户信息:
在这里插入图片描述
3.模拟各种场景的登录,点击登录一次就发送一次请求至后端
在这里插入图片描述
进入前端login的请求中,可以看到后台返回的结果包括:code、msg、data、map四项数据
在这里插入图片描述
上述四项数据实际上是R对象转化为json后返回至前端
在这里插入图片描述
至此登录功能开发完毕!

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐