谷粒学院项目总结(代码片段)

ΘLLΘ ΘLLΘ     2022-12-19     669

关键词:

文章目录

谷粒学院项目总结

1.项目介绍

1.1 采用的商业模式

B2C模式(Business To Customer 会员模式)

商家到用户,这种模式是自己制作大量自有版权的视频,放在自有平台上,让用户按月付费或者按年付费。 这种模式简单,快速,只要专心录制大量视频即可快速发展,其曾因为 lynda 的天价融资而大热。 但在中国由于版权保护意识不强,教育内容易于复制,有海量的免费资源的竞争对手众多等原因,难以取得像样的现金流

1.2 功能模块

谷粒学院,是一个B2C模式的职业技能在线教育系统,分为前台用户系统和后台运营平台

1.3 采用技术

2.Mybatis-Plus相关配置

2.1 配置分页插件

可以在config包下新建一个Mybatis-Plus的配置类MyBatisPlusConfig统一管理:

//使其成为配置类
@Configuration
//开启事务管理
@EnableTransactionManagement
//指定要变成实现类的接口所在的包,然后包下面的所有接口在编译之后都会生成相应的实现类(和在每个类加@Mapper作用相同)
@MapperScan("com.atguigu.eduservice.mapper")
public class MyBatisPlusConfig 
    //配置分页插件
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() 
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
        return interceptor;
    

2.2 自动填充

新建一个MyMetaObjectHandler类实现MetaObjectHandler接口:

//注入到spring
@Component
public class MyMetaObjectHandler implements MetaObjectHandler 
	//插入时自动填充
    @Override
    public void insertFill(MetaObject metaObject) 
        //属性名称,不是字段名称
        this.setFieldValByName("gmtCreate", new Date(), metaObject);
        this.setFieldValByName("gmtModified", new Date(), metaObject);
    

	//更新时自动填充
    @Override
    public void updateFill(MetaObject metaObject) 
        this.setFieldValByName("gmtModified", new Date(), metaObject);
    

在需要自动填充的字段加上注解:

2.3 代码生成器

public class CodeGenerator 
    @Test
    public void run() 
        // 1、创建代码生成器
        AutoGenerator mpg = new AutoGenerator();

        // 2、全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        //项目路径
        gc.setOutputDir("D:\\\\guli_parent\\\\service\\\\service_edu" + "/src/main/java");

        gc.setAuthor("xppll");
        //生成后是否打开资源管理器
        gc.setOpen(false);
        //重新生成时文件是否覆盖
        gc.setFileOverride(false);

        //UserServie
        gc.setServiceName("%sService");    //去掉Service接口的首字母I

        //主键策略
        gc.setIdType(IdType.ID_WORKER_STR);
        //定义生成的实体类中日期类型
        gc.setDateType(DateType.ONLY_DATE);
        //开启Swagger2模式
        gc.setSwagger2(true);

        mpg.setGlobalConfig(gc);

        // 3、数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://localhost:3306/guli?serverTimezone=GMT%2B8");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("root");
        dsc.setDbType(DbType.MYSQL);
        mpg.setDataSource(dsc);

        // 4、包配置
        PackageConfig pc = new PackageConfig();
        //模块名
        pc.setModuleName("eduservice");
        //包  com.atguigu.eduservice
        pc.setParent("com.atguigu");
        //包  com.atguigu.eduservice.controller
        pc.setController("controller");
        pc.setEntity("entity");
        pc.setService("service");
        pc.setMapper("mapper");
        mpg.setPackageInfo(pc);

        // 5、策略配置
        StrategyConfig strategy = new StrategyConfig();

        strategy.setInclude("edu_course", "edu_course_description", "edu_chapter", "edu_video");

        //数据库表映射到实体的命名策略
        strategy.setNaming(NamingStrategy.underline_to_camel);
        //生成实体时去掉表前缀

        strategy.setTablePrefix(pc.getModuleName() + "_");
        //数据库表字段映射到实体的命名策略
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        // lombok 模型 @Accessors(chain = true) setter链式操作
        strategy.setEntityLombokModel(true); 
        //restful api风格控制器
        strategy.setRestControllerStyle(true); 
        //url中驼峰转连字符
        strategy.setControllerMappingHyphenStyle(true); 
        mpg.setStrategy(strategy);
        
        // 6、执行
        mpg.execute();
    

3.Swagger配置

引入Swagger相关依赖:

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <scope>provided </scope>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <scope>provided </scope>
</dependency

