03-学成在线内容管理模块之课程查询

课程查询

需求分析

教学机构人员点击课程管理按钮进入课程查询界面,在课程列表页面输入查询条件查询课程的信息

  • 当不输入查询条件时默认会全部课程信息,输入查询条件会查询符合条件的课程信息,约束条件是本教学机构查询本机构的课程信息

数据模型(model工程)

课程查询功能涉及到的数据表有课程基本信息表,教学计划表

创建数据字典表: 在课程基本信息表中直接记录审核未通过的字符串不利于后期修改,如果有一天客户想要将数据表中审核未通过的记录在显示时改为未通过三个字就很麻烦

对于分类项较为固定的数据(如课程状态、课程类型、用户类型等),为了提高系统的可扩展性可以专门定义数据字典表去维护

  • 如果审核状态为审核未通过,在课程基本信息表存储审核未通过对应的代码202001,前端在展示查询出的数据时再根据代码取出它对应的文字描述显示给用户
[
    {"code":"202001","desc":"审核未通过"},
    {"code":"202002","desc":"未审核"},
    {"code":"202003","desc":"审核通过"}
]

第一步: 使用IDEA自带的客户端连接MySQL,创建内容管理数据库xc_content,执行xc_content.sql脚本向创建的内容管理数据库导入数据

在这里插入图片描述

第二步: 使用MyBatis-Plus提供的generator工程MyBatisX插件生成数据库表对应的PO类、Mapper接口、Mapper的xml文件

  • xuecheng-plus-generator工程导入当前项目工程,点击pom.xml文件右键Add as Maven Project可以自动识别maven工程

在这里插入图片描述

第三步: 修改generator工程中ContentCodeGenerator类的信息,包括数据库地址、数据库账号、数据库密码、生成的表、生成路径

在这里插入图片描述

//数据库账号
private static final String DATA_SOURCE_USER_NAME  = "root";
//数据库密码
private static final String DATA_SOURCE_PASSWORD  = "123456";
//生成的表
private static final String[] TABLE_NAMES = new String[]{
    "course_base",
    "course_market",
    "course_teacher",
    "course_category",
    "teachplan",
    "teachplan_media",
    "course_publish",
    "course_publish_pre"
};
// TODO 默认生成entity,需要生成DTO修改此变量
// 一般情况下要先生成 DTO类 然后修改此参数再生成 PO 类。
private static final Boolean IS_DTO = false;
public static void main(String[] args) {
    ....
        //生成路径
        gc.setOutputDir(System.getProperty("user.dir") + "/xuecheng-plus-generator/src/main/java");

    ....
        // 数据库配置
        DataSourceConfig dsc = new DataSourceConfig();
    dsc.setDbType(DbType.MYSQL);
    dsc.setUrl("jdbc:mysql://192.168.101.65:3306/xcplus_" + SERVICE_NAME+"166"
               + "?serverTimezone=UTC&useUnicode=true&useSSL=false&characterEncoding=utf8");
    ...
}

第四步: 修改完成后执行ContentCodeGenerator类的main方法,自动生成content包并包含内容管理模块的controller、mapper、po及service相关代码

在这里插入图片描述

第五步: 在生成的PO类中含有MyBatisPlus框架的注解,所以需要在当前模块的model工程中添加MyBatisPlus框架的依赖消除错误

@Data
@TableName("course_base")
public class CourseBase implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    /**
     * 机构ID
     */
    private Long companyId;

    /**
     * 机构名称
     */
    private String companyName;

    /**
     * 课程名称
     */
    private String name;

    /**
     * 适用人群
     */
    private String users;

    /**
     * 课程标签
     */
    private String tags;

    /**
     * 大分类
     */
    private String mt;

    /**
     * 小分类
     */
    private String st;

    /**
     * 课程等级
     */
    private String grade;

    /**
     * 教育模式(common普通,record 录播,live直播等)
     */
    private String teachmode;

    /**
     * 课程介绍
     */
    private String description;

    /**
     * 课程图片
     */
    private String pic;

    /**
     * 创建时间
     */
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createDate;

    /**
     * 修改时间
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime changeDate;

    /**
     * 创建人
     */
    private String createPeople;

    /**
     * 更新人
     */
    private String changePeople;

    /**
     * 审核状态
     */
    private String auditStatus;

    /**
     * 课程发布状态 未发布  已发布 下线
     */
    private String status;
}
<dependencies>
        <dependency>
            <groupId>com.xuecheng</groupId>
            <artifactId>xuecheng-plus-base</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <!--PO类存在mybatisplus注解,添加相关注解保证不报错-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-annotation</artifactId>
            <version>${mybatis-plus-boot-starter.version}</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-core</artifactId>
            <version>${mybatis-plus-boot-starter.version}</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
