【谷粒学院项目】day02

Author:Honey
软件工程 工科男
CSDN@Honey

前后端分离

在这里插入图片描述

创建MP代码生成器

package com.example.demo;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import org.junit.Test;

/**
 1. @author
 2. @since 2018/12/13
 */
public class CodeGenerator {

    @Test
    public void run() {

        // 1、创建代码生成器
        AutoGenerator mpg = new AutoGenerator();

        // 2、全局配置
        GlobalConfig gc = new GlobalConfig();
        //修改1
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir(projectPath + "/src/main/java");
        gc.setAuthor("testjava");
        gc.setOpen(false); //生成后是否打开资源管理器
        gc.setFileOverride(false); //重新生成时文件是否覆盖
        gc.setServiceName("%sService");	//去掉Service接口的首字母I
         //修改2
        gc.setIdType(IdType.ID_WORKER); //主键策略
        gc.setDateType(DateType.ONLY_DATE);//定义生成的实体类中日期类型
        gc.setSwagger2(true);//开启Swagger2模式

        mpg.setGlobalConfig(gc);

        // 3、数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        //修改3
        dsc.setUrl("jdbc:mysql://localhost:3306/guli");
        dsc.setDriverName("com.mysql.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("root");
        dsc.setDbType(DbType.MYSQL);
        mpg.setDataSource(dsc);

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

        // 5、策略配置
        StrategyConfig strategy = new StrategyConfig();
         //修改5
        strategy.setInclude("edu_teacher");
        strategy.setNaming(NamingStrategy.underline_to_camel);//数据库表映射到实体的命名策略
        strategy.setTablePrefix(pc.getModuleName() + "_"); //生成实体时去掉表前缀

        strategy.setColumnNaming(NamingStrategy.underline_to_camel);//数据库表字段映射到实体的命名策略
        strategy.setEntityLombokModel(true); // lombok 模型 @Accessors(chain = true) setter链式操作

        strategy.setRestControllerStyle(true); //restful api风格控制器
        strategy.setControllerMappingHyphenStyle(true); //url中驼峰转连字符

        mpg.setStrategy(strategy);


        // 6、执行
        mpg.execute();
    }
}

修改:

  1. String projectPath = System.getProperty(“user.dir”);
    为避免出错,修改为Module所在目录,如:

String project Path=“D:\Git\WorkPlace\guli_parent\service\service_edu”;

  1. 主键为varchar,修改为

gc.setIdType(IdType.ID_WORKER_STR); //主键策略

  1. 修改用户名、密码
    数据库配置

dsc.setUrl(“jdbc:mysql://localhost:3306/guli?serverTimezone=GMT%2B8”);
dsc.setDriverName(“com.mysql.cj.jdbc.Driver”);

  1. pc.setModuleName(“edu”); //模块名
    pc.setParent(“com.example.demo”);
    修改对应自己项目

  2. 修改为对应自己项目表名称

使用Swagger2测试编写的接口

  1. 引入依赖
<dependencies>
 <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-web</artifactId>
 <scope>provided </scope>
 </dependency>
 <!--mybatis-plus-->
 <dependency>
 <groupId>com.baomidou</groupId>
 <artifactId>mybatis-plus-boot-starter</artifactId>
 <scope>provided </scope>
 </dependency>
 <!--lombok用来简化实体类:需要安装lombok插件-->
 <dependency>
 <groupId>org.projectlombok</groupId>
 <artifactId>lombok</artifactId>
 <scope>provided </scope>
 </dependency>
 <!--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>
 <!-- redis -->
 <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-data-redis</artifactId>
 </dependency>
 <!-- spring2.X集成redis所需common-pool2
 <dependency>
 <groupId>org.apache.commons</groupId>
 <artifactId>commons-pool2</artifactId>
 <version>2.6.0</version>
 </dependency>-->
 </dependencies>
  1. 创建swagger的配置类
package com.honey.servicebase;

import com.google.common.base.Predicates;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@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();
    }
}

API模型:

@ApiModelProperty(value = "创建时间", example = "2019-01-01 8:00:00")
@TableField(fill = FieldFill.INSERT)
private Date gmtCreate;
@ApiModelProperty(value = "更新时间", example = "2019-01-01 8:00:00")
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date gmtModified;

在这里插入图片描述
定义接口说明和参数说明:
定义在类上:@Api
定义在方法上:@ApiOperation
定义在参数上:@ApiParam

@Api(description="讲师管理")
@RestController
@RequestMapping("/admin/edu/teacher")
public class TeacherAdminController {
 @Autowired
 private TeacherService teacherService;
@ApiOperation(value = "所有讲师列表")
 @GetMapping
 public List<Teacher> list(){
 return teacherService.list(null);
 }
 @ApiOperation(value = "根据ID删除讲师")
 @DeleteMapping("{id}")
 public boolean removeById(
 @ApiParam(name = "id", value = "讲师ID", required = true)
 @PathVariable String id){
 return teacherService.removeById(id);
 }

统一返回数据格式

-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0NTU5MzE3,size_16,color_FFFFFF,t_70)

  1. 创建子模块
  2. 创建interface,定义数据返回状态码
package com.honey.commonutils;

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

3.子模块中创建返回值类型

package com.honey.commonutils;

import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.util.HashMap;
import java.util.Map;
@Data
public class R {
   @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>();

   private 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;
   }

   //用于解决私有构造方法,实现链式编程
   //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.要使用Module引入子模块,并把接口返回类型都改为3中定义R;
在这里插入图片描述

统一异常处理

在这里插入图片描述
自定义异常:

  1. 创建异常处理类
package com.honey.servicebase.exceptionhandler;

import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor //有参构造方法
@NoArgsConstructor  //无参构造方法
public class HoneyException extends RuntimeException{
    @ApiModelProperty(value = "状态码")
    private Integer code;

    private String msg;
}

在这里插入图片描述

  1. 编写自定义异常类GlobalExceptionHandler.java
package com.honey.servicebase.exceptionhandler;

import com.honey.commonutils.ExceptionUtil;
import com.honey.commonutils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 1. 统一异常处理类
 */
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
    //指定出现什么异常执行那个这个方法
    @ExceptionHandler(Exception.class)
    //为了返回数据
    @ResponseBody
    public R error(Exception e){
        e.printStackTrace();
        return R.error().message("执行了全局异常处理");
    }

    //除0异常
    @ExceptionHandler(ArithmeticException.class)
    @ResponseBody
    public R error(ArithmeticException e){
        e.printStackTrace();
        return R.error().message("执行了除0异常处理");
    }

    //自定义异常
    @ExceptionHandler(HoneyException.class)
    @ResponseBody
    public R error(HoneyException e){
        //log.error(e.getMessage());
        log.error(ExceptionUtil.getMessage(e));
        e.printStackTrace();
        return R.error().message(e.getMsg()).code(e.getCode());
    }
}
  1. 执行自定义异常

在这里插入图片描述

统一日志处理

日志记录器(Logger)的行为是分等级的。如下表所示:
分为:OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL
默认情况下,spring boot从控制台打印出来的日志级别只有INFO及以上级别,可以配置日志级别
application.properties中配置日志级别:

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

