관심쟁이 영호

[#17] Spring Boot ㅣ JPA로 테이블에 insert하기 ㅣ 완성 코드 분석하기 본문

Bank-End/인프런- Spring 공부

[#17] Spring Boot ㅣ JPA로 테이블에 insert하기 ㅣ 완성 코드 분석하기

관심쟁이 영호 2021. 5. 1. 01:30
반응형

이전 시간에는 데이터베이스에 테이블을 어떻게 생성하는지 살펴보았다.

 

이번 시간에는 웹에서 데이터를 생성할 때를 살펴보자.

 

  • 회원가입을 해보자.

위 그림과 같이 생성했다.

"Submit" 버튼을 눌렀을 때, 어떤일이 일어날까!?

 

- 먼저 해당화면을 구성하는 html을 살펴보자.

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="fragments/header :: header" />
<style>
 .fieldError {
 border-color: #bd2130;
 }
</style>
<body>
<div class="container">
    <div th:replace="fragments/bodyHeader :: bodyHeader"/>
    <form role="form" action="/members/new" th:object="${memberForm}"
          method="post">
        <div class="form-group">
            <label th:for="name">이름</label>
            <input type="text" th:field="*{name}" class="form-control"
                   placeholder="이름을 입력하세요"
                   th:class="${#fields.hasErrors('name')}? 'form-control
fieldError' : 'form-control'">
            <p th:if="${#fields.hasErrors('name')}"
               th:errors="*{name}">Incorrect date</p>
        </div>
        <div class="form-group">
            <label th:for="city">도시</label>
            <input type="text" th:field="*{city}" class="form-control"
                   placeholder="도시를 입력하세요">
        </div>
        <div class="form-group">
            <label th:for="street">거리</label>
            <input type="text" th:field="*{street}" class="form-control"
                   placeholder="거리를 입력하세요">
        </div>
        <div class="form-group">
            <label th:for="zipcode">우편번호</label>
            <input type="text" th:field="*{zipcode}" class="form-control"
                   placeholder="우편번호를 입력하세요">
        </div>
        <button type="submit" class="btn btn-primary">Submit</button>
    </form>
    <br/>
    <div th:replace="fragments/footer :: footer" />
</div> <!-- /container -->
</body>
</html>

위와 같이 구성되었다.

여기서 <form>태그에 주목을 하면, 

"<form role="form" action="/members/new" th:object="${memberForm}" method="post">"

이렇게 코드가 짜여져 있다.

 

자세한 이해를 하고 싶다면, html의 form태그의 기능을 살펴보자!

action 으로 "/members/new"라고 적혀있다. "/members/new"라고 매핑이 되어있는 곳으로 해당 폼정보를 던진다는 뜻이다.

 

method는 폼정보를 post형태로 던진다는 뜻이다.

 

이렇게 던지면, MemberController에서 해당하는 요청 매핑이 된다.

아래의 매핑코드를 보자.

@PostMapping(value = "/members/new")
    public String create(@Valid MemberForm form, BindingResult result) {
        if (result.hasErrors()) {
            return "members/createMemberForm"; //에러가 있으면 BindingResult에서 스프링이 해당 값을 사용할 수 있도록 해준다.
        }
        Address address = new Address(form.getCity(), form.getStreet(),
                form.getZipcode());
        Member member = new Member();
        member.setName(form.getName());
        member.setAddress(address);
        memberService.join(member);
        return "redirect:/";
    }

 

해당 값으로 넘어온다.

파라미터로 "MemberForm form"이 넘어온다.

html에서 던져준 폼을 받은 것이다.

 

컨트롤러에서는 폼에서의 정보를 전부 member객체에 set해준다.

그리고 memberService의 join 메소드를 호출하여 set해준 member를 던져준다.

 

아래는 memberService 코드이다.

@Service
@Transactional(readOnly = true) //데이터 변경은 기본적으로 트랜잭션안에 있어야 한다.
@RequiredArgsConstructor // 자동 주입
public class MemberService {


    //@Autowird를 추가한다면,
    //EntityManager의 @PersistenceContext와 똑같이 자동 주입을 위함이겠지?
    // 스프링 Bean에 등록되어있는 MemberRepository를 주입해줄 것이다!!

    private final MemberRepository memberRepository;



    @Transactional
    //회원가입
    public Long join(Member member){

        validateDuplicateMember(member); //중복 회원 검증
        memberRepository.save(member);

        return member.getId();
    }
    
}

join을 받아서 중복회원을 검증하고, 영속성 컨텍스트를 관리하고있는 memberRepository에 던져준다.

 

※ validateDuplicateMember 안에 예외처리를 해두어서, 예외가 발생할 경우 save까지 넘어오지 않는다.

 

아래는 memberRepository이다.

@Repository
@RequiredArgsConstructor
public class MemberRepository {

     // @PersistenceContext // 1. JPA 사용 표준 어노테이션
    private final EntityManager em; // 2. 이렇게 해주면 스프링이 자동으로 엔티티 매니저를 만들어서 em에 주입시켜준다.

    public void save(Member member){ //저장
        em.persist(member);
    }
}

여기서 EntityManager 타입의 em이 있다.

이것을 통해서 우리는 영속성 컨텍스트를 다룰 수 있다.

 

여기까지 넘어온 member 객체는 모든 과정을 통과한 정보라서 DB에 저장해주어도 된다.

em.persist를 통해서 영속성 컨텍스트에 추가해준다.

 

이렇게하면 JPA가 알아서 해당 객체를 테이블에 매칭하여 추가해준다.

 

이것뿐만 아니라, 다른 "item" 항목에도 해당하는 로직과 똑같다.

 

그럼 이 다음에는 주문에 해당하는 로직을 살펴보자.

 

 

 

 

300x250
Comments