</dependencies>

请求响应模型类

查询条件包括: 课程名称(name)、课程审核状态(auditStatus)、课程发布状态(status),对于分页查询还要包括当前页码、每页显示记录数

  • 课程名称:可以模糊搜索
  • 课程审核状态:未提交、已提交、审核通过、审核未通过
  • 课程发布状态:未发布、已发布、已下线

第一步定义请求模型类: 对于查询条件较多的接口可以定义单独的模型类接收参数

  • 由于分页查询的接口在项目中很多地方都会用到,所以分页查询的参数(当前页码、每页显示的记录数)可以单独在xuecheng-plus-base工程中定义
  • 对于课程查询的特有参数(审核状态,课程名称,发布状态)可以在xuecheng-plus-content-model工程中定义
package com.xuecheng.base.model;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class PageParams {
    // 默认起始页码
    public static final long DEFAULT_PAGE_CURRENT = 1L;
    // 默认每页记录数
    public static final long DEFAULT_PAGE_SIZE = 10L;

    // 当前页码
    @ApiModelProperty("当前页码")
    private Long pageNo = DEFAULT_PAGE_CURRENT;

    // 当前每页记录数
    @ApiModelProperty("每页记录数")
    private Long pageSize = DEFAULT_PAGE_SIZE;
}
package com.xuecheng.content.model.dto;

@Data
@AllArgsConstructor
public class QueryCourseParamsDto {
    // 审核状态,审核状态为数据字典中的代码字段,前端会根据审核状态代码 找到对应的名称显示
    @ApiModelProperty("审核状态")
    private String auditStatus;
    // 课程名称
    @ApiModelProperty("课程名称")
    private String courseName;
    // 发布状态
    @ApiModelProperty("发布状态")
    private String publishStatus;
}

由于请求模型类中用到了lombok注解所以在base工程添加依赖包

<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
</dependencies>

查询结果包括: 课程id、课程名称、任务数(关联教学计划表查询)、创建时间、审核状态、类型,对于分页查询还要包括总记录数、当前页码、每页显示记录数

在这里插入图片描述

第二步定义响应模型类: 由于分页查询的结果数据和格式比较固定(json格式),所以单独在xuecheng-plus-base工程中定义一个基础的结果模型类

  • 响应结果为数据列表(课程id、课程名称、任务数、创建时间、审核状态、类型)和一些分页信息(总记录数、当前页、每页显示记录数)
package com.xuecheng.base.model;

@Data
@AllArgsConstructor
public class PageResult<T> implements Serializable {
    // 数据列表,课程查询接口的返回类型可以是CourseBase类型
    private List<T> items;
    // 总记录数
    private long counts;
    // 当前页码
    private long page;
    // 每页记录数
    private long pageSize;
}   

接口定义(api工程)

第一步: 使用HttpClient模拟请求: 对于查询类接口通常为GET(查询条件较少)或POST(查询条件较多),对于POST还要确定content-type即参数以什么数据格式提交

POST /content/course/list?pageNo=2&pageSize=1
Content-Type: application/json

{
  "auditStatus": "202002",
  "courseName": ""
}
// 成功响应结果
{
  "items": [
    {
      "id": 26,
      "companyId": 1232141425,
      "companyName": null,
      "name": "spring cloud实战",
      "users": "所有人",
      "tags": null,
      "mt": "1-3",
      "mtName": null,
      "st": "1-3-2",
      "stName": null,
      "grade": "200003",
      "teachmode": "201001",
      "description": "本课程主要从四个章节进行讲解: 1.微服务架构入门 2.spring cloud 基础入门 3.实战Spring Boot 4.注册中心eureka。",
      "pic": "https://cdn.educba.com/academy/wp-content/uploads/2018/08/Spring-BOOT-Interview-questions.jpg",
      "createDate": "2019-09-04 09:56:19",
      "changeDate": "2021-12-26 22:10:38",
      "createPeople": null,
      "changePeople": null,
      "auditStatus": "202002",
      "auditMind": null,
      "auditNums": 0,
      "auditDate": null,
      "auditPeople": null,
      "status": 1,
      "coursePubId": null,
      "coursePubDate": null
    }
  ],
  "counts": 23,
  "page": 2,
  "pageSize": 1
}

