diff --git "a/2\354\243\274\354\260\250 \353\246\254\353\247\210\354\235\270\353\223\234 \353\260\217 \352\263\274\354\240\234/week_2_remind/src/main/java/org/sopt/week_2_remind/controller/MemberController.java" "b/2\354\243\274\354\260\250 \353\246\254\353\247\210\354\235\270\353\223\234 \353\260\217 \352\263\274\354\240\234/week_2_remind/src/main/java/org/sopt/week_2_remind/controller/MemberController.java" new file mode 100644 index 0000000..9e96148 --- /dev/null +++ "b/2\354\243\274\354\260\250 \353\246\254\353\247\210\354\235\270\353\223\234 \353\260\217 \352\263\274\354\240\234/week_2_remind/src/main/java/org/sopt/week_2_remind/controller/MemberController.java" @@ -0,0 +1,56 @@ +package org.sopt.week_2_remind.controller; + +import lombok.RequiredArgsConstructor; +import org.sopt.week_2_remind.service.MemberCreateDto; +import org.sopt.week_2_remind.service.MemberFindDto; +import org.sopt.week_2_remind.service.MemberService; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.*; + +import java.net.URI; +import java.util.List; + +@Transactional +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/v1/member") //어디로 요청이 들어올거냐?를 보는 것. +public class MemberController { + private final MemberService memberService; + + @PostMapping + public ResponseEntity postMember(@RequestBody MemberCreateDto memberCreate){ + return ResponseEntity.created(URI.create(memberService.createMember(memberCreate))).build(); + //createMember가 MemberService의 함수이다. + } + + @GetMapping("/{memberId}") + public ResponseEntity findMemberById(@PathVariable Long memberId){ + return ResponseEntity.ok(memberService.findMemberById(memberId)); + //findMemberById가 MemberService의 함수이다. + } + + @DeleteMapping("/{memberId}") + public ResponseEntity deleteMember(@PathVariable Long memberId){ + memberService.deleteMemberById(memberId); //deleteMemberById가 MemberService의 함수이다. + return ResponseEntity.noContent().build(); + /* + 클라이언트에게 반환할 데이터가 없으므로, HTTP 상태 코드 204(No Content)를 함께 응답한다. + 이는 요청이 성공적으로 처리되었지만 응답으로 반환할 데이터가 없음을 나타낸다. + */ + } + + //기존 세미나 코드에서 이 부분 추가 + @GetMapping("/memberList") + public ResponseEntity> findAllMembers() { + try { + List members = memberService.findAllMembers(); + return ResponseEntity.ok(members); + } catch (Exception e) { + e.printStackTrace(); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); + } + } + +} diff --git "a/2\354\243\274\354\260\250 \353\246\254\353\247\210\354\235\270\353\223\234 \353\260\217 \352\263\274\354\240\234/week_2_remind/src/main/java/org/sopt/week_2_remind/controller/TestController.java" "b/2\354\243\274\354\260\250 \353\246\254\353\247\210\354\235\270\353\223\234 \353\260\217 \352\263\274\354\240\234/week_2_remind/src/main/java/org/sopt/week_2_remind/controller/TestController.java" new file mode 100644 index 0000000..8729119 --- /dev/null +++ "b/2\354\243\274\354\260\250 \353\246\254\353\247\210\354\235\270\353\223\234 \353\260\217 \352\263\274\354\240\234/week_2_remind/src/main/java/org/sopt/week_2_remind/controller/TestController.java" @@ -0,0 +1,26 @@ +package org.sopt.week_2_remind.controller; + +import org.sopt.week_2_remind.controller.dto.ApiResponse; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/* + * 이 컨트롤러는 /test 경로로 들어오는 GET 요청에는 "test API" 문자열을 반환하고, + * /test/json 경로로 들어오는 GET 요청에는 JSON 형식의 응답을 반환 + */ + +@RestController +@RequestMapping("/test") +public class TestController { + + @GetMapping + public String test(){ + return "test API"; + } + + @GetMapping("/json") + public ApiResponse testJson(){ + return ApiResponse.create("test API with JSON"); + } +} diff --git "a/2\354\243\274\354\260\250 \353\246\254\353\247\210\354\235\270\353\223\234 \353\260\217 \352\263\274\354\240\234/week_2_remind/src/main/java/org/sopt/week_2_remind/controller/dto/ApiResponse.java" "b/2\354\243\274\354\260\250 \353\246\254\353\247\210\354\235\270\353\223\234 \353\260\217 \352\263\274\354\240\234/week_2_remind/src/main/java/org/sopt/week_2_remind/controller/dto/ApiResponse.java" new file mode 100644 index 0000000..933fcde --- /dev/null +++ "b/2\354\243\274\354\260\250 \353\246\254\353\247\210\354\235\270\353\223\234 \353\260\217 \352\263\274\354\240\234/week_2_remind/src/main/java/org/sopt/week_2_remind/controller/dto/ApiResponse.java" @@ -0,0 +1,18 @@ +package org.sopt.week_2_remind.controller.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/* +JSON 통신을 해야 하므로, 이 클래스를 활용하여 JSON 객체를 만드는 것이다. +리스폰스 객체의 필드에 접근해야하기 때문에 @Getter 어노테이션이 없으면 통신이 되지 않음. + */ +@AllArgsConstructor //생성자 자동으로 생성해줌 +@Getter +public class ApiResponse { + private String content; + + public static ApiResponse create(String content){ + return new ApiResponse(content); + } +} diff --git "a/2\354\243\274\354\260\250 \353\246\254\353\247\210\354\235\270\353\223\234 \353\260\217 \352\263\274\354\240\234/week_2_remind/src/main/java/org/sopt/week_2_remind/domain/Member.java" "b/2\354\243\274\354\260\250 \353\246\254\353\247\210\354\235\270\353\223\234 \353\260\217 \352\263\274\354\240\234/week_2_remind/src/main/java/org/sopt/week_2_remind/domain/Member.java" new file mode 100644 index 0000000..9849f26 --- /dev/null +++ "b/2\354\243\274\354\260\250 \353\246\254\353\247\210\354\235\270\353\223\234 \353\260\217 \352\263\274\354\240\234/week_2_remind/src/main/java/org/sopt/week_2_remind/domain/Member.java" @@ -0,0 +1,42 @@ +package org.sopt.week_2_remind.domain; + +import jakarta.persistence.*; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.net.PasswordAuthentication; + +@Entity +@Getter +@NoArgsConstructor +public class Member { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + private String name; + + @Enumerated(EnumType.STRING) + private Part part; + private int age; + + //@Builder 애노테이션 붙임으로써 그냥 빌더패턴과 같아짐 + @Builder + private Member(String name, Part part, int age){ + this.name=name; + this.part=part; + this.age=age; + } + + //이거와 같아진 것! 편한거 골라서 쓰면 된다. + public static Member create(String name, Part part, int age){ + return Member.builder() + .name(name) + .part(part) + .age(age) + .build(); + } + +} diff --git "a/2\354\243\274\354\260\250 \353\246\254\353\247\210\354\235\270\353\223\234 \353\260\217 \352\263\274\354\240\234/week_2_remind/src/main/java/org/sopt/week_2_remind/domain/Part.java" "b/2\354\243\274\354\260\250 \353\246\254\353\247\210\354\235\270\353\223\234 \353\260\217 \352\263\274\354\240\234/week_2_remind/src/main/java/org/sopt/week_2_remind/domain/Part.java" new file mode 100644 index 0000000..9bdf7ea --- /dev/null +++ "b/2\354\243\274\354\260\250 \353\246\254\353\247\210\354\235\270\353\223\234 \353\260\217 \352\263\274\354\240\234/week_2_remind/src/main/java/org/sopt/week_2_remind/domain/Part.java" @@ -0,0 +1,10 @@ +package org.sopt.week_2_remind.domain; + +public enum Part { + IOS, + SERVER, + ANDROID, + PLAN, + WEB, + DESIGN; +} diff --git "a/2\354\243\274\354\260\250 \353\246\254\353\247\210\354\235\270\353\223\234 \353\260\217 \352\263\274\354\240\234/week_2_remind/src/main/java/org/sopt/week_2_remind/repository/MemberRepository.java" "b/2\354\243\274\354\260\250 \353\246\254\353\247\210\354\235\270\353\223\234 \353\260\217 \352\263\274\354\240\234/week_2_remind/src/main/java/org/sopt/week_2_remind/repository/MemberRepository.java" new file mode 100644 index 0000000..59373ef --- /dev/null +++ "b/2\354\243\274\354\260\250 \353\246\254\353\247\210\354\235\270\353\223\234 \353\260\217 \352\263\274\354\240\234/week_2_remind/src/main/java/org/sopt/week_2_remind/repository/MemberRepository.java" @@ -0,0 +1,11 @@ +package org.sopt.week_2_remind.repository; + +import org.sopt.week_2_remind.domain.Member; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface MemberRepository extends JpaRepository { + /* + JPA에서 기본적으로 delete, get 이런거 제공해줌.. + DB에서 자체적으로 생성해주는 ID로 찾고, 지우고 이런거 하는듯 + */ +} diff --git "a/2\354\243\274\354\260\250 \353\246\254\353\247\210\354\235\270\353\223\234 \353\260\217 \352\263\274\354\240\234/week_2_remind/src/main/java/org/sopt/week_2_remind/service/MemberCreateDto.java" "b/2\354\243\274\354\260\250 \353\246\254\353\247\210\354\235\270\353\223\234 \353\260\217 \352\263\274\354\240\234/week_2_remind/src/main/java/org/sopt/week_2_remind/service/MemberCreateDto.java" new file mode 100644 index 0000000..74f812b --- /dev/null +++ "b/2\354\243\274\354\260\250 \353\246\254\353\247\210\354\235\270\353\223\234 \353\260\217 \352\263\274\354\240\234/week_2_remind/src/main/java/org/sopt/week_2_remind/service/MemberCreateDto.java" @@ -0,0 +1,12 @@ +package org.sopt.week_2_remind.service; + +import org.sopt.week_2_remind.domain.Part; + +/* +- 자동으로 접근자 메서드(getter)가 생성된다. +- 레코드는 equals(), hashCode(), toString() 메서드가 자동으로 생성 +- 레코드는 불변(immutable)하며, 한 번 생성되면 내부 상태를 변경할 수 없습니다. +- 필드를 final로 선언하여 보장 + */ +public record MemberCreateDto(String name, Part part, int age) { +} diff --git "a/2\354\243\274\354\260\250 \353\246\254\353\247\210\354\235\270\353\223\234 \353\260\217 \352\263\274\354\240\234/week_2_remind/src/main/java/org/sopt/week_2_remind/service/MemberFindDto.java" "b/2\354\243\274\354\260\250 \353\246\254\353\247\210\354\235\270\353\223\234 \353\260\217 \352\263\274\354\240\234/week_2_remind/src/main/java/org/sopt/week_2_remind/service/MemberFindDto.java" new file mode 100644 index 0000000..54b97ee --- /dev/null +++ "b/2\354\243\274\354\260\250 \353\246\254\353\247\210\354\235\270\353\223\234 \353\260\217 \352\263\274\354\240\234/week_2_remind/src/main/java/org/sopt/week_2_remind/service/MemberFindDto.java" @@ -0,0 +1,14 @@ +package org.sopt.week_2_remind.service; + +import org.sopt.week_2_remind.domain.Member; +import org.sopt.week_2_remind.domain.Part; + +public record MemberFindDto(String name, Part part, int age) { + /* + 이 메서드는 Member 객체를 인자로 받아서 + 해당 객체의 정보를 사용하여 MemberFindDto 인스턴스를 생성합 + */ + public static MemberFindDto of(Member member){ + return new MemberFindDto(member.getName(), member.getPart(), member.getAge()); + } +} diff --git "a/2\354\243\274\354\260\250 \353\246\254\353\247\210\354\235\270\353\223\234 \353\260\217 \352\263\274\354\240\234/week_2_remind/src/main/java/org/sopt/week_2_remind/service/MemberService.java" "b/2\354\243\274\354\260\250 \353\246\254\353\247\210\354\235\270\353\223\234 \353\260\217 \352\263\274\354\240\234/week_2_remind/src/main/java/org/sopt/week_2_remind/service/MemberService.java" new file mode 100644 index 0000000..4d00b9d --- /dev/null +++ "b/2\354\243\274\354\260\250 \353\246\254\353\247\210\354\235\270\353\223\234 \353\260\217 \352\263\274\354\240\234/week_2_remind/src/main/java/org/sopt/week_2_remind/service/MemberService.java" @@ -0,0 +1,51 @@ +package org.sopt.week_2_remind.service; + +import jakarta.persistence.EntityNotFoundException; +import lombok.RequiredArgsConstructor; +import org.sopt.week_2_remind.domain.Member; +import org.sopt.week_2_remind.repository.MemberRepository; +import org.springframework.core.SpringVersion; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +public class MemberService { //Service 에는 비즈니스 로직을 구현한다. + + private final MemberRepository memberRepository; + + @Transactional + public String createMember(MemberCreateDto memberCreate){ //포스트맨에서 POST로 멤버 생성 가능 + Member member = memberRepository.save(Member.create(memberCreate.name(), memberCreate.part(), memberCreate.age())); + return member.getId().toString(); + } + + public MemberFindDto findMemberById(Long memberId){ //ID를 기준으로 Member 찾기 + Member member = memberRepository.findById(memberId).orElseThrow( + () -> new EntityNotFoundException("ID에 해당하는 사용자가 존재하지 않습니다.")); + return MemberFindDto.of(member); + } + + @Transactional + public void deleteMemberById(Long memberId){ //ID를 기준으로 Member 를 삭제 + Member member = memberRepository.findById(memberId).orElseThrow( + ()->new EntityNotFoundException("ID에 해당하는 사용자가 존재하지 않습니다.")); + memberRepository.delete(member); + } + + //기존 세미나 코드에서 이 부분 추가 + public List findAllMembers() { + try { + return memberRepository.findAll().stream() + .map(MemberFindDto::of) + .collect(Collectors.toList()); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } +}