Spring 사용하기 (Coupon_check 백엔드(6-3) - DB JPA)

김태훈·2022년 12월 31일
0

Spring_CouponCheck

목록 보기
13/14

기존 Jdbc Template의 특징은 물론, JPA 는 SQL마저 직접 작성해준다.

1. JPA 라이브러리 추가

build.gradle에 더이상 'jdbc'는 없어도 된다.
jpa를 추가시키자.

implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

그 후,properties에도 설정을 추가한다.

spring.jpa.show-sql=true

이렇게 하면, JPA가 만든 SQL을 직접 볼 수가 있다.
추가로,

spring.jpa.hibernate.ddl-auto=none

JPA는 객체를 보고, 테이블을 다 만들어버린다. 하지만 우리는 이미 테이블을 작성한 상태이므로, 해당 기능을 꺼준다.

2. 객체, ORM(Object Relation Mapping)

객체와 relation database table을 mapping 하는 것이 JPA이다.
이를 위해선 Mapping Annotation (@Entity)를 추가한다.

Member 클래스에 해당 어노테이션을 추가하자.

package Goat.CouponCheck.domain;

import jakarta.persistence.*;

@Entity
public class Member {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id; //임의의 값, 데이터 구분을 위함.
    @Column(name="Name")
    private String name;
    @Column(name="coupon")
    private Integer couponNum;
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getCouponNum() {
        return couponNum;
    }

    public void setCouponNum(Integer couponNum) {
        this.couponNum = couponNum;
    }
}

PK인 ID는 자동으로 생성해주므로, @ID라는 어노테이션과, @GeneratedValue라는 어노테이션을 함께 id앞에 붙여준다.
마찬가지로 다른 DB들도 JPA가 자동으로 관리할 수 있게끔 명시하는 Annotation을 작성한다.

3. JpaRepository 만들기

JPA는 EntityManager로 동작한다.
Spring Boot가 gradle에서 build 되어질 때, 자동으로 EntityManager를 생성하고, 우리는 이를 그저 가져다 쓰면 된다.(Injection)

package Goat.CouponCheck.repository;

import Goat.CouponCheck.domain.Coupon;
import Goat.CouponCheck.domain.Member;
import jakarta.persistence.EntityManager;

import java.util.List;
import java.util.Optional;

public class JpaRepository implements Repository{
    private final EntityManager em;

    public JpaRepository(EntityManager em) {
        this.em = em;
    }

    @Override
    public Member saveMember(Member member) {
        em.persist(member);
        return member;
    }

    public Optional<Member> findById(Long id) {
        Member member = em.find(Member.class, id);
        return Optional.ofNullable(member);
    }
    public List<Member> findAll() {
        return em.createQuery("select m from Member m", Member.class)
                .getResultList();
    }
    public Optional<Member> findByName(String name) {
        List<Member> result = em.createQuery("select m from Member m where m.name = :name", Member.class)
                .setParameter("name", name)
                .getResultList();
        return result.stream().findAny();
    }
}

    @Override
    public Optional<Integer> saveCoupon(Coupon coupon) {
        return Optional.empty();
    }
}

객체 지향이라 불리우는 이유?

public List<Member> findAll() {
	return em.createQuery("select m from Member m", Member.class)
    	.getResultList();
}

해당 코드를 보면 Member m에서 select m을 뽑는다.
원래 sql같은 경우에는 모든 column name들을 다 뽑아야 하겠지만, 이처럼 객체 자체를 뽑아온 다는 점에서 유용하다.

SpringConfig 수정

package Goat.CouponCheck;

import Goat.CouponCheck.repository.JpaRepository;
import Goat.CouponCheck.repository.Repository;
import Goat.CouponCheck.service.MemberService;
import jakarta.persistence.EntityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;

@Configuration
public class SpringConfig {
//    private DataSource dataSource;
    private EntityManager em;
    @Autowired
//    public SpringConfig(DataSource dataSource) {
//        this.dataSource = dataSource;
//    }
    public SpringConfig(EntityManager em){
        this.em = em;
    }
    @Bean
    public MemberService memberService(){
        return new MemberService(repository());
    }

    @Bean
    public Repository repository(){

//        return new MemoryRepository();
//        return new JdbcRepository(dataSource);
//        return new JdbcTemplateRepository(dataSource);
        return new JpaRepository(em)
    }

}

이전 상황들과 별개로, Jpa는 DataSource가 아닌 EntityManager를 사용하므로 해당 객체를 가져와서 파라미터로 넘겨주자.

profile
기록하고, 공유합시다

0개의 댓글