可以在config包下新建一个Swagger的配置类SwaggerConfig统一管理:

/**
 * @author xppll
 * @date 2021/11/29 14:56
 */
@Configuration  //配置类
@EnableSwagger2 //swagger注解
public class SwaggerConfig 
    @Bean
    public Docket webApiConfig() 
        return new Docket(DocumentationType.SWAGGER_2)
            .groupName("webApi")
            .apiInfo(webApiInfo())
            .select()
            .paths(Predicates.not(PathSelectors.regex("/admin/.*")))
            .paths(Predicates.not(PathSelectors.regex("/error.*")))
            .build();
    

    private ApiInfo webApiInfo() 
        return new ApiInfoBuilder()
            .title("网站-课程中心API文档")
            .description("本文档描述了课程中心微服务接口定义")
            .version("1.0")
            .contact(new Contact("Helen", "http://atguigu.com",
                                 "55317332@qq.com"))
            .build();
    


访问edu模块,可以看到:

4.统一返回数据格式

项目中我们会将响应封装成json返回,一般我们会将所有接口的数据格式统一, 使前端(iOS Android, Web)对数据的操作更一致、轻松。 一般情况下,统一返回数据格式没有固定的格式,只要能描述清楚返回的数据状态以及要返回的具体数据就可以。但是一般会包含状态码、返回消息、数据这几部分内容

4.1 统一结果返回类

commonutils(公共工具类包)包下创建统一结果返回类R

/**
 * 定义统一返回结果的类
 */
@Data
public class R 
    //swagger的注解
    @ApiModelProperty(value = "是否成功")
    private Boolean success;
    @ApiModelProperty(value = "返回码")
    private Integer code;
    @ApiModelProperty(value = "返回消息")
    private String message;
    @ApiModelProperty(value = "返回数据")
    private Map<String, Object> data = new HashMap<String, Object>();

    //构造方法私有
    public R() 
    

    //成功静态方法
    public static R ok() 
        R r = new R();
        r.setSuccess(true);
        r.setCode(ResultCode.SUCCESS);
        r.setMessage("成功");
        return r;
    
    //失败静态方法
    public static R error()
        R r = new R();
        r.setSuccess(false);
        r.setCode(ResultCode.ERROR);
        r.setMessage("失败");
        return r;
    

    //返回this是为了链式编程,例如 R.ok().code().message()
    public R success(Boolean success) 
        this.setSuccess(success);
        return this;
    

    public R message(String message) 
        this.setMessage(message);
        return this;
    

    public R code(Integer code) 
        this.setCode(code);
        return this;
    

    public R data(String key, Object value) 
        this.data.put(key, value);
        return this;
    

    public R data(Map<String, Object> map) 
        this.setData(map);
        return this;
    


4.2 统一定义返回码

这里又许多种方式,这里列举两种:

1.创建接口定义返回码

public interface ResultCode 
    public static Integer SUCCESS = 20000;
    public static Integer ERROR = 20001;

2.创建枚举类定义返回码

public enum ErrorCode 

    PARAMS_ERROR(10001, "参数有误"),
    ACCOUNT_PWD_NOT_EXIST(10002, "用户名或密码不存在"),
    TOKEN_ERROR(10003, "token不合法"),
    ACCOUNT_EXIST(10004, "账户已存在"),
    NO_PERMISSION(70001, "无访问权限"),
    SESSION_TIME_OUT(90001, "会话超时"),
    NO_LOGIN(90002, "未登录");

    private int code;
    private String msg;

    ErrorCode(int code, String msg) 
        this.code = code;
        this.msg = msg;
    
    //get,set方法...

5.统一异常处理

5.1 创建统一异常处理器

handler包下创建统一异常处理类GlobalExceptionHandler

/**
 * 统一异常处理类
 *
 * @author xppll
 * @date 2021/11/29 19:11
 */
//对加了@Controller的方法进行拦截处理,AOP的实现
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler 
    //进行一次处理,处理Exception.class的异常
    @ExceptionHandler(Exception.class)
    //返回json数据,不加的话直接返回页面
    @ResponseBody
    public R error(Exception e) 
        e.printStackTrace();
        //将信息写到日志文件中去
        log.error(e.getMessage());
        return R.error().message("执行了全局异常处理...");
    


还可以处理特定异常:

//添加特定异常方法
@ExceptionHandler(ArithmeticException.class)
@ResponseBody
public R error(ArithmeticException e)
    e.printStackTrace();
    return R.error().message("执行了特定异常");

