Skip to main content

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 全部查询