在线教育项目 Day02

在线教育项目 Day02

概念介绍:前后端分离

前端:html、css、js、jq。主要作用:数据显示

​ ajax操作:调用后端数据(调用接口)

后端:controller、service、mapper。主要作用:返回数据或操作数据

​ 开发接口:开发controller、service、mapper的过程(不是interface)

搭建项目环境

创建数据库

创建讲师数据库表(此处直接导入课程提供资料)

创建项目结构

​ 创建父工程(springboot工程)(Maven阶段学习)

​ pom类型,管理依赖版本和存放公共依赖

子模块(Maven工程)

​ 子子模块(Maven工程)

项目结构:父工程 → 子模块 → 子子模块

  1. 创建父工程(springboot工程:文件→新建→项目→spring initializ)

    配置pom.xml:

        <artifactId>guli_parent</artifactId>
        <packaging>pom</packaging>
        //表示当前类型是一个pom类型
    

    在pom.xml中添加依赖版本

  2. 创建service子模块(Maven工程:文件→新建→项目→Maven)

    注:在导入依赖时,首先需要修改版本为pom,其次需要将最开始的几个依赖注释掉,否则会报错。(xml文件的注释方法见本文最后)

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kHn7XFum-1618664317176)(…/…/AppData/Roaming/Typora/typora-user-images/image-20210404200216888.png)]

    image-20210404200256796

讲师管理接口开发

讲师管理模块配置与生成代码

一、讲师管理模块配置

  1. 在service下面service-edu模块中创建配置文件:

    resources目录下创建文件 application.properties:

    (或者可以创建yml格式文件,但未学不会)

image-20210405145314251

# 服务端口(port) 
# 因为现在创建的项目都是web工程(浏览器访问,需要用到端口)
# 若不写,则默认为Tomcat的端口号8080
server.port=8001

# 服务名
spring.application.name=service-edu

# 环境设置:dev、test、prod(开发、测试、生产环境)
spring.profiles.active=dev


# mysql数据库连接
# 新版本,需要加上时区
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/guli?serverTimezone=GMT%2B8 
spring.datasource.username=root
spring.datasource.password=mysql883721@

#mybatis日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
  1. 创建MP代码生成器

    由MybatisPlus提供,可以生成controller service mapper。不用自己创建。

    不要求会写代码,要求会改

    需要修改的部分

    • 修改代码生成的地址,改为本项目的绝对地址
    • 根据项目设置的主键的类型(long、char),修改主键策略
            //gc.setOutputDir(projectPath + "/src/main/java");//生成代码的输出目录
            gc.setOutputDir("D:\\guli_parent\\service\\service_edu" + "/src/main/java");
            //注意上下两行的区别
            //被注释的部分使用的是相对路径,可能出错
            //其下行使用绝对路径
    
            gc.setIdType(IdType.ID_WORKER); //主键策略:ID_WORKER、ID_WORKER_STR
    
    • 修改数据库配置
            dsc.setUrl("jdbc:mysql://localhost:3306/数据库名称?serverTimezone=GMT%2B8 ");
    		//修改数据库名称添加时区
            dsc.setDriverName("com.mysql.cj.jdbc.Driver");//添加“cj”
    
            dsc.setPassword("***********");//修改为自己的数据库的密码
    
    • 包配置
           // 4、包配置
           PackageConfig pc = new PackageConfig();
           
   		//改为实际上自己的包:
           //执行后,会生成一个包,包名为com.atguigu.eduservice
           pc.setParent("com.atguigu");
           pc.setModuleName("eduservice"); //模块名
           
           //包名为com.atguigu.eduservice.controller
           pc.setController("controller");
   
           //包名为com.atguigu.eduservice.entity
           pc.setEntity("entity");
   
           //包名为com.atguigu.eduservice.service,等等。顺序无所谓,都是按照此结构生成
           pc.setService("service");
           pc.setMapper("mapper");
           mpg.setPackageInfo(pc);
  • 策略配置
        strategy.setInclude("edu_teacher");//自己的表的名称,如果有多张表,用逗号隔开

        strategy.setTablePrefix(pc.getModuleName() + "_"); //生成实体时去掉表前缀
        //将表中字段get_Course在实体类中变为getCourse
	    //此处不需要修改

执行结束:

service和mapper部分编写结束;但controller 部分中只有一个类,需要自己编写。

image-20210405154236230

可能的失败的原因:路径错误、缺少依赖

