苍穹外卖01 开始喽

前言

最近开始学习“苍穹外卖”项目,基于Spring Boot和Vue.js的外卖平台项目。我之前做的是学校找的公司外包技术栈和这个项目差不多,但是也是很久之前的事情了哈哈。现在相当于使用苍穹外卖复习一下,之后背八股,刷力扣。与我之前做的项目相比,苍穹外卖在技术栈、架构设计以及业务逻辑上都有很多值得学习和借鉴的地方。为了更好地理解和掌握这个项目,我决定将学习过程中的心得体会记录下来,并与我之前做的项目进行对比分析。

看视频敲代码易,坚持不懈难,记录于此,不求对大家有什么帮助,只求能够自己能够坚持下去。

看这个项目还真的是有些小惊喜。

环境搭建

这里比较常规的就不过多介绍了,这里只介绍一下数据库的安装。
由于我经常使用的MySQL5.7 停更了,去官网下载了压缩包版本(windows版),之前安装windows版本是安装包,点点点就安好了,这里记录一下压缩版的安装过程

代码对比

这里写一些苍穹外卖和我独立开发(哭)的某个公司的无纸办公平台进行一些对比,第一天主要跟着黑马部署了一下环境,可以看到黑马的前期工作有很多都帮我们做好了,并且提供了一个简单的登录流程。

登录流程的对比

苍穹外卖的登录使用的是经典的三层架构模式,既 Controller-service-dao(这里是mapper)模式,而我的登录使用的是SpringSecurity的模式,孰优孰劣还说不准,看后期的表现。
首先来看苍穹外卖

很基本的流程,但是可以看到可以学习的点有很多

  1. 使用了JWT令牌来验证,说实话,对于JWT的了解不多,我之前使用SpringSecurity完全没有担心过类似的验证问题,了解了一下JWT。
  2. 在构建VO时,使用了建造者模式,并且在return的时候又加了一层包装,第二层包装我是没有想到的。我的话可能直接在对象里VO对象设置状态码了。

    使用建造者模式在VO类使用@Builder进行注释

这里查看一下包装的源码,可以看到实现了Serializable接口:

@Data
public class Result<T> implements Serializable {

    private Integer code; //编码:1成功,0和其它数字为失败
    private String msg; //错误信息
    private T data; //数据

    public static <T> Result<T> success() {
        Result<T> result = new Result<T>();
        result.code = 1;
        return result;
    }

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

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

}

我的登录实现

配置SpringSecurity在spring-security.xml中,如下:

```plaintext
<!-- 切换成数据库中的用户名和密码 -->
    <security:authentication-manager>
        <security:authentication-provider user-service-ref="userService">
            <!--             配置加密的方式 -->
            <security:password-encoder ref="passwordEncoder"/>
        </security:authentication-provider>
    </security:authentication-manager>

    <!-- 配置加密类 -->
    <bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>

这里我们可以看到使用userService对security进行注入。
在UserService中可以看到重写了loadUserByUsername方法,这个方法是security提供的接口,来自UserDetailsService,我们自己的接口extends这个接口,通过实现接口来对框架提供用户信息和权限信息。

    // spring 登录实现
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserInfo userInfo = null;
        try {
            userInfo = userDao.findByUsername(username);
        } catch (Exception e) {
            e.printStackTrace();
        }
        User user = new User(userInfo.getUser_name(), userInfo.getPassword(), getAuthority(userInfo.getUser_power()));
        return user;
    }

    // 权限集合转换格式供登录使用
    public List<SimpleGrantedAuthority> getAuthority(List<Power> powers) {
        List<SimpleGrantedAuthority> list = new ArrayList<>();
        for (Power power : powers) {
            list.add(new SimpleGrantedAuthority("ROLE_" + power.getPower_name().toUpperCase()));
        }
        return list;
    }

我们点开security加载用户的源码可以看到如下,我们需要实现的就是这个接口。

Service层

我们再来查看苍穹外卖的service层的登录,其中有一个状态码,表示用户是否启用,这里我使用的是SpringSecurity的权限控制,所有的正常用户都有一个ROLE_USER权限,否则是无法访问除了登录之外的页面的。:


if (employee.getStatus() == StatusConstant.DISABLE) {
    //账号被锁定
    throw new AccountLockedException(MessageConstant.ACCOUNT_LOCKED);
}

dao(mapper)

在dao层,也就是mapper层使用了注解的方式来写sql:

@Mapper
public interface EmployeeMapper {

    /**
     * 根据用户名查询员工
     * @param username
     * @return
     */
    @Select("select * from employee where username = #{username}")
    Employee getByUsername(String username);

}

我除了使用注解,还使用了动态sql,当时做了分表。

 // 登录方法
    @Select("select * from user where user_name = #{username}")
    @Results({
            @Result(id = true, property = "user_id", column = "user_id"),
            @Result(property = "user_name", column = "user_name"),
            @Result(property = "password", column = "password"),
            @Result(property = "user_sex", column = "user_sex"),
            @Result(property = "user_position", column = "user_position"),
            @Result(property = "user_department", column = "user_department"),
            @Result(property = "user_phone", column = "user_phone"),
            @Result(property = "user_email", column = "user_email"),
            @Result(property = "user_power", column = "user_id", javaType = java.util.List.class, many = @Many(select = "com.lsl.OA.dao.PowerDao.findPowerByUserId")),
            @Result(property = "power_id", column = "user_id", javaType = java.util.List.class, many = @Many(select = "com.lsl.OA.dao.UPDao.findPowerIdByUserId"))

    })
    UserInfo findByUsername(String username) throws Exception;
posted @ 2025-02-18 22:29  子画12  阅读(209)  评论(0)    收藏  举报