Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion week3/README.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
.
.
47 changes: 47 additions & 0 deletions week3/[3주차]유효석.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
* public static final int => #define과 거의 유사!
* List 활용법
1) 정의: import java.util.List; + List< type> name; 이런 식으로 정의

* 겹치지 않고 정수 리스트 생성법
### 1) 가장 단순한 방법:
- 랜덤으로 숫자 생성 -> 기존의 리스트와 비교해서 없으면 ok 아니면 다시! count 세서 원하는 만큼 while loop
### 2) set이용!
- set으로 랜덤 넘버 생성 -> list로 변환
- import java.util.Set;

Set<Integer> uniqueNumbers = new HashSet<>();
int min = 1;
int max = 45;
count = 6;

while(uniqueNumebr.size() < count){
int num = random.nextInt(max - min +1) + min;
uniqueNubers.add(num);
}

List<Integer> list = new ArrayList<uniqueNumbers>
### 3) 오름차순 정렬방법
- Collections.sort( list );

// 내부 list를 자체로 바꿈. 즉, return하는 것이 아니고 리스트의 값들에 접근해서 순서를 바꾸고 영구적으로 저장함.

### 4) 생성자 주입(DI)과 AppConfig
- 클라이언트 class에서 A class가 필요할 때, 클라이언트 class 내부에서 바로 A class를 참조하는 것은 DIP원칙에 어긋난다.
- A class보다 상위 요소를 참조하는 것이 필요함. 따라서 A class의 상위요소(인터페이스)를 클라이언트 class가 가지고 있는 것이 바람직하다.
- 이때 생성자를 이용하여 참조하는 것 보단, 의존관계와 의존성 주입을 AppConfig class에서 따로 해주는 것이 적절함.
- 이 과정을 spring이 자동으로 해줄 수도 있음

### 5) class 간의 역할 분배
- class를 각 기능별로 생성하는 것은 책임을 너무 분배하는 것..
- class 내부에서도 충분히 메소드를 이용하여 책임을 분리할 수 있다!
- validate과 같은 메소드는 따로 validator를 이용한 처리보다 각 객체가 생성될 때 검사하는 것이 좋다.
- magic number 또한 magic number들을 묶어 놓은 class를 생성하기 보단 각 class가 가지고 있는 것이 불필요한 수정을 막을 수 있다.

### 6) 궁금한 점
- magic number를 각 class가 가지고 있을 때, 외부의 class 내부에서 해당 magic number가 필요한 경우 그대로 참조하는 것이 괜찮을까?
// 외부의 class에서도 magic number 따로 선언해야 할까? - 원래 magic number를 가지고 있는 class의 정보를 외부에서 따로 정의하고 있는 것이 좋아보이진 않는데..

### 7) 느낀점
- MVC 패턴에 대한 공부가 더 필요하다고 느꼈다. 각 블로그와 블로그의 예제들을 몇번 작성해 보았지만 아직도, controller의 역할을 이해하기 어려웠다.
controller와 service와의 차이점을 이해하기 어려웠다.
- AppConfig도 아직 완벽하게 이해되지 않아서 예제 코드를 몇번 더 써봐야 할 것 같다.
3 changes: 2 additions & 1 deletion week7/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,5 @@ Mysql: https://dev.mysql.com/downloads/mysql/

![img_1.png](img_1.png)
4. 의존성(Dependencies): Spring Web, Spring Boot DevTools, Lombok, Spring Data JPA 선택
5. Create 눌러서 선택

5. Create 눌러서 선택
45 changes: 45 additions & 0 deletions week7/[7주차]유효석.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# 7주차 과제

### 스프링 어노테이션
- 코드 사이에 특별한 의미, 기능을 수행하도록 하는 기술.
- 함수의 행동을 바꾸지는 않지만, 어노테이션에 대응 하는 processor가 어노테이션에 맞는 적절한 행동을 하게 해주는 마커.


- 사용 순서:
1. 어노테이션 정의
2. 클래스에 어노테이션 배치
3. 실행 중, reflection 이용 -> 추가 정보 획득 -> 기능 실시

- 종류
- @Configuration: Bean 정의의 소스로 쓰이는 클래스 마크.
- @Bean: 메서드에서 반환된 결과를 빈으로 저장하는 애너테이션.
- @Autowired: 스프링이 의존성 주입을 할 클래스를 명시하는 마크.
- @Override:


### 스프링 컨테이너
- 컨테이너가 생성하고 관리하는 객체 = bean(어노테이션으로 추가 할 수 있음)
- 스프링 컨테이너 = bean의 생명주기를 관리하는(생성/관리/제거) 역할.
- 생성자의 사용을 줄여 -> 객체간의 결합도를 낮출 수 있음.
- 객체들의 의존성을 줄이고 인터페이스만 참조하도록 설계 가능.
- 컨테이너, 애플리케이션 시작할 때 빈 정의를 로드 -> 인스턴스 생성

### 스프링의 의존성 주입
- AppConfig를 사용하여 직접 의존성을 주입하지 않고 Spring Boot에서 자동으로 객체간 의존관계를 설정해주는 것.
- @Component 어노테이션이 붙은 클래스들을 스캔한다.
- 스캔한 클래스들을 빈으로 등록한다.
- @Autowired 어노테이션이 붙은 클래스들 타입의 빈을 찾아 의존성을 주입한다.
- ex)
@Component // 빈으로 등록할 객체
public interface MyRepository{

}

public class MyService {
private final MyRepository myRepository;

@Autowired // 여기에 의존성 주입을 해줘..!
public MyService(MyRepository myRepository){
this.myRepository = myRepository;
}
}
13 changes: 13 additions & 0 deletions week8/유효석/Application.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}

}
29 changes: 29 additions & 0 deletions week8/유효석/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
1. POST
- POST 실행
![스크린샷](https://github.com/user-attachments/assets/dff28d7a-cdfe-46c5-95a9-b1da38646482)
id가 5인 새로운 user 등록


- POST 결과
![스크린샷](https://github.com/user-attachments/assets/dd049556-e702-4ea3-8a49-1e948f94d00)


2. PUT
- PUT 실행
![스크린샷](https://github.com/user-attachments/assets/a4a7486d-45fa-4166-b223-947de5cf64be)
id가 1인 user의 name과 email을 수정함.


- PUT 결과
![스크린샷](https://github.com/user-attachments/assets/4fe5d716-aabe-41d6-a12d-7f392f93b719)


3. DELETE
- DELETE 실행
![스크린샷](https://github.com/user-attachments/assets/2ef36d24-14b4-4218-900b-4a9b08a12f6a)
id가 1인 user를 삭제함.


- DELETE 결과
![스크린샷](https://github.com/user-attachments/assets/0e1a5483-0180-4926-b293-f57a440a0755)

46 changes: 46 additions & 0 deletions week8/유효석/[8주차 유효석].md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
service - controller 분리!
// controller는 요청 + 검증 -> 절대 DB를 알면 안돼!!
// service는 실제 업무 처리 w/ DB(repository)
// repository는 실제 DB와 소통하며 데이터 관리

USER INPUT -> controller -> service -> repository -> DB

controller: JASON -> DTO와 매칭 + service에게 업무 맡겨
service: repository를 이용하여 데이터 저장/불러오기

<UserService>
[어노테이션]
@RequiredArgsConstructor
- 생성자를 만들지 않아도 됨.

public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}

이 코드 자동으로 생성

// service는 controller 너무 많은 것을 알지 않도록 중간 다리 역할을 해줌


<UserController>
//변경이 존재하지 않음!
// 차피 DTO로 Json에서 넘겨 받을 거고 넘겨줄 때도 DTO로 할거니까!

[어노테이션]
@RestController
JSON요청/응답 자동처리
-> postman에서 body로 json보내면 자동으로 객체로 변환

@RequestMapping("/users")
이 컨트롤러의 기본 주소를 /users로 설정

JPA는 어떻게 변하는가?

DTO -> Entity로 변환 at service -> Repository = entity로 저장

CRUD

Create - INSERT
Read - SELECT
Update - UPDATE
Delete - DELETE
69 changes: 69 additions & 0 deletions week8/유효석/[9주차 유효석].md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
### 연관 관계 다중성
1. 나의 개수 to 너의 개수
2. 종류
- Many to One (= 학생 입장에서 학교는 다대일)
- One to many (= 학교 입장에서 각 학생은 일대다)
- One to One
- Many to Many
3. 방향성
- 종류
+ 단방향: 한쪽의 엔티티만 상대 엔티티 참조
+ 양방향: 양쪽이 서로 참조


4. 어노테이션
- @ManyToOne
+ 다대일 관계 매핑
+ fetch: 연관 관계의 데이터를 어떻게 가져올 지
* Eager Loading = 즉시 로딩; 엔티티 조회 시, 연관된 모든 데이터 로딩 // default임.
* Lazy Loading = 지연 로딩; 객체의 초기화를 최대한 지연, 주로 권장됨.
* ex) @ManyToOne(fetch = FetchType.LAZY)


- @OneToMany
+ 일대다 관계 매핑
+ mappedBy = 연관관계의 주인 설정
* ex) mappedBy = "post"
+ cascade = 엔티티 작업 수행시, 연관 엔티티도 동일한 작업 수행
* Type: PERSIST, MERGE, DETACH, PREFRESH, REMOVE, ALL
* ex) cascade = CascadeType.ALL
-------------------

## 코드 설계

### 기능
1. 회원
- 등록 = POSTMAN으로 함.

2. 게시판
- 게시글 / 댓글 조회 / 수정 / 삭제
- 수정 삭제 = 작성자 + 관리자만

3. Entity 구성
- User
- UserService
- UserRepository
- UserController
- Post(게시글)
- Comment

#### User
+ 기존 user를 그대로
+ role을 추가해서 관리자 여부 설정

#### Post
+ id, title, content
+ update : 게시글 수정
+ comment를 list로 가지고 있음.
+ addComment : 댓글 추가
+ deleteComment : 댓글 삭제


4. entity 관계 설정
- 회원은 게시판과 일대다 관계
- 회원은 댓글과 일대다 관계
- 게시판은 댓글들과 일대다 관계

--------------------
###새롭게 알게 된 것들
- @GeneratedValue => 값이 입력되지 않았을 때 자동으로 값을 넣어줌.
42 changes: 42 additions & 0 deletions week8/유효석/controller/PostController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.example.controller;

import com.example.entity.Post;
import com.example.service.PostService;
import com.example.dto.PostDto;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequiredArgsConstructor
@RequestMapping("/posts")

public class PostController {
private final PostService postService;

@PostMapping
public Long createPost(@RequestBody PostDto postDto) {
return postService.createPost(postDto);
}

@GetMapping
public List<PostDto> getPosts(){
return postService.findAllPosts().stream().map(PostDto::fromEntity).toList();
}

@GetMapping("/{id}")
public PostDto getPostById(@PathVariable Long postId){
Post post = postService.getPostById(postId);
return PostDto.fromEntity(post);
}

@DeleteMapping("/{id}")
public void deletePost(@PathVariable Long postId, @RequestParam Long authorId){
postService.deletePost(postId, authorId);
}

}
44 changes: 44 additions & 0 deletions week8/유효석/controller/UserController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.example.controller;

import com.example.dto.UserDto;
import com.example.repository.UserRepository;
import com.example.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequiredArgsConstructor
@RequestMapping("/users") // 필수는 아니지만 있으면 편함. // 동사가 들어가지 않는다.
public class UserController {
private final UserService userService;
private final UserRepository userRepository;

//jason으로 요청이 옴.
@PostMapping // 유저 생성하는 것. 자동으로 json -> DTO 생성
public void createUser(@RequestBody UserDto userDto) {
userService.addUser(userDto);
}

@GetMapping
public List<UserDto> getUsers(){ // 전체 유저 넘겨주는 것.
return userService.getAllUsers();
}

@GetMapping("/{id}")
public UserDto getUser(@PathVariable Long id) {
return userService.getUser(id);
}

@PutMapping("/{id}")
public void updateUser(@PathVariable Long id, @RequestBody UserDto dto){
userService.updateUser(id, dto);
}

@DeleteMapping("/{id}")
public void deleteUser(@PathVariable Long id) {
userService.deleteUser(id);
}

}
29 changes: 29 additions & 0 deletions week8/유효석/dto/CommentDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.example.dto;

import com.example.entity.Comment;
import com.example.entity.User;
import com.example.entity.Post;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CommentDto {

private Long id;
private Long postId;
private Long authorId;
private String content;

//DTO -> entity
// entity -> DTO

public Comment toEntity(User author, Post post){
return Comment.builder().content(this.content).author(author).post(post).build();
}
}
Loading