二、编写后台管理api接口

  1. 编写controller代码

    @RestController注解的内部信息

    image-20210405160820771

    创建controller:

    完成了controller调用service,service调用mapper

    @RestController
    @RequestMapping("/eduservice/edu-teacher")
    //该注解表示最后访问的数据
    public class EduTeacherController {
        //controller需要调用service方法,所以需要注入service方法
        //把service注入
        @Autowired
        private EduTeacherService teacherService;
        
        //1 查询讲师表所有数据
        @GetMapping("findAll")
        public List<EduTeacher> findAllTeacher() {
            //此处的list<EduTeacher>为返回值类型
            List<EduTeacher> list = teacherService.list(null);
            return list;
        }
    }
    
  2. 创建启动类

    image-20210405163651769

    package com.atguigu.eduservice;
    
    //这是一个启动类。 //启动类的创建规范不太熟悉
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class EduApplication {
        public static void main(String[] args) {
            SpringApplication.run(EduApplication.class, args);
        }
    }
    
  3. 创建配置类

    @Configuration
    //配置类首先需要添加该注解
    @MapperScan("package com.atguigu.eduservice.mapper;")
    //此处的地址为mapper的Interface地址,EduTeacherMapper的首行中
    public class EduConfig {
        
    }
    
  4. 最终测试

    运行启动类中的main方法

    此处报错,未解决

3、配置SQL执行性能分析插件

4、创建SpringBoot启动类

5、运行启动类

6、统一返回的json时间格式

​ 在application.properties中配置:

#返回json的全局时间格式
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8

三、讲师逻辑删除功能

  1. 配置逻辑删除插件

​ 在EduConfig配置类中添加:

public class EduConfig {
    /**
     * 逻辑删除插件
     */
    @Bean
    public ISqlInjector sqlInjector() {
        return new LogicSqlInjector();
    }
    @ApiModelProperty(value = "逻辑删除 1(true)已删除, 0(false)未删除")
    @TableLogic
    private Boolean isDeleted;

**注意:**使用逻辑删除时,必须添加注解@TableLogic

  1. 在controller中编写最终的删除方法

    通过路径删除

    此后删除惯用此方法

        //2 逻辑删除讲师的方法
        //删除一般使用delete提交方法
        @DeleteMapping("{id}")
        //此处根据id删除。此处的id需要通过路径进行传递
        //localhost:8001/edu/delete/1  此处的“1”就是通过路径传递的id值
        
        public boolean removeTeacher(@PathVariable String id){
            //上一行的作用,获取到路径中输入的id值
            boolean flag = teacherService.removeById(id);
            return flag;
        }
    

3、测试删除

​ 浏览器不可以进行delete测试(可以做get提交)

​ 需要借助工具进行测试:

  • swagger测试(重点)
  • postman(了解)

整合Swagger进行接口测试

好处:

  • 能生成在线接口文档(API)

  • 方便进行接口的测试

做法:创建公共模块,整合swagger,为了使所有的模块都能使用

配置Swagger2

1、创建common模块

在guli-parent下创建子模块common

2、在common中引入相关依赖

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

同时注意修改:

    <artifactId>common</artifactId>
    <packaging>pom</packaging>

项目的打包类型:pom、jar、war

packing默认是jar类型,

pom --> 父类型都为pom类型;

jar --> 内部调用或者是作服务使用;

war --> 需要部署的项目。

maven的三种工程pom、jar、war的区别

3、在common下面创建子模块 service-base

​ 在模块service-base中,创建swagger的配置类

​ 在service_base -src -mian -java目录下新建一个包com.atguigu.servicebase.config,

​ 在其中创建一个配置类SwaggerConfig

​ 注:需要手动导入类

@Configuration  //配置类
@EnableSwagger2  //swagger注解
public class SwaggerConfig {
        

    @Bean
    public Docket webApiConfig(){

        //实质上为配置swagger插件
        //一般不需要修改,可能需要改组名、方法名或提示信息
        return new Docket(DocumentationType.SWAGGER_2) //类型:swagger
                .groupName("webApi")
                .apiInfo(webApiInfo()) //下方的方法,可以设置其中的值
                .select()
                .paths(Predicates.not(PathSelectors.regex("/admin/.*")))
                .paths(Predicates.not(PathSelectors.regex("/error.*")))
           	//路径中如果包含admin、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();
    }
}

具体使用:

​ 1. 在模块service模块中引入service-base:

​ 此时的service-base在common中,需要导入到service中,才能被service_edu使用

​ 地址:service -pom.xml

<dependency>
    <groupId>com.atguigu</groupId>
    <artifactId>service-base</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>
  1. service-edu启动类上添加注解,进行测试

    地址:service -service_edu -src -main -java -com.atguigu.eduservice -EduApplication

    @ComponentScan(basePackages={"com.atguigu"})
    //添加注解,修改启动类中的扫描规则
    //若不改,只能扫描到当前项目中的类(swagger属于另一个配置类)
    //swaggerconfig的包也是以com.atguigu开头,可以在其中扫描
    
  2. 访问swagger

    访问地址:http://localhost:8001/swagger-ui.html

    P25,待补充

6、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;

5、定义接口说明和参数说明

在EduTeacherController上添加以下注解

作用:在测试时提供更好的显示,能显示中文提示

定义在类上:@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);
    }
}

统一返回结果对象

一、统一返回数据格式

不同人设置的返回值不同,0/1,true/false

项目中我们会将响应封装成json返回,一般我们会将所有接口的数据格式统一, 使前端(iOS Android, Web)对数据的操作更一致、轻松。

一般情况下,统一返回数据格式没有固定的格式,只要能描述清楚返回的数据状态以及要返回的具体数据就可以。但是一般会包含状态码、返回消息、数据这几部分内容