Logback日志
配置logback日志:

  1. 删除application.properties中的日志配置
    注释掉以下内容
    在这里插入图片描述
  2. 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:/Git/WorkPlace/guli_log/edu" />
   <!-- 彩色日志 -->
   <!-- 配置格式变量:CONSOLE_LOG_PATTERN 彩色日志格式 -->
   <!-- magenta:洋红 -->
   <!-- boldMagenta:粗红-->
   <!-- cyan:青色 -->
   <!-- white:白色 -->
   <!-- magenta:洋红 -->
   <property name="CONSOLE_LOG_PATTERN"
             value="%yellow(%date{yyyy-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是为开发使用,只配置最底级别,控制台输出的日志级别是大于或
       等于此级别的日志信息-->
       <!-- 例如:如果此处配置了INFO级别,则后面其他位置即使配置了DEBUG级别的日
       志,也不会被输出 -->
       <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
           <level>INFO</level>
       </filter>
       <encoder>
           <Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
           <!-- 设置字符集 -->
           <charset>UTF-8</charset>
       </encoder>
   </appender>
   <!--输出到文件-->
   <!-- 时间滚动输出 level为 INFO 日志 -->
   <appender name="INFO_FILE"
             class="ch.qos.logback.core.rolling.RollingFileAppender">
       <!-- 正在记录的日志文件的路径及文件名 -->
       <file>${log.path}/log_info.log</file>
       <!--日志文件输出格式-->
       <encoder>
           <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level
               %logger{50} - %msg%n</pattern>
           <charset>UTF-8</charset>
       </encoder>
       <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
       <rollingPolicy
               class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
           <!-- 每天日志归档路径以及格式 -->
           <fileNamePattern>${log.path}/info/log-info-%d{yyyy-MMdd}.%i.log</fileNamePattern>
           <timeBasedFileNamingAndTriggeringPolicy
                   class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
               <maxFileSize>100MB</maxFileSize>
           </timeBasedFileNamingAndTriggeringPolicy>
           <!--日志文件保留天数-->
           <maxHistory>15</maxHistory>
       </rollingPolicy>
       <!-- 此日志文件只记录info级别的 -->
       <filter class="ch.qos.logback.classic.filter.LevelFilter">
           <level>INFO</level>
           <onMatch>ACCEPT</onMatch>
           <onMismatch>DENY</onMismatch>
       </filter>
   </appender>
   <!-- 时间滚动输出 level为 WARN 日志 -->
   <appender name="WARN_FILE"
             class="ch.qos.logback.core.rolling.RollingFileAppender">
       <!-- 正在记录的日志文件的路径及文件名 -->
       <file>${log.path}/log_warn.log</file>
       <!--日志文件输出格式-->
       <encoder>
           <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level
               %logger{50} - %msg%n</pattern>
           <charset>UTF-8</charset> <!-- 此处设置字符集 -->
       </encoder>
       <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
       <rollingPolicy
               class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
           <fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MMdd}.%i.log</fileNamePattern>
           <timeBasedFileNamingAndTriggeringPolicy
                   class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
               <maxFileSize>100MB</maxFileSize>
           </timeBasedFileNamingAndTriggeringPolicy>
           <!--日志文件保留天数-->
           <maxHistory>15</maxHistory>
       </rollingPolicy>
       <!-- 此日志文件只记录warn级别的 -->
       <filter class="ch.qos.logback.classic.filter.LevelFilter">
           <level>warn</level>
           <onMatch>ACCEPT</onMatch>
           <onMismatch>DENY</onMismatch>
       </filter>
   </appender>
   <!-- 时间滚动输出 level为 ERROR 日志 -->
   <appender name="ERROR_FILE"
             class="ch.qos.logback.core.rolling.RollingFileAppender">
       <!-- 正在记录的日志文件的路径及文件名 -->
       <file>${log.path}/log_error.log</file>
       <!--日志文件输出格式-->
       <encoder>
           <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level
               %logger{50} - %msg%n</pattern>
           <charset>UTF-8</charset> <!-- 此处设置字符集 -->
       </encoder>
       <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
       <rollingPolicy
               class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
           <fileNamePattern>${log.path}/error/log-error-%d{yyyy-MMdd}.%i.log</fileNamePattern>
           <timeBasedFileNamingAndTriggeringPolicy
                   class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
               <maxFileSize>100MB</maxFileSize>
           </timeBasedFileNamingAndTriggeringPolicy>
           <!--日志文件保留天数-->
           <maxHistory>15</maxHistory>
       </rollingPolicy>
       <!-- 此日志文件只记录ERROR级别的 -->
       <filter class="ch.qos.logback.classic.filter.LevelFilter">
           <level>ERROR</level>
           <onMatch>ACCEPT</onMatch>
           <onMismatch>DENY</onMismatch>
       </filter>
   </appender>
   <!--
   <logger>用来设置某一个包或者具体的某一个类的日志打印级别、以及指
   定<appender>。
   <logger>仅有一个name属性,
   一个可选的level和一个可选的addtivity属性。
   name:用来指定受此logger约束的某一个包或者具体的某一个类。
   level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL
   和 OFF,
   如果未设置此属性,那么当前logger将会继承上级的级别。
   -->
   <!--
   使用mybatis的时候,sql语句是debug下才会打印,而这里我们只配置了info,所以想
   要查看sql语句的话,有以下两种操作:
   第一种把<root level="INFO">改成<root level="DEBUG">这样就会打印sql,不过
   这样日志那边会出现很多其他消息
   第二种就是单独给mapper下目录配置DEBUG模式,代码如下,这样配置sql语句会打印,其他还是正常DEBUG级别:
   -->
   <!--开发环境:打印控制台-->
   <springProfile name="dev">
       <!--可以输出项目中的debug日志,包括mybatis的sql日志-->
       <logger name="com.guli" level="INFO" />
       <!--
       root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性
       level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR,
       ALL 和 OFF,默认是DEBUG
       可以包含零个或多个appender元素。
       -->
       <root level="INFO">
           <appender-ref ref="CONSOLE" />
           <appender-ref ref="INFO_FILE" />
           <appender-ref ref="WARN_FILE" />
           <appender-ref ref="ERROR_FILE" />
       </root>
   </springProfile>
   <!--生产环境:输出到文件-->
   <springProfile name="pro">
       <root level="INFO">
           <appender-ref ref="CONSOLE" />
           <appender-ref ref="DEBUG_FILE" />
           <appender-ref ref="INFO_FILE" />
           <appender-ref ref="ERROR_FILE" />
           <appender-ref ref="WARN_FILE" />
       </root>
   </springProfile>
</configuration>

修改value为指定输出目录:

<property name="log.path" value="D:/Git/WorkPlace/guli_log/edu" />

将错误日志输出到文件:
GlobalExceptionHandler.java 中类上添加注解@Slf4j
在这里插入图片描述
添加异常输出语句:
在这里插入图片描述
将日志堆栈信息输出到文件:
创建ExceptionUtil.java工具类

package com.honey.commonutils;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;

public class ExceptionUtil {
    public static String getMessage(Exception e) {
        StringWriter sw = null;
        PrintWriter pw = null;
        try {
            sw = new StringWriter();
            pw = new PrintWriter(sw);
            // 将出错的栈信息输出到printWriter中
            e.printStackTrace(pw);
            pw.flush();
            sw.flush();
        } finally {
            if (sw != null) {
                try {
                    sw.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            if (pw != null) {
                pw.close();
            }
        }
        return sw.toString();
    }
}

调用:

log.error(ExceptionUtil.getMessage(e));

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值