第2篇:搭建Spring Boot项目(2)

137 阅读7分钟

本篇基于公司(company)数据表,主要介绍如何集成MyBatis、PostGreSQL,并实现一个查询接口。

1. 项目文件夹结构

├─com
|  ├─jiaoxn
|  |   ├─example
|  |   |    ├─ExampleApplication.java
|  |   |    ├─utils
|  |   |    ├─service
|  |   |    |    ├─ICompanyService.java
|  |   |    |    ├─impl
|  |   |    |    |  └CompanyService.java
|  |   |    ├─entity
|  |   |    |   └Company.java
|  |   |    ├─dao
|  |   |    |  └CompanyDao.java
|  |   |    ├─controller
|  |   |    |     └CompanyController.java
|  |   |    ├─config
|  |   |    |   └SwaggerConfig.java

其中:

  • config:配置文件夹,存放相关依赖的配置文件,比如Swagger 3的配置信息;
  • entity:数据库实体层,也称为model层、pojo层,一般一个数据库一张表对应一个实体类,表字段与类属性一一对应;
    • POJO(Plain Old Java Object),强调它是一个普通的Java对象,而不是一个特殊的对象。
  • dao:数据持久层,也称为mapper层,是用作访问数据库,向数据库发送sql语句,完成数据库的增删改查等操作;
  • service:业务逻辑层,主要作用是完成业务功能逻辑,它调用dao层,并接收该层返回的数据;
  • controller:控制层,主要功能是请求和响应控制,主要负责前后端交互,接收前端的请求,并调用service层、接收service层返回的数据,最后将具体的数据返回给客户端
  • utils:主要作用是存放通用的公共类。

2. 安装相关依赖

通过访问MVNRepository网站查看具体依赖的Maven配置内容。

2.1 MyBatis依赖

<!-- MyBatis 依赖 -->
<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
</dependency>

2.2 PostgreSQL驱动依赖

MyBatis只是一个SQL层面的持久层框架,根据代码生成SQL语句、返回结果。为了完成数据库的请求操作,还需要安装数据库驱动依赖。

本例中使用PostgreSQL数据库,需要安装ProstgSQL驱动依赖。

<!-- Postgres 数据库驱动依赖 -->
<dependency>
  <groupId>org.postgresql</groupId>
  <artifactId>postgresql</artifactId>
</dependency>

2.3 lombok依赖

在编写后端代码时,经常需要编辑领域类代码,编写大量的get、set方法,重复编写很多代码。使用lombok能有大大提供开发效率。

<!-- lombok依赖 -->
<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
</dependency>

2.4 数据库连接池依赖

使用阿里巴巴开源的Druid数据连接池

<!-- 引入druid连接池 -->
<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>druid-spring-boot-starter</artifactId>
  <version>1.2.11</version>
</dependency>

2.5 Swagger 3依赖

  • Swagger是一种规范
  • springfox-swagger是基于Spring生态系统的、Swagger规范的实现
  • springfox-boot-starter是springfox针对Spring Boot提供的一个starter,简化Swagger依赖的导入
<!-- swagger 依赖 -->
<dependency>
  <groupId>io.springfox</groupId>
  <artifactId>springfox-boot-starter</artifactId>
  <version>3.0.0</version>
</dependency>

3. 配置Swagger 3

通过pom.xml安装对应的依赖后,需要做如下配置,一个是创建Swagger配置文件,提供相关的配置;另一个是编辑application.yml文件,提供spring.mvc.pathmatch.matching-strategy配置,修复Spring Boot(Spring Boot 版本2.6以上)整合spring-fox出现的问题。

3.1 Swagger配置文件

config文件夹中,创建SwaggerConfg.java文件,内容如下:

@Configuration
@EnableOpenApi
public class SwaggerConfig {
    @Bean
    public Docket docket() {
        return new Docket(DocumentationType.OAS_30)
                .apiInfo(apiInfo()).enable(true)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.jiaoxn.example.controller"))
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("这里是Swagger标题")
                .description("这里是Swagger描述")
                .version("v1.0")
                .build();
    }
}

