零基础做Java项目 瑞吉外卖 day-1

397 阅读5分钟

瑞吉外卖

在学这个项目之前我花了1天了解了java的基本语法,第二天学习了maven和springboot的大致思路,觉得不能仅限于此,故开始进行瑞吉外卖项目的编写。 本人在这之前只通过菜鸟教程学过java的语法,html和css看过,对于javaweb一问三不知,所以该笔记会在某些问题上整的特别明细,会有很多相关的知识点的补充,也有我以前做过的项目的理解,会用其他语言(如Python和Go)的web开发例子去进行比较。

关于环境配置就不用说太多,可以直接使用他提供的配置,如pom.xml,application.yml,还有其他静态文件可以直接使用。 初见springboot时,里面的运行让我费解。无论是其命名方式,又或者是其项目管理模式。而MVC又与我之前写三层架构有些许区别,这让我有些没那么适应。 最主要的是@,也就是注解这东西。 我一开始想着这@如同python中的装饰器来使用,但其实是不同的。 注解对元数据进行了检查、对比等工作,不会对所修饰的代码产生直接的影响。装饰器可以对方法进行功能上的改变,可以对所修饰的代码产生直接的影响。 注解本质上是接口的一种 在我们打开@SpringBootApplication的注解。使用@interface用于自定义一个注解。而该注解在定义之后就可以为我们使用。 image.png 注解的存在让我们能很快的使用包去完成我们所想做的是。 首先我们在我们的ReggieApplication文件中写道

package com.itheima.reggie;
​
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
​
@Slf4j
@SpringBootApplication
public class ReggieApplication {
    public static void main(String[] args) {
        SpringApplication.run(ReggieApplication.class,args);
        log.info("项目启动成功...");
    }
}

使用@SpringBootApplication注释是为了驱动springboot程序,而@Slf4j是用来使用log反馈信息的。 我们再创建config文件夹,再创建WebMvcConfig文件,通过这样我们能导入了静态资源。

package com.itheima.reggie.config;
​
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
​
@Slf4j
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
    /**
     * 设置静态资源映射
     * @param registry
     */
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        log.info("开始进行静态资源映射...");
        registry.addResourceHandler("/backend/**").addResourceLocations("classpath:/backend/");
        registry.addResourceHandler("/front/**").addResourceLocations("classpath:/front/");
    }
}

其实从这一步之后很明显的感受到诸多ooc关键字的使用,如extends,implements等等,又或者是 @Override(用于覆盖父类方法),用于不断地去面向对象编程。而我在这段时间里常写Go,java和go两者虽同为静态语言,但因为一个是面向对象的,一个不是,写的思路有很大的差别。

当我们进行员工实体的创建。

package com.itheima.reggie.entity;
​
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
​
/**
 * 员工实体
 */
@Data
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;
​
}

如果是学过Go或者Python的朋友,可能会明白是model构建的过程,在go中一般是如下这么写的。从这样的感觉其实差不多,都是进行模型的创建。

package models
​
import "time"type Comment struct {
    PostID     uint64    `db:"question_id" json:"question_id"`
    ParentID   uint64    `db:"parent_id" json:"parent_id"`
    CommentID  uint64    `db:"comment_id" json:"comment_id"`
    AuthorID   uint64    `db:"author_id" json:"author_id"`
    Content    string    `db:"content" json:"content"`
    CreateTime time.Time `db:"create_time" json:"create_time"`
}

而我们还要进行mapper的创建

package com.itheima.reggie.mapper;
​
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.reggie.entity.Employee;
import org.apache.ibatis.annotations.Mapper;
​
@Mapper
    public interface EmployeeMapper extends BaseMapper<Employee>{
    }

mapper这层其实可以理解成MyBatis(orm,可以理解成gorm,sqlx,sqlachemy)的导入。extends,也就是继承,就是导入属于mapper的方法。 关于通用结果类R,也就是在common里面的,也直接复制进去就更好了,类似于Go中写的类似response的文件。 我们继续写service文件,引入myvatis plus中的IService方法,使用其给我们整体搭好框架,方便我们进行模型的绑定,进行crud。

在java中用于函数的泛型。

controller层是我们的重中之重,我们重点说说。

package com.itheima.reggie.controller;
​
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.itheima.reggie.common.R;
import com.itheima.reggie.entity.Employee;
import com.itheima.reggie.service.EmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
​
import javax.servlet.http.HttpServletRequest;
​
@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {
​
    @Autowired
    private EmployeeService employeeService;
​
    /**
     * 员工登录
     * @param request
     * @param employee
     * @return
     */
    @PostMapping("/login")
    public R<Employee> login(HttpServletRequest request,@RequestBody Employee employee){
​
        //1、将页面提交的密码password进行md5加密处理
        String password = employee.getPassword();
        password = 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() == 0){
            return R.error("账号已禁用");
        }
​
        //6、登录成功,将员工id存入Session并返回登录成功结果
        request.getSession().setAttribute("employee",emp.getId());
        return R.success(emp);
    }
​
    /**
     * 员工退出
     * @param request
     * @return
     */
    @PostMapping("/logout")
    public R<String> logout(HttpServletRequest request){
        //清理Session中保存的当前登录员工的id
        request.getSession().removeAttribute("employee");
        return R.success("退出成功");
    }
}
​

该项如同Gin中的路由组一样,我们设置了个employee的路由组,。

@RequestMapping("/employee")

在这之下还有两个Post方法,用于映射到我们的登录登出。

    @PostMapping("/login")
    @PostMapping("/logout")

关于登录的思路其实大差不差。首先是将页面提交的密码进行隐私化,再根据提供的username查询数据库,如果没查询到就返回登录失败。再进行密码比对。比对成功后查看员工状态,如果一切正常就选择登录成功,将员工id存入session并返回成功。 (这里也可以使用jwt,但是课程中使用session就用session吧。特别是我们之后还得写登出,jwt登出有些难写) 而我们登出的功能如下,其实只要把request中的session给remove掉就好了。

    @PostMapping("/logout")
    public R<String> logout(HttpServletRequest request){
        //清理Session中保存的当前登录员工的id
        request.getSession().removeAttribute("employee");
        return R.success("退出成功");
    }

以上是day1的内容,但我因为不熟练并还在忙其他事所以并没有在一天之内完成。 作为java新手,我有很多代码看不懂是正常的,所以在一个一个查,并试图进行理解。 在学习语言的时候感觉java其实没有那么难,但刚开始学习springboot的时候就觉得很多恶意。过于冗长的代码,ooc的嵌套,这让前几天还在写Go的我很不适应。其语法糖很怪,有些地方很需要表述,又有很多地方过于抽象。 而且我个人不喜欢注解这种方法,可读性没那么强,让人摸不着头脑。