1. 예제 프로젝트 설명
- 게시글을 작성하는 기본 CRUD 프로젝트 가정
- 게시글 작성 시 이미지 업로드를 포함하여 구현하고 싶음
2. 공통 코드
- 이미지 업로드 로직을 제외한 기본적인 게시글 작성, 조회 로직만을 포함
* 구현한 이미지 업로드 프로젝트 *
- 내부 디렉토리에 업로드 https://blogan99.tistory.com/138
- DB에 이미지 직접 저장 https://blogan99.tistory.com/139
- 외부 경로에 업로드 https://blogan99.tistory.com/140
2-1. 공통 의존 라이브러리
- build.gradle
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'com.mysql:mysql-connector-j'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
- application.yml
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/imageDB
username: image_user
password: 1234
jpa:
hibernate:
ddl-auto: create # 처음만 create -> 이후엔 update로 수정
2-2. domain
- Post
- 게시글 엔티티에 해당
- 이미지 업로드 부분은 포함 x
@Entity
@Getter @Setter
@NoArgsConstructor
public class Post {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "post_id")
private Long id;
private String title;
private String content;
public Post(String title, String content) {
this.title = title;
this.content = content;
}
}
- PostDto
- 게시글 작성 시 필요한 DTO
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PostDto {
private String title;
private String content;
}
2-3. repository
- PostRepository
- JpaRepository 상속
@Repository
public interface PostRepository extends JpaRepository<Post, Long> {
}
2-4. service
- PostService
- 기본적인 게시글 작성, 조회 로직만 포함
@Service
@RequiredArgsConstructor
public class PostService {
private final PostRepository postRepository;
// 모든 게시글 리턴
public List<Post> findAll() {
return postRepository.findAll();
}
// 특정 게시글 리턴
public Post findById(Long postId) {
return postRepository.findById(postId).orElse(null);
}
// 게시글 저장
@Transactional
public Post save(PostDto postDto) {
Post post = new Post(postDto.getTitle(), postDto.getContent());
return postRepository.save(post);
}
}
2-5. controller
- PostApiController
- REST API 사용 방식으로 구현
- 기본적인 게시글 작성, 조회 로직만 포함
@RestController
@RequiredArgsConstructor
@RequestMapping("/v0/api/posts")
public class PostApiController {
private final PostService postService;
// 모든 게시글 조회
@GetMapping
public ResponseEntity<List<Post>> findAllPosts() {
return ResponseEntity.ok(postService.findAll());
}
// 특정 게시글 단건 조회
@GetMapping("/{postId}")
public ResponseEntity<Post> findPost(@PathVariable("postId") Long postId) {
Post post = postService.findById(postId);
return post == null ? ResponseEntity.status(HttpStatus.NO_CONTENT).body(null) : ResponseEntity.ok(post);
}
// 게시글 작성
@PostMapping
public ResponseEntity<Post> savePost(@RequestBody PostDto postDto) {
return ResponseEntity.status(HttpStatus.CREATED)
.body(postService.save(postDto));
}
}
3. 공통 실행 결과
- Postman으로 결과 확인
3-1. 게시글 작성 (POST localhost:8080/v0/api/posts)
3-2. 모든 게시글 조회 (GET localhost:8080/v0/api/posts)
3-3. 특정 게시글 조회 (GET localhost:8080/v0/api/posts/1)