SWLUG(2026)/유지보수

[4주차] member entity, order entity, cart entity 설계 / 포스트맨 실습

batterygj 2026. 5. 10. 19:00

1. Member Entity 설계

member.json 코드

@Entity  // JPA 엔티티임을 선언(자바클래스를 DB테이블로 인식시킴)
@Table(name="member") // 엔티티 클래스가 데이터베이스의 member테이블과 매핑되도록 명시
@Getter @Setter  // 자바빈즈 패턴에 따라 필드에 접근하고 값을 수정할 수 있는 메서드를 컴파일 시점에 자동 생성
public class Member {
    @Id // 해당 필드(Id)를 테이블의 Primary Key(기본키)로 지정
    @Column(name="member_id")  //실제 데이터베이스 테이블의 컬럼명을 member_id로 매핑
    @GeneratedValue(strategy = GenerationType.IDENTITY) // 기본키 생성전략 설정. IDENTITY는 기본키 생성을 DB에 위임하는 방식
    private Long id;

    private String name; // 별도의 어노테이션이 없으면 필드명이 그대로 테이블의 컬럼명으로 매핑됨
    @Column(unique=true) // 바로 아래에 있는 필드에만 unique 제약조건을 걺. 여기서는 중복 이메일값 들어오는 것 방지
    private String email;
    private String password;
    private String address;

    @Enumerated(EnumType.STRING) // 자바의 Enum 타입을 문자열로 데이터베이스에 저장(ENUM 순서가 바뀌어도 데이터 꼬이지 않음)
    private Role role;

    @CreatedDate // 엔티티가 생성되어 저장될 때의 시간을 자동으로 주입
    private LocalDateTime createdBy;
    @LastModifiedDate // 엔티티값을 변경할 때 마지막으로 수정된 시간을 자동으로 업데이트
    private LocalDateTime modifiedBy;

 

 

constant/Role 코드

public enum Role {
    USER, ADMIN
}

->  프로젝트 전체에서 공통으로 사용할 상태값 정의. USER, ADMIN 두 종류의 상태값을 사용한다는 선언

 

+) enum : enumeration. 관련된 상수(정해진 값)들을 모아놓은 특별한 클래스임을 선언

Role: 이 열거형의 이름

 


2. Order Entity 설계

@Entity // 자바클래스를 DB테이블로 인식시킴
@Table(name="orders") // DB에 생성될 테이블의 이름을 orders로 지정
@Getter  // 클래스 상단에 private Long id; 이런 어노테이션 있으면 컴파일 시점에 getId() 자동 생성
public class Order {
    @Id // Id가 이 테이블의 PK
    @Column(name="order_id") // 객체 변수명은 id이지만 DB 컬럼명은 order_id로 씀
    @GeneratedValue(strategy = GenerationType.IDENTITY) // PK생성 권한을 DB에 넘김
    private Long id;

    @ManyToOne // 다대일관계
    @JoinColumn(name="member_id")  // 이 설정이 적힌 orders 테이블에 member_id라는 이름의 컬럼이 생성됨. member 테이블의 PK값 저장
    private Member member;
}

+) Order 객체 입장에서 여러주문이 한명의 회원에게 연결되므로 다대일 관계

FK : 외부 키


3. Car Entity 설계

@Entity
@Table(name="carts")  // DB에 생성될 테이블이름을 carts로 지정
@Getter // 모든 필드에 대해 데이터를 읽는 메서드를 자동 생성
@Setter // 모든 필드에 대해 데이터를 수정하는 메서드를 자동 생성
public class Cart {
    @Id
    @Column(name="cart_id")  // 실제 DB컬럼명을 cart_id로 매핑
    @GeneratedValue(strategy=GenerationType.IDENTITY)  // PK 생성방식 DB에 위임
    private Long id;

    @ManyToOne  // 다대일관계(한 회원이 여러 시점의 장바구니를 가질 수 있음)
    @JoinColumn(name="member_id")  // carts 테이블 안에 member_id라는 외래 키(FK) 컬럼을 만듦. 이 컬럼이 Member 테이블의 PK와 연결되는 통로가 됨
    private Member member;