其中:

  • 第1行的@Configuration注解通常用来声明一个Java配置类,用来取代以前的XML配置文件,从而使得配置变得更加简单、方便;
  • 第2行的@EnableOpenApi注解表明开启Swagger;
  • 第4行的@Bean注解方法docket,该方法会被AnnotationConfigApplicationContextAnnotationConfigWebApplicationContext扫描,然后添加到Spring容器中;
  • 第6行的new Docket(DocumentationType.OAS_30)表示使用3.0 版本的Swagger API,其中OAS的全程是OpenAPISpecification的简称,即OpenAPI说明书;
  • 第7行的apiInfo(apiInfo())表示配置API文档的基本信息
  • 第9行的内容指定API的接口范围为controller包;
  • 第10行的内容指定匹配所有的URL。

3.2 修改application.yml文件

完成2.1的配置文件后,启动应用时,可能会出现下图的问题:

img

img

这个问题的修复方式之一:修改application.yml文件,提供spring.mvc.pathmatch.matching-strategy配置即可:

spring:
  ...
  mvc:
      pathmatch:
        matching-strategy: ant_path_matcher

4. 初始化数据库配置

编辑application.yml文件,增加数据库配置。

spring:
  datasource:
    driver-class-name: org.postgresql.Driver
    url: jdbc:postgresql://localhost:5432/example
    username: postgres
    password: admin
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      initial-size: 10 # 初始化连接池大小
      min-idle: 5 # 最小空闲连接
      max-active: 15 # 最大连接数
      query-timeout: 1000 # 最大查询超时时间
      transaction-query-timeout: 10000 # 事务查询最大超时时间
      remove-abandoned-timeout: 30000 # 关闭空闲连接超时时间
      filters: stat, config

5. 配置MyBatis

编辑application.yml文件,增加MyBatis相关的配置:

mybatis:
  configuration:
    map-underscore-to-camel-case: true # 启用MyBatis的驼峰变量名映射
  mapper-locations: classpath:mapper/*.xml # 配置MyBatis的映射文件的存放位置
  type-aliases-package: com.jiaoxn.example.entity # 配置MyBatis Mapper别名,指定到具体的包

6. 创建数据表

本篇文章主要介绍公司数据表的CURD相关的操作,需要提前创建对应的数据表,SQL语句如下:

DROP TABLE IF EXISTS company;
CREATE TABLE company(
    id SERIAL NOT NULL,
    gmt_create TIMESTAMP NOT NULL,
    gmt_modified TIMESTAMP NOT NULL,
    name VARCHAR(255NOT NULL,
    is_deleted VARCHAR(1NOT NULL DEFAULT  0,
    PRIMARY KEY (id)
);

COMMENT ON TABLE company IS '公司';
COMMENT ON COLUMN company.id IS '主键';
COMMENT ON COLUMN company.gmt_create IS '创建时间';
COMMENT ON COLUMN company.gmt_modified IS '修改时间';
COMMENT ON COLUMN company.name IS '公司名称';
COMMENT ON COLUMN company.is_deleted IS '是否已删除;0表示未删除,1表示已删除';

7. 实现业务功能

7.1 创建相关文件

  • entity包中创建CompanyDO.java类;
  • dao包中创建CompanyDAO.java接口;
  • service包中创建CompanyService.java接口;
  • server.impl包中创建CompanyServiceImpl.java类;
  • controller包中创建CompanyController.java类。

7.2 修改主应用文件

package com.jiaoxn.example;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan(value = "com.jiaoxn.example.dao")
public class ExampleApplication {

 public static void main(String[] args) {
  SpringApplication.run(ExampleApplication.class, args);
 }

}

其中:

  • 增加了@MapperScan注解,在指定的包中查找对应的Mapper类

7.2 初始化CompanyDO类

package com.jiaoxn.example.entity;

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

import java.util.Date;

@Data
@ApiModel(value = "公司")
public class CompanyDO {
    @ApiModelProperty(value = "主键", name = "主键",  required = true)
    private Integer id;

    @ApiModelProperty(value = "创建时间", name = "创建时间"required = true)
    private Date gmtCreate;

    @ApiModelProperty(value = "修改时间", name = "修改时间"required = true)
    private Date gmtModified;

    @ApiModelProperty(value = "公司名称", name = "公司名称"required = true)
    private String name;

    @ApiModelProperty(value = "是否以删除", name = "是否以删除", notes = "0:已删除,1:未删除"required = true)
    private String isDeleted;
}

其中:

  • @Datalombok提供的注解,使用在类上,提供类属性的get、set方法,提供equal、hasCode、toString、canEqual方法;
  • @ApiModel@ApiModelPropertyspringfox提供的注解:
    • @ApiModel在实体类上使用,在swagger中提供模型的其他信息;
    • @ApiModelProperty在被@ApiModel注解的类的属性上使用,在swagger中添加和操作模型属性的数据。

在swagger上的展示效果如下:

img

7.2 根据ID查询具体的Company

  1. 编辑CompanyDAO文件,增加如下内容:
package com.jiaoxn.example.dao;

import com.jiaoxn.example.entity.CompanyDO;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;

@Repository
public interface CompanyDAO {
    @Select("SELECT * FROM company WHERE id = #{id};")
    CompanyDO queryById(Integer id);
}

其中:

  • @Repository:Spring提供的注解,用在持久层的接口上,将接口的实现类交给Spring管理,并能将所标注的类中抛出的数据访问异常封装为Spring的数据访问异常类型。另外,不使用该注解的话,在service层,以依赖注入的方式使用dao层,会提示警告。
  1. 编辑CompanyService文件,定义查询接口;
package com.jiaoxn.example.service;

import com.jiaoxn.example.entity.CompanyDO;

public interface CompanyService {
    /**
     * 通过ID查询单条数据
     * @param id 主键内容
     * @return 实例对象
     */
    CompanyDO queryById(Integer id);
}
  1. 编辑CompanyServiceImpl文件,实现CompanyService接口,并实现queryById方法;
