-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[전규진] 3차 과제 제출 #9
base: develop
Are you sure you want to change the base?
Changes from all commits
a0f1f58
fbe369e
d859da7
306f351
1c40372
f8b161a
90b9daa
bb02b16
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,43 @@ | ||
package cotato.backend.domains.post; | ||
|
||
import org.hibernate.annotations.ColumnDefault; | ||
import org.springframework.boot.context.properties.bind.DefaultValue; | ||
import org.springframework.stereotype.Service; | ||
|
||
import jakarta.persistence.Column; | ||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.GeneratedValue; | ||
import jakarta.persistence.GenerationType; | ||
import jakarta.persistence.Id; | ||
import lombok.AccessLevel; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import lombok.Setter; | ||
|
||
@Entity | ||
@Getter | ||
@Setter | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
public class Post { | ||
|
||
@Id@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private Long id; | ||
|
||
@Column(nullable = false) | ||
private String title; | ||
|
||
@Column(nullable = false) | ||
private String content; | ||
|
||
@Column(nullable = false) | ||
private String name; | ||
|
||
@ColumnDefault("0") | ||
private int views; | ||
|
||
public Post(String title, String content, String name) { | ||
this.title = title; | ||
this.content = content; | ||
this.name = name; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,19 @@ | ||
package cotato.backend.domains.post; | ||
|
||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.stream.Collectors; | ||
|
||
import org.springframework.data.domain.Page; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.DeleteMapping; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.PathVariable; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RequestParam; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
import cotato.backend.common.dto.DataResponse; | ||
|
@@ -23,4 +33,47 @@ public ResponseEntity<DataResponse<Void>> savePostsByExcel(@RequestBody SavePost | |
|
||
return ResponseEntity.ok(DataResponse.ok()); | ||
} | ||
|
||
@PostMapping("/single") | ||
public ResponseEntity<DataResponse<Void>> savePostBySingle(@RequestBody PostDTO postDTO){ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. validation도 추가해보시면 좋을 거 같아요! |
||
postService.savePostBySingle(postDTO); | ||
|
||
return ResponseEntity.ok(DataResponse.ok()); | ||
} | ||
|
||
@GetMapping("/read/{id}") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. RESTful API 맞지 않는 url 같습니다! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
public ResponseEntity<Post> readPostBySingle(@PathVariable Long id){ | ||
Post post = postService.readPostBySingle(id); | ||
|
||
return ResponseEntity.ok(post); | ||
} | ||
|
||
@GetMapping("/readByViews") | ||
public ResponseEntity<Map<String, Object>> readByView(@RequestParam(defaultValue = "0") int page){ | ||
int size = 10; | ||
Page<Post> postPage = postService.getPosts(page, size); | ||
List<Map<String, Object>> filteredPosts = postPage.getContent().stream().map(post -> { | ||
Map<String, Object> postMap = new HashMap<>(); | ||
postMap.put("id", post.getId()); | ||
postMap.put("title", post.getTitle()); | ||
postMap.put("name", post.getName()); | ||
return postMap; | ||
}).collect(Collectors.toList()); | ||
|
||
Map<String, Object> response = new HashMap<>(); | ||
response.put("posts", filteredPosts); // 게시글 리스트 | ||
response.put("currentPage", postPage.getNumber()); // 현재 페이지 | ||
response.put("totalPages", postPage.getTotalPages()); | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 변환을 controller에서 하셨군요! |
||
return ResponseEntity.ok(response); | ||
} | ||
|
||
@DeleteMapping("/delete/{id}") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. /delete는 따로 필요없을거같아요! |
||
public ResponseEntity<DataResponse<String>> deletePostBySingle(@PathVariable Long id) { | ||
postService.deletePostBySingle(id); | ||
|
||
return ResponseEntity.ok(DataResponse.success("게시글이 성공적으로 삭제 되었습니다.")); | ||
} | ||
|
||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package cotato.backend.domains.post; | ||
|
||
public class PostDTO { | ||
|
||
private String title; | ||
|
||
private String content; | ||
|
||
private String name; | ||
|
||
public String getTitle() { | ||
return title; | ||
} | ||
|
||
public String getContent() { | ||
return content; | ||
} | ||
|
||
public String getName() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. getter를 직접 만드셨군요! |
||
return name; | ||
} | ||
|
||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package cotato.backend.domains.post; | ||
|
||
import org.springframework.data.domain.Page; | ||
import org.springframework.data.domain.Pageable; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
import org.springframework.stereotype.Repository; | ||
|
||
@Repository | ||
public interface PostRepository extends JpaRepository<Post, Long> { | ||
Page<Post> findAllByOrderByViewsDesc(Pageable pageable); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,8 +3,13 @@ | |
import static cotato.backend.common.exception.ErrorCode.*; | ||
|
||
import java.util.List; | ||
import java.util.Optional; | ||
import java.util.stream.Collectors; | ||
|
||
import org.springframework.data.domain.Page; | ||
import org.springframework.data.domain.PageRequest; | ||
import org.springframework.data.domain.Pageable; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
|
@@ -20,6 +25,8 @@ | |
@Transactional | ||
public class PostService { | ||
|
||
private final PostRepository postRepository; | ||
|
||
// 로컬 파일 경로로부터 엑셀 파일을 읽어 Post 엔터티로 변환하고 저장 | ||
public void saveEstatesByExcel(String filePath) { | ||
try { | ||
|
@@ -33,10 +40,37 @@ public void saveEstatesByExcel(String filePath) { | |
return new Post(title, content, name); | ||
}) | ||
.collect(Collectors.toList()); | ||
postRepository.saveAll(posts); | ||
|
||
} catch (Exception e) { | ||
log.error("Failed to save estates by excel", e); | ||
throw ApiException.from(INTERNAL_SERVER_ERROR); | ||
} | ||
} | ||
|
||
public void savePostBySingle(PostDTO postDTO) { | ||
Post post = new Post(postDTO.getTitle(), postDTO.getContent(), postDTO.getName()); | ||
postRepository.save(post); | ||
} | ||
|
||
public Post readPostBySingle(Long id) { | ||
Optional<Post> optionalPost = postRepository.findById(id); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 부분은 조금 잘 못 된 거 같습니다! 스프링에서의 전역 예외 처리 방법에 대해 정리해서 다음 과제 pr에 첨부해주세요! |
||
Post post = optionalPost.get(); | ||
post.setViews(post.getViews() + 1); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Entity의 직접적인 Setter 사용은 값의 일관성을 해치는 결과가 나올수도 있어서 생성자 |
||
|
||
return post; | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
public Page<Post> getPosts(int page, int size) { | ||
Pageable pageable = PageRequest.of(page, size); | ||
return postRepository.findAllByOrderByViewsDesc(pageable); | ||
} | ||
|
||
public void deletePostBySingle(Long id) { | ||
Post post = postRepository.findById(id) | ||
.orElseThrow(() -> ApiException.of(HttpStatus.NOT_FOUND,"해당 ID의 게시글을 찾을 수 없습니다", "")); | ||
postRepository.delete(post); | ||
|
||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,13 @@ | ||
spring.application.name=backend | ||
|
||
spring.jpa.hibernate.ddl-auto=update | ||
spring.jpa.show-sql=true | ||
spring.jpa.properties.hibernate.format_sql=true | ||
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect | ||
|
||
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver | ||
spring.datasource.url=jdbc:mysql://localhost:3306/world?serverTimezone=UTC&characterEncoding=UTF-8 | ||
spring.datasource.username= root | ||
spring.datasource.password = 0000 | ||
Comment on lines
+10
to
+11
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 데이터베이스 키값이 외부로 노출되고 있어요! 보안상 문제가 발생할 수도 있으니 gitignore을 이용해서 해당 파일을 숨기는 것을 권장해 드려요 |
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오 이렇게 디폴트값을 지정할 수 있군요 배워갑니다!