SpringBoot实战-(5) 讲师分页、条件查询,统一异常处理,统一日志处理

以下内容参考自下面视频:

https://www.bilibili.com/video/BV1y7411y7am

1.分页查询

1.1 配置分页插件

在EduConfig类中配置

SpringBoot实战-(5) 讲师分页、条件查询,统一异常处理,统一日志处理_第1张图片

/**
 * 分页插件
 */
@Bean
public PaginationInterceptor paginationInterceptor(){
    return new PaginationInterceptor();
}

1.2 在Controller中调用

/**
 * 分页查询
 */
@GetMapping("pageTeacher/{current}/{limit}")
public R pageListTeacher(@PathVariable long current,@PathVariable long limit){
    Page<EduTeacher> pageTeacher = new Page<>(current, limit);
    teacherService.page(pageTeacher, null);

    long total = pageTeacher.getTotal();
    List<EduTeacher> records = pageTeacher.getRecords();

    return R.ok().data("total",total).data("records",records);
}

2.条件、分页组合查询

SpringBoot实战-(5) 讲师分页、条件查询,统一异常处理,统一日志处理_第2张图片

2.1 创建条件查询实体类

@Data
public class TeacherQuery {
    @ApiModelProperty(value = "教师名称,模糊查询")
    private String name;

    @ApiModelProperty(value = "头衔 1高级讲师 2首席讲师")
    private Integer level;

    @ApiModelProperty(value = "查询开始时间", example = "2019-01-01 10:10:10")
    private String begin;//注意,这里使用的是String类型,前端传过来的数据无需进行类型转换

    @ApiModelProperty(value = "查询结束时间", example = "2019-12-01 10:10:10")
    private String end;
}

2.2 在Controller中调用

@RequestBody(required = false) 传递的参数以json形式传递,可以没有

@PostMapping 使用Post才能接收到json形式的参数,get不行

/**
 * 条件、分页组合查询
 */
@PostMapping("pageTeacherCondition/{current}/{limit}")
public R pageTeacherCondition(@PathVariable long current, @PathVariable long limit,
                              @RequestBody(required = false)TeacherQuery teacherQuery){
    //创建page对象
    Page<EduTeacher> pageTeacher = new Page<>(current, limit);

    //创建wrapper对象
    QueryWrapper<EduTeacher> wrapper = new QueryWrapper<>();

    //判断teacherQuery对象中的属性是否为空,不为空的话,添加到wrapper中
    String name = teacherQuery.getName();
    Integer level = teacherQuery.getLevel();
    String begin = teacherQuery.getBegin();
    String end = teacherQuery.getEnd();

    if (!StringUtils.isEmpty(name)){
        wrapper.like("name",name);
    }
    if (!StringUtils.isEmpty(level)){
        wrapper.eq("lever",level);
    }
    if (!StringUtils.isEmpty(begin)){
        wrapper.ge("gmt_create",begin);
    }
    if (!StringUtils.isEmpty(end)){
        wrapper.ge("gmt_create",end);
    }

    //查询
    teacherService.page(pageTeacher, wrapper);

    long total = pageTeacher.getTotal();
    List<EduTeacher> records = pageTeacher.getRecords();

    return R.ok().data("total",total).data("records",records);
}

3.添加讲师

3.1 添加注解

在实体类的属性上添加字自动填充注解

@ApiModelProperty(value = "创建时间")
@TableField(fill = FieldFill.INSERT)
private Date gmtCreate;

@ApiModelProperty(value = "更新时间")
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date gmtModified;

3.2 配置自动填充插件

在下图所示结构中新建MyMetaObjectHandler类

SpringBoot实战-(5) 讲师分页、条件查询,统一异常处理,统一日志处理_第3张图片

该类能使用的前提还需要在启动类上配置

@ComponentScan(basePackages = {“com.atguigu”}),

因为之前已经配置过,此处不再配置

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

3.3 编写Controller

/**
 * 添加讲师
 */
@PostMapping("addTeacher")
public R addTeacher(@RequestBody EduTeacher eduTeacher){
    boolean save = teacherService.save(eduTeacher);
    return save ? R.ok() : R.error();
}

4.根据id查询讲师

/**
 * 根据id查询对应讲师
 * @param id
 * @return
 */
@ApiOperation(value = "根据id查询对应讲师")
@GetMapping("getTeacher/{id}")
public R getTeacher(@PathVariable String id){
    EduTeacher eduTeacher = teacherService.getById(id);
    return R.ok().data("teacher",eduTeacher);
}

5.修改讲师

/**
 * 根据id修改对应讲师
 * @param eduTeacher
 * @return
 */
@ApiOperation(value = "根据id修改对应讲师")
@PostMapping("updateTeacher")
public R updateTeacher(@RequestBody EduTeacher eduTeacher){
    boolean update = teacherService.updateById(eduTeacher);
    return update ? R.ok() :R.error();
}

6.全局异常处理

6.1 创建统一异常处理类

在下面结构中创建GlobalExceptionHandler类

SpringBoot实战-(5) 讲师分页、条件查询,统一异常处理,统一日志处理_第4张图片
@ControllerAdvice 使用 @ControllerAdvice 实现全局异常处理,只需要定义类,添加该注解即可

@ExceptionHandler(Exception.class) 指定出现什么异常执行这个方法

@ResponseBody 为了返回数据