    @CreatedDate  // 장바구니가 처음 생성된 시간을 createBy 필드에 자동 기록
    private LocalDateTime createdBy; 
    @LastModifiedDate  // 장바구니 정보가 마지막으로 수정된 시간을 modifiedBy 필드에 자동 기록
    private LocalDateTime modifiedBy;
}

 

 

 


DB 확인

mysql -u root -p

show databases;

use swlug26test;

show tables;

desc [table명];

 


member service 

@Service // 비즈니스로직을 수행하는 서비스 객체임
@RequiredArgsConstructor // 의존성 주입을 위함. final이 붙은 필드를 매개변수로 갖는 생성자를 자동으로 만듦
public class MemberService {

    private final MemberRepository memberRepository; // 서비스가 DB에 접근하기 위해 사용하는 도구

    // CREATE
    public Member save(Member member) {  // 1.저장할 회원 정보를 담은 member객체를 외부로부터 받음
        member.setCreatedBy(LocalDateTime.now());  // 2.엔티티의 시간필드에 현재 시간을 대입하여 가공
        return memberRepository.save(member); // 3.가공된 데이터를 DB에 저장
    }

    // READ (전체 조회)
    public List<Member> findAll() {  // DB에 저장된 회원정보를 모두 찾아 list로 반환
        return memberRepository.findAll(); //3.모든 데이터를 다 가져옴
    }

    // READ (단건 조회)
    public Member findById(Long id) {
        return memberRepository.findById(id)
                .orElseThrow(() -> new IllegalArgumentException("회원 없음"));
    } // 2.DB에서 찾았는데 없으면 에러를 발생시키는 예외처리 로직 수행 3.특정 ID데이터 찾아서 가져옴

    // UPDATE
    public Member update(Long id, Member updatedMember) { //1.누구(id)를 무엇으로(updateMember)로 고칠지 입력받음
        Member member = findById(id); //2.기존데이터를 DB에서 먼저 꺼내서
        member.setName(updatedMember.getName());
        member.setEmail(updatedMember.getEmail());
        member.setAddress(updatedMember.getAddress());
        member.setPassword(updatedMember.getPassword());
        member.setRole(updatedMember.getRole());
        member.setModifiedBy(LocalDateTime.now()); // 2.원본 객체(member)에 새로운 정보들을 하나씩 대입(수정)
        return memberRepository.save(member);  // 3.수정이 끝난 객체를 다시저장하여 DB 업데이트
    }

    // DELETE
    public void delete(Long id) {  // 지우고 싶은 회원 id를 받음
        memberRepository.deleteById(id);  // 해당 id의 데이터를 삭제
    }

+) private final MemberRepository memberRepository; 에서 final

: 서비스가 작동하는 동안 이 도구가 바뀌지 않도록 안전하게 고정

 

+) 서비스의 역할(3단계흐름)

1. 데이터 수령(매개변수로 값을 받음)

2. 로직 처리(데이터 가공 및 검증)

3. Repository 명령(DB작업 수행 요청)


member repository 

: 회원정보를 다루는 기본 도구들을 상속받으면서, 이메일로 회원을 찾는 기능을 추가한 인터페이스

public interface MemberRepository extends JpaRepository<Member, Long> {
    Optional<Member> findByEmail(String email);
}

extends JpaRepository<Member, Long> : member service에서 썼던 save(), findAll(), findById() 등의 기본 기능을 

바로 사용 가능

Optional<Member> findByEmail(String email)  :  이메일로 회원을 찾았을 때 존재하면 그 회원을 돌려주지만, 없으면 비어있는 상태로 돌려주어 에러(Nullpointerexception을 안전하게 방지)

 


member controller 

@RestController  // 응답을 HTML형태가 아닌 JSON형태로 주겠다고 선언
@RequiredArgsConstructor  // 서비스(memberService)를 자동으로 연결해줌
@RequestMapping("/members")  // 이 클래스의 모든 기능은 /members 주소로 시작
public class MemberController {

    private final MemberService memberService;

    // CREATE
    @PostMapping  // HTTP POST 요청 (데이터 등록 시 사용)
    public Member create(@RequestBody Member member) {
        // @RequestBody: 사용자가 보낸 JSON 데이터를 객체로 변환해서 받음
        return memberService.save(member);
    }

