03. 医院设置_后端

1、Swagger2 测试工具

编写和维护接口文档是每个程序员的职责,根据Swagger2可以快速帮助我们编写最新的API接口文档,再也不用担心开会前仍忙于整理各种资料了,间接提升了团队开发的沟通效率。

swagger通过注解表明该接口会生成文档,包括接口名、请求方法、参数、返回信息的等等。

@Api:修饰整个类,描述Controller的作用

@ApiOperation:描述一个类的一个方法,或者说一个接口

@ApiParam:单个参数描述

@ApiModel:用对象来接收参数

@ApiModelProperty:用对象接收参数时,描述对象的一个字段

@ApiImplicitParam:一个请求参数

@ApiImplicitParams:多个请求参数

a. 引入依赖

在common模块pom.xml引入Swagger2依赖

<!--swagger-->
<dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId>
</dependency>
<dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId>
</dependency>
b. 添加swagger2配置类

在service-util模块添加 com.atguigu.yygh.common.config.Swagger2Config 配置类

package com.atguigu.yygh.common.config;/*** Swagger2 配置信息*/
@Configuration
@EnableSwagger2
public class Swagger2Config {@Beanpublic Docket webApiConfig() {return new Docket(DocumentationType.SWAGGER_2).groupName("webApi").apiInfo(webApiInfo()).select()// 只显示api路径下的页面.paths(Predicates.and(PathSelectors.regex("/api/.*"))).build();}@Beanpublic Docket adminApiConfig() {return new Docket(DocumentationType.SWAGGER_2).groupName("adminApi").apiInfo(adminApiInfo()).select()// 只显示 admin 路径下的页面.paths(Predicates.and(PathSelectors.regex("/admin/.*"))).build();}private ApiInfo webApiInfo() {return new ApiInfoBuilder().title("网站-API文档").description("本文档描述了网站微服务接口定义").version("1.0").contact(new Contact("atguigu","http://atguigu.com","codeLemon@163.com")).build();}private ApiInfo adminApiInfo() {return new ApiInfoBuilder().title("后台管理系统——API文档").description("本文档描述了后台管理系统微服务接口定义").version("1.0").contact(new Contact("atguigu", "http://atguigu.com", "codelemon@163.com")).build();}
}
c. 在启动类上添加包扫描

因为Swagger2Config 和启动类不在一个模块下,引入进来之后,需要添加组件扫描。否则不能访问SwaggerUI界面

@SpringBootApplication
@ComponentScan(basePackages = "com.atguigu")
public class ServiceHospApplication {public static void main(String[] args) {SpringApplication.run(ServiceHospApplication.class, args);}
}
2、搭建医院模块(service_hosp)

医院设置主要是用来保存开通医院的一些基本信息,每个医院一条信息,保存了医院编号(平台分配,全局唯一)和接口调用相关的签名key等信息,是整个流程的第一步,只有开通了医院设置信息,才可以上传医院相关信息。

我们所开发的功能就是基于单表的一个CRUD、锁定/解锁和发送签名信息这些基本功能。

a. 创建数据库

表结构:

hosname: 医院名称

hoscode: 医院编号(平台分配,全局唯一,api接口必填信息)

api_url: 医院回调的基础url(如:预约下单,我们要调用该地址去医院下单)

sign_key: 双方api接口调用的签名key,有平台生成

contacts_name: 医院联系人姓名

contacts_phone: 医院联系人手机

status: 状态(锁定/解锁)

#
# Database "yygh_hosp"
#CREATE DATABASE IF NOT EXISTS `yygh_hosp` CHARACTER SET utf8mb4;
USE `yygh_hosp`;#
# Structure for table "hospital_set"
#CREATE TABLE `hospital_set` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',`hosname` varchar(100) DEFAULT NULL COMMENT '医院名称',`hoscode` varchar(30) DEFAULT NULL COMMENT '医院编号',`api_url` varchar(100) DEFAULT NULL COMMENT 'api基础路径',`sign_key` varchar(50) DEFAULT NULL COMMENT '签名秘钥',`contacts_name` varchar(20) DEFAULT NULL COMMENT '联系人',`contacts_phone` varchar(11) DEFAULT NULL COMMENT '联系人手机',`status` tinyint(3) NOT NULL DEFAULT '0' COMMENT '状态',`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',`is_deleted` tinyint(3) NOT NULL DEFAULT '0' COMMENT '逻辑删除(1:已删除,0:未删除)',PRIMARY KEY (`id`),UNIQUE KEY `uk_hoscode` (`hoscode`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='医院设置表';
b. service_hosp.pom

在service下创建service_hosp模块

<parent><groupId>com.atguigu.yygh</groupId><artifactId>service</artifactId><version>0.0.1-SNAPSHOT</version>
</parent><groupId>com.atguigu.yygh</groupId>
<artifactId>service_hosp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>service-hosp</name>
<description>service-hosp</description><dependencies>
</dependencies><build><finalName>service-hosp</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins>
</build>
c. application.yaml
# 服务端口
server:port: 8201spring:application:# 服务名name: service-hosp# 环境设置:dev、test、prodprofiles:active: dev# 数据库连接datasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/yygh_hosp?characterEncoding=utf-8&useSSL=falseusername: rootpassword: 0903he0419# 返回json的全局时间格式jackson:date-format: yyyy-MM-dd HH:mm:sstime-zone: GMT+8mybatis-plus:#配置mapper xml文件的路径mapper-locations: com/atguigu/yygh/hosp/mapper/xml/*.xml
d. 创建配置类

在com.atguigu.yygh.hosp.config 创建HospConfig 配置类

将mapper扫描放在配置类上

@Configuration
@MapperScan("com.atguigu.yygh.hosp.mapper")
public class HospConfig {// Mybatis-Plus 分页插件@Beanpublic PaginationInterceptor paginationInterceptor() {return new PaginationInterceptor();}
}
e. 导入实体类

BaseEntity

@Data
public class BaseEntity implements Serializable {@ApiModelProperty(value = "id")@TableId(type = IdType.AUTO)private Long id;@ApiModelProperty(value = "创建时间")@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")@TableField("create_time")private Date createTime;@ApiModelProperty(value = "更新时间")@TableField("update_time")private Date updateTime;@ApiModelProperty(value = "逻辑删除(1:已删除,0:未删除)")@TableLogic@TableField("is_deleted")private Integer isDeleted;@ApiModelProperty(value = "其他参数")@TableField(exist = false)private Map<String,Object> param = new HashMap<>();
}

com.atguigu.yygh.model.hosp.HospitalSet

@Data
@ApiModel(description = "医院设置")
@TableName("hospital_set")
public class HospitalSet extends BaseEntity {private static final long serialVersionUID = 1L;@ApiModelProperty(value = "医院名称")@TableField("hosname")private String hosname;@ApiModelProperty(value = "医院编号")@TableField("hoscode")private String hoscode;@ApiModelProperty(value = "api基础路径")@TableField("api_url")private String apiUrl;@ApiModelProperty(value = "签名秘钥")@TableField("sign_key")private String signKey;@ApiModelProperty(value = "联系人姓名")@TableField("contacts_name")private String contactsName;@ApiModelProperty(value = "联系人手机")@TableField("contacts_phone")private String contactsPhone;@ApiModelProperty(value = "状态")@TableField("status")private Integer status;}

HospitalSetVo

@Data
public class HospitalSetQueryVo {@ApiModelProperty(value = "医院名称")private String hosname;@ApiModelProperty(value = "医院编号")private String hoscode;
}
f. 创建统一返回结果类

Result

/*** 全局统一返回结果类*/
@Data
@ApiModel(value = "全局统一返回结果")
public class Result<T> {@ApiModelProperty(value = "返回码")private Integer code;@ApiModelProperty(value = "返回消息")private String message;@ApiModelProperty(value = "返回数据")private T data;public Result(){}protected static <T> Result<T> build(T data) {Result<T> result = new Result<T>();if (data != null)result.setData(data);return result;}public static <T> Result<T> build(T body, ResultCodeEnum resultCodeEnum) {Result<T> result = build(body);result.setCode(resultCodeEnum.getCode());result.setMessage(resultCodeEnum.getMessage());return result;}public static <T> Result<T> build(Integer code, String message) {Result<T> result = build(null);result.setCode(code);result.setMessage(message);return result;}public static<T> Result<T> ok(){return Result.ok(null);}/*** 操作成功* @param data* @param <T>* @return*/public static<T> Result<T> ok(T data){Result<T> result = build(data);return build(data, ResultCodeEnum.SUCCESS);}public static<T> Result<T> fail(){return Result.fail(null);}/*** 操作失败* @param data* @param <T>* @return*/public static<T> Result<T> fail(T data){Result<T> result = build(data);return build(data, ResultCodeEnum.FAIL);}public Result<T> message(String msg){this.setMessage(msg);return this;}public Result<T> code(Integer code){this.setCode(code);return this;}public boolean isOk() {if(this.getCode().intValue() == ResultCodeEnum.SUCCESS.getCode().intValue()) {return true;}return false;}
}

ResultCodeEnum

/*** 统一返回结果状态信息类*/
@Getter
public enum ResultCodeEnum {SUCCESS(200,"成功"),FAIL(201, "失败"),PARAM_ERROR( 202, "参数不正确"),SERVICE_ERROR(203, "服务异常"),DATA_ERROR(204, "数据异常"),DATA_UPDATE_ERROR(205, "数据版本异常"),LOGIN_AUTH(208, "未登陆"),PERMISSION(209, "没有权限"),CODE_ERROR(210, "验证码错误"),
//    LOGIN_MOBLE_ERROR(211, "账号不正确"),LOGIN_DISABLED_ERROR(212, "改用户已被禁用"),REGISTER_MOBLE_ERROR(213, "手机号已被使用"),LOGIN_AURH(214, "需要登录"),LOGIN_ACL(215, "没有权限"),URL_ENCODE_ERROR( 216, "URL编码失败"),ILLEGAL_CALLBACK_REQUEST_ERROR( 217, "非法回调请求"),FETCH_ACCESSTOKEN_FAILD( 218, "获取accessToken失败"),FETCH_USERINFO_ERROR( 219, "获取用户信息失败"),//LOGIN_ERROR( 23005, "登录失败"),PAY_RUN(220, "支付中"),CANCEL_ORDER_FAIL(225, "取消订单失败"),CANCEL_ORDER_NO(225, "不能取消预约"),HOSCODE_EXIST(230, "医院编号已经存在"),NUMBER_NO(240, "可预约号不足"),TIME_NO(250, "当前时间不可以预约"),SIGN_ERROR(300, "签名错误"),HOSPITAL_OPEN(310, "医院未开通,暂时不能访问"),HOSPITAL_LOCK(320, "医院被锁定,暂时不能访问"),;private Integer code;private String message;private ResultCodeEnum(Integer code, String message) {this.code = code;this.message = message;}
}
g. Mapper 层

com.atguigu.yygh.model.hosp.mapper

@Mapper
public interface HospitalSetMapper extends BaseMapper<HospitalSet> {
}

com.atguigu.yygh.model.hosp.mapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.yygh.hosp.mapper.HospitalSetMapper"></mapper>
h. Service 层

com.atguigu.yygh.model.hosp.service

public interface HospitalSetService extends IService<HospitalSet> {
}

com.atguigu.yygh.model.hosp.service.impl

@Service
public class HospitalSetServiceImpl extends ServiceImpl<HospitalSetMapper, HospitalSet> implements HospitalSetService {@Autowiredprivate HospitalSetMapper hospitalSetMapper;
}
i. Controller 层

com.atguigu.yygh.model.hosp.controller

package com.atguigu.yygh.hosp.controller;@Api(tags = "医院设置管理")
@RestController
@RequestMapping("/admin/hosp/hospitalSet")
public class HospitalSetController {@Autowiredprivate HospitalSetService hospitalSetService;/** 1、查询医院设置表所有信息* */@ApiOperation(value = "获取所有医院设置")@GetMapping("findAll")public Result findAllHospitalSet() {// 调用 service的方法List<HospitalSet> list = hospitalSetService.list();return Result.ok(list);}/** 2、逻辑删除医院设置* */@ApiOperation(value = "逻辑删除医院设置")@DeleteMapping("{id}")public Result removeHospSet(@PathVariable Long id) {boolean flag = hospitalSetService.removeById(id);if (flag) {return Result.ok();} else {return Result.fail();}}/** 3、条件查询带分页* */@ApiOperation(value = "条件查询带分页")@PostMapping("findPageHospSet/{current}/{limit}")public Result findPageHospSet(@PathVariable long current,@PathVariable long limit,@RequestBody(required = false)HospitalSetQueryVo hospitalSetQueryVo) {// 创建 page 对象,传递当前页,每页记录数Page<HospitalSet> page = new Page<>(current, limit);QueryWrapper<HospitalSet> wrapper = new QueryWrapper<>();String hosname = hospitalSetQueryVo.getHosname();//医院名称String hoscode = hospitalSetQueryVo.getHoscode();//医院编号if (!StringUtils.isEmpty(hosname)) {wrapper.like("hosname", hospitalSetQueryVo.getHosname());}if (!StringUtils.isEmpty(hoscode)) {wrapper.eq("hosocde", hospitalSetQueryVo.getHoscode());}// 调用方法实现分页查询Page<HospitalSet> pageHospitalSet = hospitalSetService.page(page, wrapper);// 返回结果return Result.ok(pageHospitalSet);}/** 4、添加医院设置* */@ApiOperation(value = "添加医院设置")@PostMapping("saveHospitalSet")public Result saveHospitalSet(@RequestBody HospitalSet hospitalSet) {// 设置状态:1 使用,0 不能使用hospitalSet.setStatus(1);// 签名秘钥Random random = new Random();hospitalSet.setSignKey(MD5.encrypt(System.currentTimeMillis() + "" + random.nextInt(1000)));//调用serviceboolean save = hospitalSetService.save(hospitalSet);if (save) {return Result.ok();} else {return Result.fail();}}/** 5、根据id获取医院设置* */@ApiOperation(value = "根据id获取医院设置")@GetMapping("getHospSet/{id}")public Result getHospSet(@PathVariable Long id) {HospitalSet hospitalSet = hospitalSetService.getById(id);return Result.ok(hospitalSet);}/** 6、修改医院设置* */@ApiOperation(value = "修改医院设置")@PostMapping("updateHospitalSet")public Result updateHospitalSet(@RequestBody HospitalSet hospitalSet) {boolean flag = hospitalSetService.updateById(hospitalSet);if (flag) {return Result.ok();} else {return Result.fail();}}/** 7、批量删除医院设置* */@ApiOperation(value = "批量删除医院设置")@DeleteMapping("batchRemove")public Result batchRemoveHospitalSet(@RequestBody List<Long> idList) {boolean flag = hospitalSetService.removeByIds(idList);if (flag) {return Result.ok();} else {return Result.fail();}}/** 8、医院设置锁定与解锁* */@ApiOperation(value = "医院设置锁定与解锁")@PutMapping("lockHospitalSet/{id}/{status}")public Result lockHospitalSet(@PathVariable Long id,@PathVariable Integer status) {// 根据id查询医院设置信息HospitalSet hospitalSet = hospitalSetService.getById(id);// 设置状态hospitalSet.setStatus(status);// 调用方法hospitalSetService.updateById(hospitalSet);return Result.ok();}/** 9、发送签名秘钥* */@PutMapping("sendKey/{id}")public Result lockHospitalSet(@PathVariable Long id) {HospitalSet hospitalSet = hospitalSetService.getById(id);String signKey = hospitalSet.getSignKey();String hoscode = hospitalSet.getHoscode();// TODO 发送短信return Result.ok();}
}
j. 统一异常处理

在common-util模块添加自定义异常处理类——YyghException

@Data
@ApiModel(value = "自定义全局异常类")
public class YyghException extends RuntimeException {@ApiModelProperty(value = "异常状态码")private Integer code;/*** 通过状态码和错误消息创建异常对象* @param message* @param code*/public YyghException(String message, Integer code) {super(message);this.code = code;}/*** 接收枚举类型对象* @param resultCodeEnum*/public YyghException(ResultCodeEnum resultCodeEnum) {super(resultCodeEnum.getMessage());this.code = resultCodeEnum.getCode();}@Overridepublic String toString() {return "YyghException{" +"code=" + code +", message=" + this.getMessage() +'}';}
}

在common-util模块添加全局异常处理类——GlobalExceptionHandler

/*
* 全局异常处理类
* */
@RestControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(Exception.class)public Result error(Exception e) {e.printStackTrace();return Result.fail();}/** 自定义异常处理* */@ExceptionHandler(YyghException.class)public Result error(YyghException e) {e.printStackTrace();System.out.println(e.getCode() + " : " + e.getMessage());return Result.build(e.getCode(), e.getMessage());}
}

在controller中测试全局异常是否生效:访问根据id获取医院设置此接口测试自定义异常

/*
* 5、根据id获取医院设置
* */
@ApiOperation(value = "根据id获取医院设置")
@GetMapping("getHospSet/{id}")
public Result getHospSet(@PathVariable Long id) {try {// 模拟异常int a = 1 / 0;} catch (Exception e) {throw new YyghException("失败了呀", 2002);}HospitalSet hospitalSet = hospitalSetService.getById(id);return Result.ok(hospitalSet);
}
k. 统一日志处理

日志记录器(Logger)的行为是分等级的。如下表所示:分为:OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL

默认情况下,spring boot从控制台打印出来的日志级别只有INFO及以上级别,可以配置日志级别

# 设置日志级别
logging:level:root: debug
  • 这种方式只能将日志打印在控制台上

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:/yygh_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-MM-dd}.%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-MM-dd}.%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-MM-dd}.%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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/223320.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vuepress-----25、右侧目录