@ControllerAdvice
public class GlobalExceptionHandler {

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

6.2 导入依赖

因为要使用的R类与当前类不在一个包下

所以要导入相关包

在service_base下引入common_utils包

<artifactId>service_baseartifactId>

<dependencies>
    <dependency>
        <groupId>com.atguigugroupId>
        <artifactId>common_utilsartifactId>
        <version>0.0.1-SNAPSHOTversion>
    dependency>
dependencies>

同时

因为之前在service包下引入了service_base包和common_utils包,此处应该将common_utils包的依赖注释掉

根据maven的依赖传递

在service_base包中引入common_utils包后

其他包再引入service_base包时候,就会包含common_utils包

<artifactId>serviceartifactId>
    <packaging>pompackaging>
    <modules>
        <module>service_edumodule>
    modules>

    <dependencies>

        <dependency>
            <groupId>com.atguigugroupId>
            <artifactId>service_baseartifactId>
            <version>0.0.1-SNAPSHOTversion>
        dependency>
            





        

7.特定异常处理

//特定异常
@ExceptionHandler(ArithmeticException.class)
@ResponseBody    //为了返回数据
public R error(ArithmeticException e){
    e.printStackTrace();
    return R.error().message("执行了ArithmeticException异常处理......");
}

8.自定义异常

8.1 新建自定义异常类

类的位置如下

SpringBoot实战-(5) 讲师分页、条件查询,统一异常处理,统一日志处理_第5张图片
类的内容如下

@Data
@AllArgsConstructor
@NoArgsConstructor
public class GuliException extends RuntimeException {
    private Integer code;   //状态码

    private String msg;  //异常信息
}

8.2 使用自定义的异常类

//自定义异常
@ExceptionHandler(GuliException.class)
@ResponseBody    //为了返回数据
public R error(GuliException e){
    e.printStackTrace();
    return R.error().code(e.getCode()).message(e.getMsg());
}

8.3 在controlelr中调用

SpringBoot实战-(5) 讲师分页、条件查询,统一异常处理,统一日志处理_第6张图片

9.统一日志处理

9.1 更改默认日志级别

在application.properties文件中对日志的级别进行配置,默认的是INFO

常用的还有ERROR WRAN INFO DEBUG ALL等

需要注意的是,后边的级别包含前边的级别

#设置日志级别 ERROR WRAN INFO DEBUG ALL
logging.level.root=DEBUG

9.2 自定义日志-logback

9.2.1 注释掉原来设置的日志级别

#mybatis日志
#mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

#设置日志级别 ERROR WRAN INFO DEBUG ALL
#logging.level.root=DEBUG

9.2.2 新建logback-spring.xml文件

在resources下新建logback-spring.xml文件

注意设置日志的输出地


<configuration  scan="true" scanPeriod="10 seconds">
    
    
    
    

    <contextName>logbackcontextName>
    
    <property name="log.path" value="E:/MarkDown学习/guliProgram/edu" />

    
    
    
    
    
    
    
    <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">
        
        
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFOlevel>
        filter>
        <encoder>
            <Pattern>${CONSOLE_LOG_PATTERN}Pattern>
            
            <charset>UTF-8charset>
        encoder>
    appender>


    

    
    <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        
        <file>${log.path}/log_info.logfile>
        
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%npattern>
            <charset>UTF-8charset>
        encoder>
        
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            
            <fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.logfileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MBmaxFileSize>
            timeBasedFileNamingAndTriggeringPolicy>
            
            <maxHistory>15maxHistory>
        rollingPolicy>
        
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFOlevel>
            <onMatch>ACCEPTonMatch>
            <onMismatch>DENYonMismatch>
        filter>
    appender>

    
    <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        
        <file>${log.path}/log_warn.logfile>
        
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%npattern>
            <charset>UTF-8charset> 
        encoder>
        
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.logfileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MBmaxFileSize>
            timeBasedFileNamingAndTriggeringPolicy>
            
            <maxHistory>15maxHistory>
        rollingPolicy>
        
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>warnlevel>
            <onMatch>ACCEPTonMatch>
            <onMismatch>DENYonMismatch>
        filter>
    appender>


    
    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        
        <file>${log.path}/log_error.logfile>
        
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%npattern>
            <charset>UTF-8charset> 
        encoder>
        
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.logfileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MBmaxFileSize>
            timeBasedFileNamingAndTriggeringPolicy>
            
            <maxHistory>15maxHistory>
        rollingPolicy>
        
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERRORlevel>
            <onMatch>ACCEPTonMatch>
            <onMismatch>DENYonMismatch>
        filter>
    appender>

    
    
    
    <springProfile name="dev">
        
        <logger name="com.guli" level="INFO" />

        
        <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>

9.2.3 使用

启动项目,在设置的文件夹下即可看到对应的文件

SpringBoot实战-(5) 讲师分页、条件查询,统一异常处理,统一日志处理_第7张图片

9.2.4 更多设置

例如在异常类上的设置,可以把更多信息输入的文件中

此外还有一些设置,此处不再细述

注意要添加下面的注解和方法

@Slf4j

log.error(e.getMsg());

@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    //自定义异常
    @ExceptionHandler(GuliException.class)
    @ResponseBody    //为了返回数据
    public R error(GuliException e){
        log.error(e.getMsg());
        e.printStackTrace();
        return R.error().code(e.getCode()).message(e.getMsg());
    }
}
ation>

9.2.3 使用

启动项目,在设置的文件夹下即可看到对应的文件

[外链图片转存中…(img-fpLNmb0j-1594567776547)]

9.2.4 更多设置

例如在异常类上的设置,可以把更多信息输入的文件中

此外还有一些设置,此处不再细述

注意要添加下面的注解和方法

@Slf4j

log.error(e.getMsg());

@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    //自定义异常
    @ExceptionHandler(GuliException.class)
    @ResponseBody    //为了返回数据
    public R error(GuliException e){
        log.error(e.getMsg());
        e.printStackTrace();
        return R.error().code(e.getCode()).message(e.getMsg());
    }
}

你可能感兴趣的:(springboot)