json数据的两种格式:对象、数组

定义统一结果:

{
  "success": 布尔, //响应是否成功
  "code": 数字, //响应码(int)
  "message": 字符串, //返回消息
  "data": HashMap //返回数据,放在键值对中
}

map格式:key + value

二、创建统一结果返回类

1、在common模块下创建子模块common-utils

很多模块都会用到这一模块,所以同swagger一起放到common模块中

2、创建接口(interface)定义返回码

创建包com.atguigu.commonutils,创建接口 ResultCode.java

在其中定义响应码的固定值。或者可以写一个常量类。

public interface ResultCode {
    //状态码,两个固定的值
    public static Integer SUCCESS = 20000;//成功

    public static Integer ERROR = 20001;//失败
}

4、创建结果类

创建类 R.java

@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(){}
    //方法私有化,让其他人不可以创建(new),只能使用下方定义的两个static方法

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

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

二、统一返回结果使用

1、在service模块中添加依赖

此处报错未找到依赖

原因:创建common_utils和service_base时使用的名称不对,在依赖中需要修改名称

        <dependency>
            <groupId>com.atguigu</groupId>
            <artifactId>common_utils</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

2、修改Controller中的返回结果

不清楚是哪一个controller

@ApiOperation(value = "所有讲师列表")
@GetMapping
public R list(){
    List<Teacher> list = teacherService.list(null);
    return R.ok().data("items", list);
}

3、Swagger中测试

分页与条件查询

分页

1、MyBatisPlusConfig中配置分页插件

地址:EduConfig

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

2、分页Controller方法

编写讲师分页查询接口的方法

TeacherAdminController(EduTeacherController.java)中添加分页方法

//3. 分页查询讲师的方法
    @GetMapping("pageTeacher/{current}/{limit}")
    //此处为路径传值 pageTeacher/{current}/{limit},传入下方page所需的两个值
    //current表示当前页,limit表示每页显示的记录数
    public R pageListTeacher(@PathVariable long current,@PathVariable long limit){

        //创建page对象

        Page<EduTeacher> pageTeacher = new Page<>(current,limit);
        //调用方法实现分页
        //调用方法时,底层封装,把所有分页数据封装到pageTeacher对象里面
        teacherService.page(pageTeacher,null);

        long total = pageTeacher.getTotal();//总记录数
        List<EduTeacher> records = pageTeacher.getRecords();
        return R.ok();
        //返回的结果参考统一结果返回的效果
        //ok()是在那里定义的函数
        
        //或者使用下面这种方法:
        //Map map = new HashMap();
        //map.put("total",total);
        //map.put("records",records);
        //return.R.ok().data(map);
    }

注:本例中通过路径传值的方法需要掌握; Page<EduTeacher> pageTeacher = new Page<>(current,limit);中需要填写参数

未解决:

  1. Page<EduTeacher> pageTeacher = new Page<>(current,limit);处,括号内引入的参数未出现提示;

  2. long total = pageTeacher.getTotal();//总记录数处,getTotal方法未显示

  3. Swagger测试

二、多条件组合查询(带分页功能)

根据讲师名称name,讲师头衔level、讲师入驻时间gmt_create(时间段)查询

1、创建查询对象

创建com.guli.edu.query包,创建TeacherQuery.java查询对象

2、service

接口

实现

3、controller

TeacherAdminController中修改 pageList方法:

增加参数TeacherQuery teacherQuery,非必选

4.在Swagger中测试

新增与修改

一、自动填充封装

1、在service-base模块中添加

创建包handler,创建自动填充类 MyMetaObjectHandler

2、在实体类添加自动填充注解

二、controller方法定义

  1. 新增

  2. 根据id查询

  3. 根据id修改

统一异常处理

一、创建统一异常处理器
在service-base中创建统一异常处理类GlobalExceptionHandler.java:

三、处理特定异常
1、添加异常处理方法
GlobalExceptionHandler.java中添加

四、自定义异常
1、创建自定义异常类

2、业务中需要的位置抛出GuliException

3、添加异常处理方法
GlobalExceptionHandler.java中添加

统一日志处理

遇到的问题及解决办法

SQL yog中使用SQL语句导入表

对于一个新建的数据库,无法打开query界面输入sql语句,需要先创建一个表。

image-20210404185259371

此时,该数据库下没有表:

image-20210404185342122

右键→创建表

在这里插入图片描述

创建表:

image-20210404185702470

打开表:

image-20210404190241488

image-20210404190314683

image-20210404190423304

image-20210404190456875

刷新界面:

在这里插入图片描述

导入成功:

image-20210404190610702

在 .xml 文件中添加注释

选中待注释的代码,使用快捷键:Ctrl + Shift + "/"

Maven导入依赖后的操作

需要按刷新键进行刷新,即完成联网下载

image-20210404201107483

粘贴文字到Typora时如何消除格式

Ctrl + Shift + V 完成去格式粘贴

对于不理解部分的补充

controller、service、mapper

Java Web中的mapper、service、controller、model究竟分别是什么作用?

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值