5.2 自定义异常处理

handler包下创建自定义异常类GuliException

/**
 * 自定义异常
 * 需要继承RuntimeException
 * @author xppll
 * @date 2021/11/29 20:09
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class GuliException extends RuntimeException 
    //状态码
    private Integer code;
    //异常信息
    private String msg;

处理自定义异常:

//添加自定义异常
//需要自己手动抛出
@ExceptionHandler(GuliException.class)
@ResponseBody
public R error(GuliException e)
    log.error(e.getMessage());
    e.printStackTrace();
    //传入自己定义的参数
    return R.error().code(e.getCode()).message(e.getMsg());

栗子:自己手动抛出

@GetMapping("findAll")
public R list()
    try 
        int a = 10/0;
    catch(Exception e) 
        throw new GuliException(20003,"出现自定义异常");
    
    List<EduTeacher> list = teacherService.list(null);
    return R.ok().data("items",list);

6.统一日志处理

6.1 配置日志级别

日志记录器(Logger)的行为是分等级的。如下表所示: 分为:OFFFATALERRORWARNINFODEBUGALL 默认情况下,spring boot从控制台打印出来的日志级别只有INFO及以上级别,可以配置日志级别:

# 设置日志级别
logging.level.root=WARN

这种配置方式只能将日志打印在控制台上

6.2 Logback日志

spring boot内部使用Logback作为日志实现的框架

配置logback日志

注意:需要删除application.properties中的其它日志配置

resources 中创建 logback-spring.xml(名字必须一模一样!)

<?xml version="1.0" encoding="UTF-8"?>
<configuration  scan="true" scanPeriod="10 seconds">
    <!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
    <!-- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true -->
    <!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
    <!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->

    <contextName>logback</contextName>
    <!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“$”来使用变量。 -->
    <property name="log.path" value="D:/guli_1010/edu" />

    <!-- 彩色日志 -->
    <!-- 配置格式变量:CONSOLE_LOG_PATTERN 彩色日志格式 -->
    <!-- magenta:洋红 -->
    <!-- boldMagenta:粗红-->
    <!-- cyan:青色 -->
    <!-- white:白色 -->
    <!-- magenta:洋红 -->
    <property name="CONSOLE_LOG_PATTERN"
              value="%yellow(%dateyyyy-MM-dd HH:mm:ss) |%highlight(%-5level) |%blue(%thread) |%blue(%file:%line) |%green(%logger) |%cyan(%msg%n)"/>


    <!--输出到控制台-->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <!--此日志appender是为开发

谷粒学院权限管理模块(代码片段)

文章目录谷粒学院项目权限管理模块1.数据库表2.菜单相关操作2.1递归查询全部菜单2.2递归删除菜单2.3给角色分配权限2.4根据角色获取菜单2.5添加菜单2.6修改菜单3.角色相关操作3.1获取角色分页列表3.2其他操作4.用户相关操作4.1获... 查看详情

day201.项目起步mybatisplus谷粒学院(代码片段)

谷粒学院一、起步0、前置知识1、项目背景在线教育顾名思义,是以网络为介质的教学方式,通过网络,学员与教师即使相隔万里也可以开展教学活动;此外,借助网络课件,学员还可以随时随地进行学习&... 查看详情

谷粒学院第四天(代码片段)

一、axios1、介绍2、使用<!DOCTYPEhtml><htmllang="en"><head><title>axios使用</title><scriptsrc="vue.min.js"></script><scriptsrc="axios. 查看详情

谷粒学院——day09整合阿里云视频点播(代码片段)

❤作者主页:Java技术一点通的博客❀个人介绍:大家好,我是Java技术一点通!( ̄▽ ̄)~*🍊记得关注、点赞、收藏、评论⭐️⭐️⭐️📣认真学习,共同进步!!!🎉🎉视... 查看详情

谷粒学院开发:教师管理模块(代码片段)

前后端分离开发前端html,css,js,jq主要作用:数据显示ajax后端controllerservicemapper主要作用:返回数据或操作数据接口讲师管理模块(后端)准备工作创建数据库,创建讲师数据库表CREATETABLE`edu_teacher`(`id&#... 查看详情

阿里云短信服务不对个人开放?如何在阿里云市场免费购买短信服务?云市场购买到的短信服务如何使用?(以谷粒学院项目为例)(代码片段)

问题描述:在做谷粒学院项目时,需要使用阿里云的短信服务用于注册验证,但是阿里云的短信服务目前不对个人开放了,看到弹幕说可以在云市场购买,于是果断尝试了一把,这过程中又遇到头疼的依赖... 查看详情

nuxtcannotresolve“swiper/dist/css/swiper.css“(写谷粒学院碰到)(代码片段)

报错内容这个错就是没找到这个文件,原因如下官方说6.x版本里是没有dist这个文件夹的,所以引入要用swiper/swiper-bundle.css(后面会说在哪里引入),你可以自己找下自己用npminstall命令在node_modules文件夹里下载... 查看详情

谷粒商城简介(代码片段)

...现,采用前后端分离继续编写。项目介绍gulimall(谷粒商城)项目是一套电商项目,包括前台商城系统以及后台管理系统,基于SpringCloud+SpringCloudAlibaba+MyBatis-Plus实现& 查看详情

谷粒商城简介(代码片段)

...现,采用前后端分离继续编写。项目介绍gulimall(谷粒商城)项目是一套电商项目,包括前台商城系统以及后台管理系统,基于SpringCloud+SpringCloudAlibaba+MyBatis-Plus实现& 查看详情

第198天学习打卡(谷粒商城项目排错)(代码片段)

排错AttrServiceImpl.java下加入这个代码后规格参数页面又不显示了@OverridepublicPageUtilsqueryBaseAttrPage(Map<String,Object>params,LongcatelogId,Stringtype)QueryWrapper<AttrEntity>queryWrapper=newQueryW 查看详情

谷粒商城学习笔记--项目快速开发与分布式组件(代码片段)

一、人人项目1、下载人人项目在码云上搜索人人开源,我们使用renren-fast(后端)、renren-fast-vue(前端)项目。https://gitee.com/renreniogitclonehttps://gitee.com/renrenio/renren-fast.gitgitclonehttps://gitee. 查看详情

第189天学习打卡(项目谷粒商城31平台属性规格修改)(代码片段)

平台属性规格修改gulimall.product.voAttrRespVo.javapackagecom.doudou.gulimall.product.vo;importcom.baomidou.mybatisplus.annotation.TableId;importlombok.Data;@DatapublicclassAttrRespVo/***属性id*/@TableI 查看详情

谷粒商城-分布式基础项目环境搭建(代码片段)

目录1. 项目背景2.项目架构3.分布式基础概念3.1.微服务3.2.集群&分布式&节点3.3.远程调用3.4.负载均衡3.5.服务注册/发现&注册中心3.6.配置中心3.7.服务熔断&服务降级 3.8.API网关  4.环境搭建4.1.安装Docker4.2.docker安装mysql1.... 查看详情

第197天学习打卡(项目谷粒商城排错)(代码片段)

P74修改vue这里是规格参数视频和自己的代码,视频的代码可以查询处规格参数的数据,自己的代码查询不到相应的页面,总体排完错再来修改排除发现后面这些是加了其他属性的,是正确的应该是在规格参数的时... 查看详情

第192天学习打卡(项目谷粒商城34新增分组和属性关联)(代码片段)

新增分组与属性关联packagecom.doudou.gulimall.product.controller;importjava.util.Arrays;importjava.util.List;importjava.util.Map;//importorg.apache.shiro.authz.annotation.RequiresPermissions;importcom.doudou.gu 查看详情

谷粒商城学习笔记——第一期:项目简介(代码片段)

一、项目简介1.项目背景市面上有5种常见的电商模式B2B、B2C、C2B、C2C、O2OB2B模式(BusinesstoBusiness),是指商家和商家建立的商业关系。如阿里巴巴B2C模式(BusinesstoConsumer),就是我们经常看到的供应商直接把商品买个用户,... 查看详情

谷粒商城学习笔记——第一期:项目简介(代码片段)

一、项目简介1.项目背景市面上有5种常见的电商模式B2B、B2C、C2B、C2C、O2OB2B模式(BusinesstoBusiness),是指商家和商家建立的商业关系。如阿里巴巴B2C模式(BusinesstoConsumer),就是我们经常看到的供应商直接把商品买个用户,... 查看详情

第191天学习打卡(项目谷粒商城33查询分组未关联的属性)(代码片段)

查询分组未关联的属性packagecom.doudou.gulimall.product.service.impl;importcom.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;importcom.doudou.common.constant.ProductConstant;importcom.doudou.gulimall 查看详情