# 25、vuepress 右侧目录 https://github.com/xuek9900/vuepress-plugin-right-anchor vuepress-plugin-right-anchor English &#xff5c;中文 在用 Vuepress 2.x 编写的文档页面右侧添加 锚点导航栏 # 版本 2.x.x -> Vuepress 2.x -> npm next -> master 分支0…

PS扣印章

1 印章区域图片 2 3 吸取印章上的颜色&#xff0c;调节容差&#xff0c;尽量小一点&#xff0c;过大会将背景也进来 4 CtrlJ 把选区复制出来&#xff0c;这个印章图层比较淡&#xff0c;可以通过多复制几个叠加或通过叠加模式来调节。 5 对几个图层选中后CtrlE合并图层 6 选…

IT圈茶余饭后的“鄙视链”

哈哈&#xff0c;IT圈的鄙视链&#xff0c;简直就是一出情感大戏&#xff01;这个圈子里的人们总是忍不住要互相比较&#xff0c;互相鄙视&#xff0c;仿佛这是一场刺激的游戏&#xff0c;每个人都想要站在鄙视链的最顶端&#xff0c;成为那个最牛逼的存在。 首先&#xff0c;…

深度学习第5天:GAN生成对抗网络

☁️主页 Nowl &#x1f525;专栏 《深度学习》 &#x1f4d1;君子坐而论道&#xff0c;少年起而行之 ​​ 文章目录 一、GAN1.基本思想2.用途3.模型架构 二、具体任务与代码1.任务介绍2.导入库函数3.生成器与判别器4.预处理5.模型训练6.图片生成7.不同训练轮次的结果对比 一…