第二步: 在当前模块的api接口工程的resources目录下添加日志的配置文件log4j2-dev.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration monitorInterval="180" packages="">
    <properties>
        <property name="logdir">logs</property>
        <property name="PATTERN">%date{YYYY-MM-dd HH:mm:ss,SSS} %level [%thread][%file:%line] - %msg%n%throwable</property>
    </properties>
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="${PATTERN}"/>
        </Console>

        <RollingFile name="ErrorAppender" fileName="${logdir}/error.log"
            filePattern="${logdir}/$${date:yyyy-MM-dd}/error.%d{yyyy-MM-dd-HH}.log" append="true">
            <PatternLayout pattern="${PATTERN}"/>
            <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true" />
            </Policies>
        </RollingFile>

        <RollingFile name="DebugAppender" fileName="${logdir}/info.log"
            filePattern="${logdir}/$${date:yyyy-MM-dd}/info.%d{yyyy-MM-dd-HH}.log" append="true">
            <PatternLayout pattern="${PATTERN}"/>
            <ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true" />
            </Policies>
        </RollingFile>
        
        <!--异步appender-->
        <Async name="AsyncAppender" includeLocation="true">
            <AppenderRef ref="ErrorAppender"/>
            <AppenderRef ref="DebugAppender"/>
        </Async>
    </Appenders>
    
    <Loggers>
        <!--过滤掉spring和mybatis的一些无用的debug信息-->
        <logger name="org.springframework" level="INFO">
        </logger>
        <logger name="org.mybatis" level="INFO">
        </logger>
        <logger name="cn.itcast.wanxinp2p.consumer.mapper" level="DEBUG">
        </logger>

        <logger name="springfox" level="INFO">
        </logger>
        <logger name="org.apache.http" level="INFO">
        </logger>
        <logger name="com.netflix.discovery" level="INFO">
        </logger>
        
        <logger name="RocketmqCommon"  level="INFO" >
        </logger>
        
        <logger name="RocketmqRemoting" level="INFO"  >
        </logger>
        
        <logger name="RocketmqClient" level="WARN">
        </logger>

        <logger name="org.dromara.hmily" level="WARN">
        </logger>

        <logger name="org.dromara.hmily.lottery" level="WARN">
        </logger>

        <logger name="org.dromara.hmily.bonuspoint" level="WARN">
        </logger>
        <!--OFF   0-->
        <!--FATAL   100-->
        <!--ERROR   200-->
        <!--WARN   300-->
        <!--INFO   400-->
        <!--DEBUG   500-->
        <!--TRACE   600-->
        <!--ALL   Integer.MAX_VALUE-->
        <Root level="DEBUG" includeLocation="true">
            <AppenderRef ref="AsyncAppender"/>
            <AppenderRef ref="Console"/>
            <AppenderRef ref="DebugAppender"/>
        </Root>
    </Loggers>
</Configuration>

第三步: 在当前模块api接口工程的resources目录下中添加属性配置文件bootstrap.yml

server:
  servlet:
    context-path: /content
  # 设置内容管理服务的端口为63040 
  port: 63040
## 微服务配置
spring: 
  application:
    name: content-api
## 日志文件配置路径
logging:
  config: classpath:log4j2-dev.xml
## swagger文档的配置信息
swagger:
  title: "学成在线内容管理系统"
  description: "内容系统管理系统对课程相关信息进行业务管理数据"
  base-package: com.xuecheng.content
  enabled: true
  version: 1.0.0

第四步: 在当前模块api接口工程的pom.xml文件中添加定义请求接口时所需要的依赖

