본문 바로가기

개발일지/Spring

[Spring] 스프링 입문 - JPA

JPA

JPA를 

쓰는 걸까?
  • 기존 반복 코드, 기본적인 SQL 까지 JPA가 직접 만들어서 실행해준다
  • SQL, 데이터 중심 설계에서 객체 중심 설계로 패러다임 전환
  • 개발 생산성을 크게 높일 수 있다

 

 

application.properties 설정

spring.jap.show-sql=true
spring.jpa.hibernate.ddl-auto=none

위의 세팅을 해준다

 

 

ORM

O : 객체

R : 관계형 데이터베이스

M : 매핑

객체와 관계형 데이터베이스를 매핑한다!

 

💡 매핑을 위해 Entity 어노테이션 사용
@Entity
public class Member {

Member는 JPA에서 관리하는 엔티티가 된다

 

 

PK 매핑

쿼리에 id를 넣는 것이 아니라,

DB에 값을 넣으면 DB가 자동으로 id를 생성한다

identity 전략

@Id @GeneratedValue(strategy = GenerationType.IDENTITY)

IDENTITY 전략 사용

 

 

Name 매핑

@Column(name = "username")
    private String name;

DB의 username과 매핑된다

 

 

JPA 리포지토리를 생성하자

1. EntityManager 생성

JPA는 EntityManager로 모든 것이 동작한다

즉, JPA를 쓰려면 EntityManager를 주입 받아야 한다!

private final EntityManager em;

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

 

2. save

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

persist 함수만 쓰면 끝 !

persist() ⇒ 영구 저장하겠다 라는 뜻

JPA가 insert 쿼리 만들어서 DB에 넣고 setId까지 해준다 ! 너무나도 편리

 

3. find

@Override
    public Optional<Member> findById(Long id) {
        Member member = em.find(Member.class, id);
        return Optional.ofNullable(member);
    }

PK 조회하기!
JPA가 select 쿼리 만들어서 조회, 리턴 할 때는 Optional로! 값이 없을 수도 있으니..

 

PK가 아닌 값을 조회하려면..

JPQL이라는 객체 지향 쿼리 언어를 사용해야 한다!

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

SQL과 비슷하지만, 테이블을 대상으로 쿼리를 날리는 게 아니라 객체(Entity)를 대상으로 쿼리를 날린다

객체 자체를 select! select m id, name 값 매핑을 할 필요가 없다

@Override
    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();
    }

위 코드도 마찬가지로,

pk가 아닌 name값을 찾는 것이다

JPQL 사용!

 

 

JPA를 사용하려면 트랜잭션이 있어야 한다 !

 

데이터를 저장하거나 변경할 때는 트랜잭션이 있어야 한다

@Transactional
public class MemberService {

 

4. Entity 매니저 불러오기

@Configuration
public class SpringConfig {

    private EntityManager em;

    @Autowired
    public SpringConfig(EntityManager em) {
        this.em = em;
    }

매니저를 불러오고, 빈 설정

@Bean
    public MemberRepository memberRepository() {
        return new JpaMemberRepository(em);
    }

 

 

스프링 데이터 JPA

스프링 부트 + JPA 만으로도 개발 생산성이 많이 증가한다

스프링 JPA를 사용하면, 인터페이스 만으로 개발이 가능하다!

 

인터페이스 설정만 하면 끝

public interface SpringDataJpaMemberRepository extends JpaRepository<Member, Long>, MemberRepository {
    @Override
    Optional<Member> findByName(String name);
}

스프링 데이터 JPA의 JpaRepository에서 기본적으로 findAll, save 등이 제공된다

@Configuration
public class SpringConfig {
    private final MemberRepository memberRepository;

    @Autowired
    public SpringConfig(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }

    @Bean
    public MemberService memberService() {
        return new MemberService(memberRepository);
    }

//    @Bean
//    public MemberRepository memberRepository() {
//        return new JdbcMemberRepository(dataSource);
//        return new JdbcTemplateMemberRepository(dataSource);
//        return new JpaMemberRepository(em);
//    }
}

스프링 데이터 JPA가 SpringDataJpaMemberRepository 인터페이스를 보고

스프링 빈을 자동으로 만든다! 객체를 생성하고, 스프링 빈에 올린다

 

 

 

💡 JPQL select m from Member m where m.name = ?

위의 쿼리를 해석해서,

findByName, finByNameAndId 와 같이

메서드 이름 만으로도 조회를 할 수 있다


@참고자료

[인프런] 김영한 - 스프링 입문 강의 (무료)