package com.jiaoxn.example.service.impl;

import com.jiaoxn.example.dao.CompanyDAO;
import com.jiaoxn.example.entity.CompanyDO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class CompanyServiceImpl implements com.jiaoxn.example.service.CompanyService {
    private final CompanyDAO companyDAO;

    @Autowired
    public CompanyServiceImpl(CompanyDAO companyDAO) {
        this.companyDAO = companyDAO;
    }

    public CompanyDO queryById(Integer id) {
        return companyDAO.queryById(id);
    }
}

其中:

  • @Service:用于标识当前类是一个service类,并自动注入到Spring容器中;
  • @Autowried:自动装配,其作用是为了消除Java代码中的getter/setter与Bean属性中的property。Spring看到该注解后,将自动地在代码上下文中找到和其匹配的的Bean,并自动注入到对应的地方。
  1. 编辑CompanyController文件,内容如下:
package com.jiaoxn.example.controller;


import com.jiaoxn.example.entity.CompanyDO;
import com.jiaoxn.example.service.impl.CompanyServiceImpl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Api(tags = "公司")
@RestController
@RequestMapping("/company")
public class CompanyController {
    private final CompanyServiceImpl companyServiceImpl;

    @Autowired
    public CompanyController(CompanyServiceImpl companyServiceImpl) {
        this.companyServiceImpl = companyServiceImpl;
    }

    @ApiOperation(value = "通过ID查询单条数据")
    @ApiResponses({
            @ApiResponse(code = 200, message = "查询成功"),
            @ApiResponse(code = 500, message = "服务器内部错误")
    })
    @GetMapping("{id}")
    public ResponseEntity<CompanyDO> queryById(
            @ApiParam(name = "id", value = "公司ID", required = true) @PathVariable(name = "id") Integer id
    ) {

        return ResponseEntity.ok(companyServiceImpl.queryById(id));
    }
}

其中:

  • @Api:springfox提供的注解,用于类,表示这个类是Swagger的资源;
  • @ApiOperation:swagger提供的注解,用于描述某个接口的功能;
  • @ApiResponses@ApiResponse:swagger提供的注解,用于方法,会在接口文档里面对当前接口返回的信息进行说明;
  • @ApiParam:swagger提供的注解,用于方法,参数,字段说明,在方法上面对参数进行说明,会在接口文档上面显示参数的说明;
  • @RestController:SpringMVC的注解,用于标识该Controller提供RESTful API;
  • @RequestMapping:SpringMVC的注解,映射URL路径,将HTTP的请求地址映射到控制器类的处理方法上;
  • @GetMapping:SpringMVC的注解,是组合注解@RequestMapping(method=RequestMethod.GET)的缩写,用于将HTTP Get映射到具体的方法上。

7.5 实现效果

img