<dependencies>
    <!--cloud的基础环境包-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-context</artifactId>
    </dependency>
    <!-- SpringBoot的SpringWebMVC集成 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- 排除SpringBoot依赖的日志包冲突 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
    <!-- SpringBoot集成log4j2 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-log4j2</artifactId>
    </dependency>
    <!--SprinBoot集成swagger-->
    <dependency>
        <groupId>com.spring4all</groupId>
        <artifactId>swagger-spring-boot-starter</artifactId>
        <version>1.9.0.RELEASE</version>
    </dependency>
</dependencies>

第五步: 在当前模块的api接口工程中定义Controller方法接收请求

  • pageParams分页参数在URL中以键值对格式,queryCourseParams课程查询参数在请求体中以json格式传入,使用@RequestBody注解将json转成Java对象
  • 由于课程查询的特有参数不是必填项(如果没有表示查询所有课程),所以需要在@RequestBody注解后添加(required=false)属性
package com.xuecheng.content.api;
@RestController
@Api(value = "课程信息编辑接口", tags = "课程信息编辑接口")
public class CourseBaseInfoController {  
    @ApiOperation("课程查询接口")
    @PostMapping("/course/list")
    public PageResult<CourseBase> list(PageParams pageParams, @RequestBody(required=false) QueryCourseParamsDto queryCourseParams){
        // 定义测试数据
        /*CourseBase courseBase = new CourseBase();
        courseBase.setId(15L);
        courseBase.setDescription("测试课程");
        PageResult<CourseBase> result = new PageResult<>();
        result.setItems(Arrays.asList(courseBase));
        result.setPage(1);
        result.setPageSize(10);
        result.setCounts(1);
        return result;*/
        // 调用业务层提供的方法查询课程信息
        PageResult<CourseBase> pageResult = courseBaseInfoService.queryCourseBaseList(pageParams, queryCourseParams);
        return pageResult;
    }
}

第六步: 在当前模块的api接口工程中定义启动类,同时使用@EnableSwagger2Doc注解启用Swagger

package com.xuecheng;
@EnableSwagger2Doc
@SpringBootApplication(scanBasePackages = "com.xuecheng") 
public class ContentApiApplication {
    public static void main(String[] args) {
        SpringApplication.run(ContentApiApplication.class, args);
    }
}

第七步: 运行api工程的启动类ContentApiApplication,即对外暴露API接口,使用浏览器访问http://localhost:63040/content/swagger-ui.html查看接口信息

在这里插入图片描述

第八步: 在base工程的com.xuecheng.base.config包下配置LocalDateTimeConfig类指定json字符串与LocalDateTime类型相互转换时的格式

在这里插入图片描述

@Configuration
public class LocalDateTimeConfig {
    /*
     * 序列化内容
     *   LocalDateTime -> String
     * 服务端返回给客户端内容
     * */
    @Bean
    public LocalDateTimeSerializer localDateTimeSerializer() {
        return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }
    /*
     * 反序列化内容
     *   String -> LocalDateTime
     * 客户端传入服务端数据
     * */
    @Bean
    public LocalDateTimeDeserializer localDateTimeDeserializer() {
        return new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }
    // 配置
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
        return builder -> {
            builder.serializerByType(LocalDateTime.class, localDateTimeSerializer());
            builder.deserializerByType(LocalDateTime.class, localDateTimeDeserializer());
        };
    }
}

业务层环境搭建

service工程即业务层负责为api接口工程提供业务处理支撑,本项目的业务层包括了持久层的代码,也可以将持久层和业务层分为两个工程但需要增加成本

第一步: 将generator工程MyBatisX插件自动生成数据库表的Mapper接口和XML映射文件并拷贝到service工程的com.xuecheng.content.mapper包下(注意修改包路径)

在这里插入图片描述

第二步: 在service工程的pom.xml中添加MP和数据库以及日志相关的依赖

<dependencies>
    <dependency>
        <groupId>com.xuecheng</groupId>
        <artifactId>xuecheng-plus-content-model</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>
    <!-- MySQL驱动 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <!-- mybatis plus的依赖 -->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-context</artifactId>
  </dependency>
    <!--SpringBoot集成Junit-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <!--排除SpringBoot依赖的日志包冲突 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <!-- SpringBoot集成log4j2 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-log4j2</artifactId>
    </dependency>
</dependencies>

