First the official documentation:
1. JPA related concepts
2. Create a Springboot project
Modify the pom file, you can directly copy and paste, web dependencies and JPA dependencies.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.11</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>mybatisdemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mybatisdemo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
The yml configuration file is as follows: Pay attention to the driver version and database name.
spring:
jpa:
show-sql: true
hibernate:
ddl-auto: update
datasource:
url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT
username: root
password: 1111
driver-class-name: com.mysql.cj.jdbc.Driver
Create an entity class: the case structure is as follows, you can create it according to this, entity class, service, dao, controller
Create a dao package to inherit from
JpaRepository,
The first is the entity class, and the second is the type of the primary key of the entity class.
package com.example.mybatisdemo.dao;
import com.example.mybatisdemo.model.Account;
import org.springframework.data.jpa.repository.JpaRepository;
public interface AccountDao extends JpaRepository<Account,Integer> {
}
The following are some methods that come with JPA, you can view the source code, as follows;
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package org.springframework.data.jpa.repository;
import java.util.List;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.QueryByExampleExecutor;
@NoRepositoryBean
public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
List<T> findAll();
List<T> findAll(Sort sort);
List<T> findAllById(Iterable<ID> ids);
<S extends T> List<S> saveAll(Iterable<S> entities);
void flush();
<S extends T> S saveAndFlush(S entity);
<S extends T> List<S> saveAllAndFlush(Iterable<S> entities);
/** @deprecated */
@Deprecated
default void deleteInBatch(Iterable<T> entities) {
this.deleteAllInBatch(entities);
}
void deleteAllInBatch(Iterable<T> entities);
void deleteAllByIdInBatch(Iterable<ID> ids);
void deleteAllInBatch();
/** @deprecated */
@Deprecated
T getOne(ID id);
/** @deprecated */
@Deprecated
T getById(ID id);
T getReferenceById(ID id);
<S extends T> List<S> findAll(Example<S> example);
<S extends T> List<S> findAll(Example<S> example, Sort sort);
}
Create a service package.
package com.example.mybatisdemo.service;
import com.example.mybatisdemo.model.Account;
import java.util.List;
public interface AccountService {
List<Account> findAll();
}
Create an implementation class impl
package com.example.mybatisdemo.service.impl;
import com.example.mybatisdemo.dao.AccountDao;
import com.example.mybatisdemo.model.Account;
import com.example.mybatisdemo.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountDao accountDao;
@Override
public List<Account> findAll() {
return accountDao.findAll();
}
}
Entity class:
package com.example.mybatisdemo.model;
import lombok.*;
import javax.persistence.Id;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Table;
import java.io.Serializable;
@Entity
@Table(name="account")
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@ToString
public class Account implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
private double money;
}
controller:
package com.example.mybatisdemo.controller;
import com.example.mybatisdemo.model.Account;
import com.example.mybatisdemo.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/account")
public class AccountController {
@Autowired
private AccountService accountService;
@RequestMapping("/findAll")
public List<Account> findAll(){
return accountService.findAll();
}
}
The above is the part of integrating JPA, and then put on Swagger2.
3. Integrate Swagger2
(1) Introduction to Swagger:
Swagger is a standardized and complete framework for generating, describing, invoking and visualizing RESTful style Web services. The overall goal is to have the client and the filesystem update at the same rate as the server. Documenting methods, parameters and models is tightly integrated into the server-side code, allowing the API to always stay in sync. Swagger makes deployment management and using powerful APIs easier than ever.
(2) API description of Swagger:
(3) Specific use:
Add pom dependencies.
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
<exclusions>
<exclusion>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>1.5.22</version>
</dependency>
Modify the yml configuration file, the following Mvc related configuration must be added, otherwise an error will be reported. Because of the version problem.
spring:
jpa:
show-sql: true
hibernate:
ddl-auto: update
datasource:
url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT
username: root
password: 1111
driver-class-name: com.mysql.cj.jdbc.Driver
mvc:
pathmatch:
matching-strategy: ant_path_matcher
management:
endpoints:
web:
exposure:
include: health
Create a new config folder. Create it as shown below.
The code is as follows: Note the path in the code.
package com.example.mybatisdemo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class AppSwaggerConfig {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.example.mybatisdemo"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("曹俊测试Swagger接口文档")
.description("测试模块")
.version("1.0.release").build();
}
}
Modify the entity class as follows: add relevant field descriptions.
package com.example.mybatisdemo.model;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import javax.persistence.Id;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Table;
import java.io.Serializable;
@Entity
@Table(name="account")
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@ToString
@ApiModel(description = "用户账户表")
public class Account implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@ApiModelProperty(value = "ID")
private Integer id;
@ApiModelProperty(value = "姓名")
private String name;
@ApiModelProperty(value = "账户余额")
private double money;
}
Create a dto folder, add two files Result PageResult inside
code show as below:
package com.example.mybatisdemo.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(description = "数据传输对象-通用结果")
public class Result {
@ApiModelProperty(value = "操作结果")
private boolean success;
@ApiModelProperty(value = "操作消息")
private String message;
}
package com.example.mybatisdemo.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(description = "数据传输对象-分页结果")
public class PageResult {
@ApiModelProperty(value = "总条数")
Long total;
@ApiModelProperty(value = "结果集")
List rows;
}
Modify it on the controller. Add the relevant CRUD code:
package com.example.mybatisdemo.controller;
import com.example.mybatisdemo.dao.AccountDao;
import com.example.mybatisdemo.dto.PageResult;
import com.example.mybatisdemo.dto.Result;
import com.example.mybatisdemo.model.Account;
import com.example.mybatisdemo.service.AccountService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/account")
@Api(tags = "用户管理")
public class AccountController {
@Autowired
private AccountService accountService;
@Autowired
private AccountDao accountDao;
@GetMapping("/findAll")
@ApiOperation(value = "查询所有用户信息")
public List<Account> findAll(){
return accountService.findAll();
}
@PostMapping("/newAccount")
@ApiOperation(value = "新增")
public Result newAccount(Account account){
try {
accountService.newAccount(account);
return new Result(true,"添加成功");
}catch (Exception e){
e.printStackTrace();
return new Result(false,"添加失败");
}
}
@GetMapping("/findPage/{currentPage}/{size}")
@ApiOperation(value = "分页查询")
@ApiImplicitParams({
@ApiImplicitParam(name = "currentPage", value = "当前页码", required = true, dataTypeClass = Integer.class),
@ApiImplicitParam(name = "size", value = "每页条数", required = true, dataTypeClass = Integer.class)
})
public PageResult findPage(@PathVariable("currentPage") int currentPage, @PathVariable("size") int size) {
Page<Account> page = accountDao.findAll(PageRequest.of(currentPage, size));
return new PageResult(page.getTotalElements(), page.getContent());
}
@GetMapping("/findPage2")
@ApiOperation(value = "分页查询2")
@ApiImplicitParams({
@ApiImplicitParam(name = "currentPage", value = "当前页码", required = true, dataTypeClass = Integer.class),
@ApiImplicitParam(name = "size", value = "每页条数", required = true, dataTypeClass = Integer.class)
})
public PageResult findPage2(@RequestParam("currentPage") int currentPage, @RequestParam("size") int size) {
Page<Account> page = accountDao.findAll(PageRequest.of(currentPage, size));
return new PageResult(page.getTotalElements(), page.getContent());
}
@GetMapping("/findOne")
@ApiOperation(value = "根据id查询")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "ID", required = true, dataTypeClass = Long.class)
})
public Account findOne(Integer id) {
return accountDao.findById(id).get();
}
@GetMapping("/delete")
@ApiOperation(value = "删除")
@ApiImplicitParams({
@ApiImplicitParam(name = "ids", value = "ID集合", required = true, dataTypeClass = Long.class)
})
public Result delete(Integer[] ids) {
try {
for (Integer id : ids) {
accountDao.deleteById(id);
}
return new Result(true, "删除成功");
} catch (Exception e) {
e.printStackTrace();
return new Result(false, "删除失败");
}
}
}
Finally start the project for testing
http://localhost:8080/swagger-ui.html