CSS特效030:日蚀动画

CSS常用示例100专栏目录 本专栏记录的是经常使用的CSS示例与技巧&#xff0c;主要包含CSS布局&#xff0c;CSS特效&#xff0c;CSS花边信息三部分内容。其中CSS布局主要是列出一些常用的CSS布局信息点&#xff0c;CSS特效主要是一些动画示例&#xff0c;CSS花边是描述了一些CSS…

高级C#技术(二)

前言 本章为高级C#技术的第二节也是最后一节。前一节在下面这个链接 高级C#技术https://blog.csdn.net/qq_71897293/article/details/134930989?spm1001.2014.3001.5501 匿名类型 匿名类型如其名&#xff0c;匿名的没有指定变量的具体类型。 举个例子&#xff1a; 1 创建…

SpringBoot运维中的高级配置

&#x1f648;作者简介&#xff1a;练习时长两年半的Java up主 &#x1f649;个人主页&#xff1a;程序员老茶 &#x1f64a; ps:点赞&#x1f44d;是免费的&#xff0c;却可以让写博客的作者开心好久好久&#x1f60e; &#x1f4da;系列专栏&#xff1a;Java全栈&#xff0c;…

2023年【烟花爆竹经营单位主要负责人】免费试题及烟花爆竹经营单位主要负责人模拟考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 烟花爆竹经营单位主要负责人免费试题参考答案及烟花爆竹经营单位主要负责人考试试题解析是安全生产模拟考试一点通题库老师及烟花爆竹经营单位主要负责人操作证已考过的学员汇总&#xff0c;相对有效帮助烟花爆竹经营…