第三步: 在service工程com.xuecheng.content.config包下创建MybatisPlusConfig配置类,配置扫描Mapper接口注解分页拦截器

  • 分页插件的原理: 首先分页参数放到ThreadLocal中,然后拦截执行的sql根据数据库类型添加对应的分页语句重写sql
/**
 * Mybatis-Plus配置
 */
@Configuration
@MapperScan("com.xuecheng.content.mapper")
    public class MybatisPlusConfig {
    /**
     * 定义分页拦截器
     * @return
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
} 

第四步: 在service工程的test/resources目录下创建所需要的配置文件log4j2-dev.xml(日志文件)bootstrap.yml(配置数据库连接信息)

在这里插入图片描述

spring:
  #application:
    #name: content-service
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/xc_content?serverTimezone=UTC&userUnicode=true&useSSL=false
    username: root
    password: 123456
# 日志文件配置路径    
logging:
  config: classpath:log4j2-dev.xml 

第五步: 在service工程的test目录下添加启动类

在这里插入图片描述

package com.xuecheng.content;
@Slf4j
@SpringBootApplication
public class ContentApplication {
    public static void main(String[] args) {
        SpringApplication.run(ContentApplication.class, args);
    }
}

第六步: 在service工程的test目录下对应Java目录所在的包结构com.xuecheng.content,然后编写测试类测试Mapper的功能

在这里插入图片描述

@Slf4j
@SpringBootTest
class CourseBaseMapperTests{
    @Autowired
    CourseBaseMapper courseBaseMapper;
    @Test
    public void testCourseBaseMapper() {
        CourseBase courseBase = courseBaseMapper.selectById(22);
        log.info("查询到数据:{}", courseBase);
        Assertions.assertNotNull(courseBase);
    }
}

业务层开发(service工程)

第一步: 使用IDEA自带的客户端连接MySQL,创建系统管理数据库xc_system,执行xcplus_system.sql脚本向创建的系统管理数据库导入数据

第二步: 编写Service接口及其实现类

package com.xuecheng.content.service;
// 课程基本信息管理业务接口 
public interface CourseBaseInfoService  {
 /**
  * @description 课程查询接口
  * @param pageParams 分页参数
  * @param queryCourseParamsDto 条件条件
  * @return com.xuecheng.base.model.PageResult<com.xuecheng.content.model.po.CourseBase>
  * @author Mr.M
  * @date 2022/9/6 21:44
 */
  PageResult<CourseBase> queryCourseBaseList(PageParams pageParams, QueryCourseParamsDto queryCourseParamsDto);

 }
package com.xuecheng.content.service.impl;
/**
 * @description 课程信息管理业务接口实现类
 * @author Mr.M
 * @date 2022/9/6 21:45
 * @version 1.0
 */
@Service
public class CourseBaseInfoServiceImpl  implements CourseBaseInfoService {
 @Autowired
 CourseBaseMapper courseBaseMapper;

 @Override
 public PageResult<CourseBase> queryCourseBaseList(PageParams pageParams, QueryCourseParamsDto queryCourseParamsDto) {
  //构建查询条件对象
  LambdaQueryWrapper<CourseBase> queryWrapper = new LambdaQueryWrapper<>();
  //构建查询条件,根据课程名称查询
  queryWrapper.like(StringUtils.isNotEmpty(queryCourseParamsDto.getCourseName()),CourseBase::getName,
                                    queryCourseParamsDto.getCourseName());
  //构建查询条件,根据课程审核状态查询 			    
  queryWrapper.eq(StringUtils.isNotEmpty(queryCourseParamsDto.getAuditStatus()),CourseBase::getAuditStatus,
                                    queryCourseParamsDto.getAuditStatus());       
  //构建查询条件,根据课程发布状态查询
  queryWrapper.eq(StringUtils.isNotEmpty(queryCourseParams.getPublishStatus()), CourseBase::getStatus,    	
                  					queryCourseParams.getPublishStatus());
  //分页对象
  Page<CourseBase> page = new Page<>(pageParams.getPageNo(), pageParams.getPageSize());
  //查询数据内容获得结果
  Page<CourseBase> pageResult = courseBaseMapper.selectPage(page, queryWrapper);
  //获取数据列表
  List<CourseBase> list = pageResult.getRecords();
  //获取数据总数
  long total = pageResult.getTotal();
  //构建结果集封装到QueryCourseParamDto对象中
  PageResult<CourseBase> courseBasePageResult = new PageResult<>(list, total, pageParams.getPageNo(), pageParams.getPageSize());
  return courseBasePageResult;
 }
}

