Spring Boot CRUD using JPA
info
Create a Project, practice CRUD using Spring-JPA.
使用 Spring-JPA 练习增删改查
Maven 配置
pom.xml
配置文件
...
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
...
<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>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.modelmapper/modelmapper -->
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>2.4.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
Spring Boot 配置文件
server.port = 8080
# datasource
spring.datasource.url = jdbc:mysql://localhost:3306/iccblog?useSSL=false&serverTimezone=UTC
spring.datasource.username= ...
spring.datasource.password= ...
# hibernate properties
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
# hibernate ddl auto(create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto = update
...
logging.level.org.springframework.security=DEBUG
spring.security.user.name=...
spring.security.user.password=...
spring.security.user.roles=ADMIN
## App Properties
app.jwt-secret= JWTSecretKeysds
app.jwt-expiration-milliseconds = 604800000
## Spring Profile: dev, prod
spring.profiles.active=dev
Spring Boot CRUD
entity
package com.chuwa.iccblog.entity;
@Entity
@Table(name = "posts", uniqueConstraints = {
@UniqueConstraint(columnNames = {"title"})
})
public class Post {
@Id
@GeneratedValue(
strategy = GenerationType.IDENTITY
)
private Long id;
@Column(name = "title", nullable = false)
private String title;
@Column(name = "description", nullable = false)
private String description;
@Column(name = "content", nullable = false)
private String content;
@OneToMany(mappedBy = "post", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<Comment> comments = new HashSet<>();
@CreationTimestamp
private LocalDateTime createDateTime;
@UpdateTimestamp
private LocalDateTime updateDateTime;
}
// ...
dao
package com.chuwa.iccblog.dao;
@Repository
public interface PostRepository extends JpaRepository<Post, Long> {
}
payload
package com.chuwa.iccblog.payload;
public class PostDto {
private long id;
@NotEmpty
@Size(min = 2, message = "Post title should have at least 2 characters")
private String title;
@NotEmpty
@Size(min = 10, message = "Post description should have at least 10 characters")
private String description;
@NotEmpty
private String content;
}
// ...
package com.chuwa.iccblog.payload;
public class PostResponse {
private List<PostDto> content;
private int pageNo;
private int pageSize;
private long totalElements;
private int totalPages;
private boolean last;
}
// ...
service and impl
package com.chuwa.iccblog.service;
public interface PostService {
PostDto createPost(PostDto postDto);
PostDto getPostById(long id);
PostDto updatePost(PostDto postDto, long id);
void deletePostById(long id);
// 分页查询
PostResponse getAllPost(int pageNo, int pageSize, String sortBy, String sortDir);
}
package com.chuwa.iccblog.service.impl;
@Service
public class PostServiceImpl implements PostService {
@Autowired
private PostRepository postRepository;
@Override
public PostDto createPost(PostDto postDto) {
// 把payload转换为entity,让 DAO 去把该数据存到数据库中
// postDto pojo -> post entity
Post post = new Post();
post.setTitle(postDto.getTitle());
post.setDescription(postDto.getDescription());
post.setContent(postDto.getContent());
// 已转换成 entity
Post savedPost = postRepository.save(post);
// 把 post entity对象转换为dto
PostDto postResponse = new PostDto();
postResponse.setId(savedPost.getId());
postResponse.setDescription(savedPost.getDescription());
postResponse.setTitle(savedPost.getTitle());
postResponse.setContent(savedPost.getContent());
return postResponse;
}
@Override
public PostDto getPostById(long id) {
Post post = postRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("post", "id", id));
return mapToDTO(post);
}
@Override
public PostDto updatePost(PostDto postDto, long id) {
Post post = postRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("post", "id", id));
post.setTitle(postDto.getTitle());
post.setDescription(postDto.getDescription());
post.setContent(postDto.getContent());
Post updatePost = postRepository.save(post);
return mapToDTO(updatePost);
}
@Override
public void deletePostById(long id) {
Post post = postRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("post", "id", id));
postRepository.delete(post);
}
@Override
public PostResponse getAllPost(int pageNo, int pageSize, String sortBy, String sortDir) {
Sort sort = sortDir.equalsIgnoreCase(Sort.Direction.ASC.name()) ? Sort.by(sortBy).ascending()
: Sort.by(sortBy).descending();
// create pageable instance
PageRequest pageRequest = PageRequest.of(pageNo, pageSize, sort);
Page<Post> pagePosts = postRepository.findAll(pageRequest);
// get content for page abject
List<Post> posts = pagePosts.getContent();
List<PostDto> postDtos = posts.stream().map(post -> mapToDTO(post)).collect(Collectors.toList());;
PostResponse postResponse = new PostResponse();
postResponse.setContent(postDtos);
postResponse.setPageNo(pagePosts.getNumber());
postResponse.setPageSize(pagePosts.getSize());
postResponse.setTotalElements(pagePosts.getTotalElements());
postResponse.setTotalPages(pagePosts.getTotalPages());
postResponse.setLast(pagePosts.isLast());
return postResponse;
}
private PostDto mapToDTO(Post post) {
PostDto postDto = new PostDto();
postDto.setId(post.getId());
postDto.setTitle(post.getTitle());
postDto.setDescription(post.getDescription());
postDto.setContent(post.getContent());
return postDto;
}
private Post mapToEntity(PostDto postDto){
Post post = new Post();
post.setTitle(postDto.getTitle());
post.setDescription(postDto.getDescription());
post.setContent(postDto.getContent());
return post;
}
}
controller
package com.chuwa.iccblog.controller;
@RestController
@RequestMapping("/api/v1/posts")
public class PostController {
@Autowired
private PostService postService;
@PostMapping
public ResponseEntity<PostDto> createPost(@RequestBody PostDto postDto) {
// 调用 service
PostDto postResponse = postService.createPost(postDto);
return new ResponseEntity<>(postResponse, HttpStatus.CREATED);
}
@GetMapping("/{id}")
public ResponseEntity<PostDto> getPostById(@PathVariable(name = "id") long id) {
return ResponseEntity.ok(postService.getPostById(id));
}
@PutMapping("/{id}")
public ResponseEntity<PostDto> updatePostById(@RequestBody PostDto postDto, @PathVariable(name = "id") long id) {
PostDto postResponse = postService.updatePost(postDto, id);
return new ResponseEntity<>(postResponse, HttpStatus.OK);
}
@DeleteMapping("/{id}")
public ResponseEntity<String> deletePost(@PathVariable(name = "id") long id) {
postService.deletePostById(id);
return new ResponseEntity<>("Post entity deleted successfully.", HttpStatus.OK);
}
/**
* 该方法用于分页查询
* @param pageNo
* @param pageSize
* @param sortBy
* @param sortDir
* @return PostResponse
*/
@GetMapping
public PostResponse getAllPosts(
@RequestParam(value = "pageNo", defaultValue = AppConstants.DEFAULT_PAGE_NUMBER, required = false) int pageNo,
@RequestParam(value = "pageSize", defaultValue = AppConstants.DEFAULT_PAGE_SIZE, required = false) int pageSize,
@RequestParam(value = "sortBy", defaultValue = AppConstants.DEFAULT_SORT_BY, required = false) String sortBy,
@RequestParam(value = "sortDir", defaultValue = AppConstants.DEFAULT_SORT_DIR, required = false) String sortDir
) {
return postService.getAllPost(pageNo, pageSize, sortBy, sortDir);
}
}
API Testing
- 通过 JWT 登录
- 获取
accessToken
- Authorization:
Bearer Token
- 填入
Token
- 分页查询 or 全部查询