vscode报错:建立连接:XHR failed

文章目录 问题解决方案 问题 Windows端ssh远程连接Linux端&#xff0c;Windows端vscode报错&#xff1a;“…XHR failed.” 解决方案 参考&#xff1a;解决 Windows 端 VS Code “无法与 “…“ 建立连接&#xff1a;XHR failed.” 问题 亲测有效。 总结&#xff1a; linux…

TreeSelect 树型选择控件 编辑回显时所选的值与展开后的数据不对应 解决方案

一、业务场景&#xff1a; 最近在使用Vue框架和antd-vue组件库的时候&#xff0c;发现在做编辑回显时** TreeSelect 树型选择控件** 组件的选中的值能拿到&#xff0c;但是在下拉列表的回显位置有偏差。为了大家后面遇到和我一样的问题&#xff0c;给大家分享一下 二、bug信息…

基于ssm毕业生就业管理平台论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本毕业生就业管理平台就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信…

Mesh里面的MFB是什么文件,工程重置了能否还原?

答&#xff1a;模方工程重置了以后&#xff0c;如果有备份可以还原。 模方是一款针对实景三维模型的冗余碎片、水面残缺、道路不平、标牌破损、纹理拉伸模糊等共性问题研发的实景三维模型修复编辑软件。模方4.1新增自动单体化建模功能&#xff0c;支持一键自动提取房屋结构&am…