test目录下编写测试类CourseBaseInfoServiceTests测试courseBaseInfoService

@SpringBootTest
public class CourseBaseInfoServiceTests {
    @Autowired
    CourseBaseInfoService courseBaseInfoService;
    @Test
    void testCourseBaseInfoService() {
        //查询条件
        QueryCourseParamsDto queryCourseParamsDto = new QueryCourseParamsDto();
        queryCourseParamsDto.setCourseName("java");
        queryCourseParamsDto.setAuditStatus("202004");
        queryCourseParamsDto.setPublishStatus("203001");

        //分页参数
        PageParams pageParams = new PageParams();
        pageParams.setPageNo(1L);//页码
        pageParams.setPageSize(3L);//每页记录数
		/
        PageResult<CourseBase> courseBasePageResult = courseBaseInfoService.queryCourseBaseList(pageParams, queryCourseParamsDto);
        System.out.println(courseBasePageResult);
    }
}

Swagger测试

第一步: 访问http://localhost:63040/content/swagger-ui.html, 打开Swagger文档输入查询条件进行测试

在这里插入图片描述

第二步: 查看请求响应的结果

在这里插入图片描述


Httpclient测试

使用Swagger时每次测试都需要进入浏览器并且它并不能保存测试数据,所以IDEA提供了一个非常方便的http接口测试工具httpclient

在这里插入图片描述

第一步: 进入Controller类并找到http接口对应的方法

在这里插入图片描述

第二步: 点击Generate request in HTTP Client即可生成一个以.http结尾的文件.它可以随着项目工程一起保存

在这里插入图片描述

第三步: 添加请求参数进行测试,注意请求和参数之间需要保留一个空白行

在这里插入图片描述

第四步: 观察控制台查看响应结果

http://localhost:63040/course/list?pageNo=2&pageSize=10

HTTP/1.1 200 
Content-Type: application/json
Transfer-Encoding: chunked
Date: Wed, 07 Sep 2022 00:54:50 GMT
Keep-Alive: timeout=60
Connection: keep-alive

{
  "items": [
    {
      "id": 88,
      "companyId": 1232141425,
      "companyName": null,
      "name": "1",
      "users": "1",
      "tags": "1",
      "mt": "1-1",
      "mtName": null,
      "st": "1-1-1",
      "stName": null,
      "grade": "204001",
      "teachmode": "200002",
      "description": "1",
      "pic": "http://r3zc5rung.hd-bkt.clouddn.com/cb1b6038-ef68-4362-8c29-a966886d1dc5sakUiFHLb5sRFdIK",
      "createDate": "2021-12-27 20:14:53",
      "changeDate": "2021-12-27 20:28:58",
      "createPeople": null,
      "changePeople": null,
      "auditStatus": "202002",
      "auditMind": null,
      "auditNums": 0,
      "auditDate": null,
      "auditPeople": null,
      "status": 1,
      "coursePubId": null,
      "coursePubDate": null
    },
   ....
  ],
  "counts": 14,
  "page": 2,
  "pageSize": 10
}

第五步: 为了方便保存.http文件,我们单独在项目工程的根目录下创建一个api-test目录并以模块为单位创建.http文件

在这里插入图片描述

第六步: 为了方便将来和网关集成测试,我们可以创建配置文件http-client.env.json并配置测试主机地址,文件名和位置固定,否则找不到对应的变量

在这里插入图片描述

{
  "dev": {
    "access_token": "",
    "gateway_host": "localhost:63010",
    "content_host": "localhost:63040",
    "system_host": "localhost:63110",
    "media_host": "localhost:63050",
    "search_host": "localhost:63080",
    "auth_host": "localhost:63070",
    "checkcode_host": "localhost:63075",
    "learning_host": "localhost:63020"
  }
}

第七步: 在xc-content-api.http文件中将http://localhost:63040用配置的content_host变量代替

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MAT工具定位分析Java堆内存泄漏问题方法