    // READ (전체)
    @GetMapping // HTTP GET 요청 (데이터 조회 시 사용)
    public List<Member> getAll() {
        return memberService.findAll();
    }

    // READ (단건)
    @GetMapping("/{id}")
    public Member getOne(@PathVariable Long id) {  // 주소창에 적힌 {id} 숫자를 변수로 받음
        return memberService.findById(id);  // id로 회원을 찾아 정보를 반환
    }

    // UPDATE
    @PutMapping("/{id}") // HTTP PUT 요청 (데이터 수정 시 사용)
    public Member update(@PathVariable Long id, @RequestBody Member member) {
        return memberService.update(id, member);
    } // 누구(id), 어떻게 고칠지(member)를 동시에 받아 update를 실행해 수정완료된 객체 전송

    // DELETE
    @DeleteMapping("/{id}")  // HTTP DELETE 요청 (데이터 삭제 시 사용)
    public String delete(@PathVariable Long id) {
        memberService.delete(id);
        return "삭제 완료";
    }
}

 


포스트맨 실습

-> Intelli J 실행한채로 포스트맨 실행

package com.swlug26test.shop;

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

@SpringBootApplication
public class ShopApplication {

	public static void main(String[] args) {
		SpringApplication.run(ShopApplication.class, args); //실제 서버를 구동시키는 명령
	} // Spring 로고가 뜨고, 8080 포트가 열리면서 포스트맨의 요청을 받을 준비가 됨

}

- 회원 생성 ( POST http://localhost:8080/members )

 

1. controller : 회원 생성 요청을 인식하고 사용자가 JSON으로 보낸 데이터를 자바 객체로 변환해서 받음

(@PostMapping, @RequestBoy가 담당)

 

2. entity : 회원 데이터가 DB에 어떤 형태로 쌓일지 정의한 클래스

 

3. service : 필요한 데이터 가공

(modifyedBy, createdBy를 LocalDateTime.now()로 세팅)

 

4. repository : 자바 객체를 DB가 알아들을 수 있는 SQL로 바꿔 전달

 

 


- 전체 조회 ( GET  http://localhost:8080/members )

 

1. controller : service에게 목록을 가져오라 명령. 결과물인 list를 json형태로 바꿔 응답

 

2. entity : DB에서 꺼내온 수많은 데이터를 자바 객체(Member)형태로 담음

 

3. service : repository가 가져온 데이터를 컨트롤러에게 전달(필요시 목록을 전달하거나 필터링하는 로직을 넣음)

 

4. repository : findAll() 메서드를 통해 DB에 SELECT * 쿼리를 보내 모든 회원 정보를 가져옴


 

- 단건 조회 ( GET  http://localhost:8080/members/1 )

 

1. controller : URL 끝에 붙은 /1을 @PathVariable로 추출해 특정 id값을 service에 전달

 

2. entity : 찾으려는 딱 한명의 정보만 담은 객체가 됨

 

3. service : repository의 fiindById를 호출. 해당id가 없으면 회원 없음 같은 예외 처리 수행

 

4. repository : DB에서 해당 id를 가진 행 하나만 가져옴


 

- 수정 ( PUT  http://localhost:8080/members/1 )

 

1. controller : PUT메서드와 수정할 데이터, 타겟 id(/1)를 동시에 받아 service에 넘김

 

2. entity : 기존 데이터를 불러와서 새로운 값으로 덮어쓰기 당함

 

3. service : 기존 데이터를 DB에서 꺼냄

-> 꺼낸 데이터에 새로운 값을 set

-> setModifiedBy(LocalDateTime.now())를 실행해 수정 시각 기록

 

4. repository : 수정된 객체를 다시 DB에 반영


 

- 삭제 ( DELETE  http://localhost:8080/members/1 )

 

1. controller : DELETE 신호를 받고 작업이 끝나면 사용자에게 '삭제 완료'라는 문자열 메시지 보냄

 

2. entity : DB에서 영구적으로 지워질 대상

 

3. service : repository의 deleteById를 호출해 삭제 명령

 

4. repository : DB에 DELETE FROM ... 쿼리를 보내 해당 데이터를 삭제