JVM垃圾回收算法

自动化的管理内存资源&#xff0c;垃圾回收机制必须要有一套算法来进行计算&#xff0c;哪些是有效的对象&#xff0c;哪些是无效的对象&#xff0c;对于无效的对象就要进行回收处理。 常见的垃圾回收算法有&#xff1a;引用计数法、标记清除法、标记压缩法、复制算法、分代算…

如何消除视频中的背景噪音

如果你在繁忙的街道上、刮风的日子、或在其他有嘈杂声音的周围拍摄视频&#xff0c;则会产生令人烦恼的噪音。幸运的是&#xff0c;从视频中消除背景噪音并不是一件困难的事情&#xff0c;因为有许多可靠的降噪软件可以提供帮助。本文就收集了3种最佳方法&#xff0c;可帮助你轻…

[RoarCTF 2019]Easy Calc1 wp

[RoarCTF 2019]Easy Calc1 wp 预测试 手工测试 这个页面实现了一个简单的计算器功能&#xff0c;当输入 11 时能正确返回执行结果 2&#xff0c; 但当输入 11&&ifconfig 之类的表达式时&#xff0c;会出现弹窗&#xff1a; 查看源码 前端页面调用了一个函数&#xf…

掌握 RPC 接口测试:一篇详尽的接口测试手册

