谷粒学院项目总结

Posted ΘLLΘ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了谷粒学院项目总结相关的知识,希望对你有一定的参考价值。

文章目录

谷粒学院项目总结

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是为开发

以上是关于谷粒学院项目总结的主要内容,如果未能解决你的问题,请参考以下文章

谷粒学院——Day20项目总结

谷粒学院权限管理模块

谷粒学院权限管理模块

Day201.项目起步MyBatisPlus 谷粒学院

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

谷粒商城项目总结