原创/朱季谦 一、MAT概述与安装 MAT&#xff0c;全称Memory Analysis Tools&#xff0c;是一款分析Java堆内存的工具&#xff0c;可以快速定位到堆内泄漏问题。该工具提供了两种使用方式&#xff0c;一种是插件版&#xff0c;可以安装到Eclipse使用&#xff0c;另一种是独立版…

论文浅尝 | 用于开放式文本生成的事实增强语言模型

笔记整理&#xff1a;李煜&#xff0c;东南大学硕士&#xff0c;研究方向为知识图谱 链接&#xff1a;https://proceedings.neurips.cc/paper_files/paper/2022/hash/df438caa36714f69277daa92d608dd63-Abstract-Conference.html 1. 动机 生成式语言模型&#xff08;例如 GPT-3…

【图论】最小生成树(python和cpp)

文章目录 一、声明二、简介三、代码C代码Python代码 一、声明 本帖持续更新中如有纰漏望指正&#xff01; 二、简介 &#xff08;a&#xff09;点云建立的k近邻图&#xff08;b&#xff09;k近邻图上建立的最小生成树 最小生成树 (Minimum Spanning Tree&#xff0c;简称 M…

使用Tauri开发桌面应用

本文是对视频 Tauri入门教程[1]的学习与记录 Tauri官网[2] 对 node版本有要求 创建项目及目录介绍: 项目的目录结构如下 可以安装推荐的插件 执行npm run tauri build出错,根据 https://github.com/tauri-apps/tauri/issues/7430 执行 yarn add -D tauri-apps/cli && y…

缺陷预测(一)——论文复现

运行CGCN文件 问题一&#xff1a;CNN输入维度的问题出现的问题解决问题原因 问题二&#xff1a;mix时&#xff0c;输入的train_in和train_gen.inputs数据格式不一致出现的问题解决问题 最终结果 问题一&#xff1a;CNN输入维度的问题 出现的问题 数据集改好之后&#xff0c;出…

Python Flask: 构建轻量级、灵活的Web应用

大家好&#xff0c;我是涛哥&#xff0c;今天为大家分享 Python Web开发框架 Flask&#xff0c;文章3400字&#xff0c;阅读大约15分钟&#xff0c;大家enjoy~~ Flask是一个流行的Python Web框架&#xff0c;以其轻量级、灵活和易学的特性受到开发者的喜爱。本文将深入探讨Flas…

微服务简单理解与快速搭建

分布式和微服务 含义 微服务架构 微服务架构风格是一种将一个单一应用程序开发为一组小型服务的方法&#xff0c;每个服务运行在自己的进程中&#xff0c;服务间通信采用轻量级通信机制(通常用HTTP资源API)。这些服务围绕业务能力构建并且可通过全自动部署机制独立部署。这些服…

C语言进阶之指针(2)

✨ 猪巴戒&#xff1a;个人主页✨ 所属专栏&#xff1a;《C语言进阶》 &#x1f388;跟着猪巴戒&#xff0c;一起学习C语言&#x1f388; 目录 前情回顾 1.数组参数&#xff0c;指针参数 1.1一维数组传参 1.2二维数组传参 1.3一级指针传参 1.4二级指针传参 思考&#xf…

算法萌新闯力扣:同构字符串

力扣题&#xff1a;同构字符串 开篇 对于字符串相关的题目&#xff0c;哈希表经常会使用到&#xff0c;这道题更是如此&#xff0c;还用到了两个哈希表。拿下它&#xff0c;你对字符串题目的理解就会更上一层楼。 题目链接:205.同构字符串 题目描述 代码思路 看完题目后&a…

Django实战项目-学习任务系统-任务完成率统计

接着上期代码内容&#xff0c;继续完善优化系统功能。 本次增加任务完成率统计功能&#xff0c;为更好的了解哪些任务完成率高&#xff0c;哪些任务完成率低。 该功能完成后&#xff0c;学习任务系统1.0版本就基本完成了。 1&#xff0c;编辑urls配置文件&#xff1a; ./mysi…

原论文一比一复现 | 更换 RT-DETR 主干网络为 【ResNet-50】【ResNet-101】【ResNet-152】| 对比实验必备