RPC 是什么&#xff1f; 远程过程调用协议&#xff08;RPC&#xff09;是一种技术&#xff0c;它允许在不同的机器上执行函数&#xff0c;就好像这些函数是本地调用一样。简单地说&#xff0c;客户端系统透明地从网络上的远程服务器软件请求服务&#xff0c;而无需理解复杂的网…

借助文档控件Aspose.Words,在Java中比较 Word、PDF 和 PPT 文档

文档比较是各个领域的一项关键任务&#xff0c;包括法律、出版和内容管理。它确保准确跟踪和审查对合同、报告或法律协议等文档的更改。Java 开发人员经常寻求高效可靠的方法来执行文档比较&#xff0c;而Aspose提供了强大的解决方案。在这篇博文中&#xff0c;我们将探讨如何高…

浏览器的事件循环机制(Event loop)

事件循环 浏览器的进程模型 何为进程&#xff1f; 程序运行需要有它自己专属的内存空间&#xff0c;可以把这块内存空间简单的理解为进程 每个应用至少有一个进程&#xff0c;进程之间相互独立&#xff0c;即使要通信&#xff0c;也需要双方同意。 何为线程&#xff1f; …

C语言——字符函数和字符串函数(二)

&#x1f4dd;前言&#xff1a; 上一篇文章C语言——字符函数和字符串函数&#xff08;一&#xff09;对字符函数和字符串函数strlen&#xff0c;strcpy和strncpy&#xff0c;strcat和strncat进行了初步的讲解 这篇文章主要再讲解几个我们常用到的其他字符串函数&#xff08;附…

teamCity使用

1.server部署 2.地址 http://10.172.48.7:32204/favorite/projects?modebuilds 3.新增项目 拉取git项目 编辑配置 复制其他项目配置 步骤1.Maven 步骤2 build image 步骤3 push image 步骤4 deploy to k8s