本篇基于公司(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,该方法会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext扫描,然后添加到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
这个问题的修复方式之一:修改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(255) NOT NULL,
is_deleted VARCHAR(1) NOT 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;
}
其中:
@Data:lombok提供的注解,使用在类上,提供类属性的get、set方法,提供equal、hasCode、toString、canEqual方法;@ApiModel和@ApiModelProperty:springfox提供的注解:-
@ApiModel在实体类上使用,在swagger中提供模型的其他信息;@ApiModelProperty在被@ApiModel注解的类的属性上使用,在swagger中添加和操作模型属性的数据。
在swagger上的展示效果如下:
7.2 根据ID查询具体的Company
- 编辑
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层,会提示警告。
- 编辑
CompanyService文件,定义查询接口;
package com.jiaoxn.example.service;
import com.jiaoxn.example.entity.CompanyDO;
public interface CompanyService {
/**
* 通过ID查询单条数据
* @param id 主键内容
* @return 实例对象
*/
CompanyDO queryById(Integer id);
}
- 编辑
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,并自动注入到对应的地方。
- 编辑
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映射到具体的方法上。