本专栏内容均为博主独家全网首发,未经授权,任何形式的复制、转载、洗稿或传播行为均属违法侵权行为,一经发现将采取法律手段维护合法权益。我们对所有未经授权传播行为保留追究责任的权利。请尊重原创,支持创作者的努力,共同维护网络知识产权。 更深层的神经网络更难训练。…

香港科技大学广州|机器人与自主系统学域博士招生宣讲会—电子科技大学专场!!!(暨全额奖学金政策)

在机器人和自主系统领域实现全球卓越—机器人与自主系统学域 硬核科研实验室&#xff0c;浓厚创新产学研氛围&#xff01; 教授亲临现场&#xff0c;面对面答疑解惑助攻申请&#xff01; 一经录取&#xff0c;享全额奖学金1.5万/月&#xff01; &#x1f559;时间&#xff1a;…

基于谐波参数空间的卷积神经网络自动三维牙齿分割

论文连接&#xff1a;https://www.sciencedirect.com/science/article/abs/pii/S1524070320300151 机构&#xff1a; a英国卡迪夫大学计算机科学与信息学院 b中国科学院大学北京 c中国科学院计算技术研究所北京 d深圳大数据研究院&#xff0c;深圳518172 代码链接&#x…

4路光栅尺磁栅尺编码器解码转换5MHz高速差分信号转Modbus TCP网络模块 YL97-RJ45

特点&#xff1a; ● 光栅尺磁栅尺解码转换成标准Modbus TCP协议 ● 光栅尺5V差分信号直接输入&#xff0c;4倍频计数 ● 模块可以输出5V的电源给光栅尺供电 ● 高速光栅尺磁栅尺计数&#xff0c;频率可达5MHz ● 支持4个光栅尺同时计数&#xff0c;可识别正反转 ● 可网…

Looking for downloadable pre-built shared indexes关闭

这个功能很烦,把他关闭就行了 PyCharm的“Looking for downloadable pre-built shared indexes”是指PyCharm IDE中的一个功能&#xff0c;用于搜索和下载可共享的预构建索引。 这个功能的主要用途是帮助开发人员在开发过程中快速地获取和使用预构建的索引&#xff0c;以提高…

算法笔记-第七章-链表(未完成)

算法笔记-第七章-链表 链表的遍历链表结点的个数链表的头插法!链表删除元素链表反转例题思路一:原地反转思路二:头插法链表去除重复元素(有些复杂了)思路题目一题目二链表的遍历 #include<cstdio> const int N = 100; struct Node {int data, next;//表示的是当前数据和…

基于K7的PXIPXIe数据处理板(Kintex-7 FMC载板)

基于PXI&PXIe总线架构的高性能数据预处理FMC 载板&#xff0c;板卡具有 1 个 FMC&#xff08;HPC&#xff09;接口&#xff0c;1 个 X8 PCIe 和1个PCI主机接口&#xff1b;板卡采用 Xilinx 的高性能 Kintex-7 系列 FPGA 作为实时处理器&#xff0c;实现 FMC 接口数据的采集…

网络安全-学习手册

前言 前几天发布了一篇 网络安全&#xff08;黑客&#xff09;自学 没想到收到了许多人的私信想要学习网安黑客技术&#xff01;却不知道从哪里开始学起&#xff01;怎么学 今天给大家分享一下&#xff0c;很多人上来就说想学习黑客&#xff0c;但是连方向都没搞清楚就开始学习…

【postgresql】CentOS7 安装Pgweb

Pgweb Pgweb是PostgreSQL的一个基于web的数据库浏览器&#xff0c;用Go编写&#xff0c;可在Mac、Linux和Windows机器上运行。以零依赖性的简单二进制形式分布。非常易于使用&#xff0c;并具有适当数量的功能。简单的基于web和跨平台的PostgreSQL数据库浏览器。 特点 跨平台…

ubuntu22.04 x86环境上使用QEMU搭建arm虚拟机

1、安装qemu及相关依赖 apt-get -y install qemu apt-get -y install bridge-utils apt-get -y install vnc4server apt-get -y install qemu-kvm apt install -y qemu-system-arm apt-get -y install libvirt0 apt-get -y install libvirt-daemon apt-get -y install l…