์คํ๋ง DB ์ ๊ทผ ๊ธฐ์
5. JPA
- JPA๋ ๊ธฐ์กด์ ๋ฐ๋ณต ์ฝ๋๋ ๋ฌผ๋ก ์ด๊ณ SQL๋ ์ง์ ๋ง๋ค์ด์ ์คํํด์ค๋ค.
- SQL๊ณผ ๋ฐ์ดํฐ ์ค์ฌ์ ์ค๊ณ์์ ๊ฐ์ฒด ์ค์ฌ์ ์ค๊ณ๋ก ํจ๋ฌ๋ค์์ ์ ํํ ์ ์๋ค.
- ๊ฐ๋ฐ ์์ฐ์ฑ์ ํฌ๊ฒ ๋์ผ ์ ์๋ค.
1) ํ๊ฒฝ ์ค์
- build.gradle ํ์ผ์ JPA, h2 ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ด๋ จ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ถ๊ฐ
- spring-boot-starter-data-jpa: ๋ด๋ถ์ jdbc ๊ด๋ จ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํฌํจํ๋ค. ๋ฐ๋ผ์ jdbc๋ ์ ๊ฑฐํด๋ ๋๋ค.
- ์คํ๋ง ๋ถํธ์ JPA ์ค์ ์ถ๊ฐ
- show-sql: JPA๊ฐ ์์ฑํ๋ SQL์ ์ถ๋ ฅํ๋ค.
- ddl-auto: JPA๋ ํ ์ด๋ธ์ ์๋์ผ๋ก ์์ฑํ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋๋ฐ none์ ํด๋น ๊ธฐ๋ฅ์ ๋๋ค. create๋ฅผ ์ฌ์ฉํ๋ฉด ์ํฐํฐ ์ ๋ณด๋ฅผ ๋ฐํ์ผ๋ก ํ ์ด๋ธ๋ ์ง์ ์์ฑํด์ค๋ค.
2) JPA ์ํฐํฐ ๋งคํ
- JPA๋ ์๋ฐ ํ์ค์์ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ์์ ์ ์ํ ์ธํฐํ์ด์ค์ด๋ค.
- JPA์ ๊ตฌํ์ฒด๋ก hibernate ๋ฑ์ด ์๊ณ ์ด ๊ตฌํ ๊ธฐ์ ์ ์ด์ฉํด JPA๋ฅผ ์ฌ์ฉํ๋ค.
- @Entity: JPA๊ฐ ๊ด๋ฆฌํ๋ ๊ฐ์ฒด๋ก ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํ ์ด๋ธ๊ณผ ๋งคํ(ORM)์ ๋์์ค๋ค.
package hello.hello.spring.domain;
import javax.persistence.*;
@Entity
public class Member {
@Id // ๊ธฐ๋ณธํค(pk)
@GeneratedValue(strategy = GenerationType.IDENTITY) // DB๊ฐ ์์ฑํ๋ key(id)๋ผ๋ ๋ป
private Long id; // ์์คํ
์ด ์ ์ฅํ ์์์ ๊ฐ
// @Column(name = "username"): ๋ง์ฝ DB์ ์ปฌ๋ผ ๋ช
์ด ๋ค๋ฅด๋ค๋ฉด ์ง์ ์ค์
private String name;
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;
}
}
3) ์๋น์ค ๊ณ์ธต์ ํธ๋์ญ์ ์ถ๊ฐ
- ์คํ๋ง์ ํด๋น ํด๋์ค์ ๋ฉ์๋๋ฅผ ์คํํ ๋ ํธ๋์ญ์ ์ ์์ํ๊ณ , ๋ฉ์๋๊ฐ ์ ์ ์ข ๋ฃ๋๋ฉด ํธ๋์ญ์ ์ ์ปค๋ฐํ๋ค. ๋ง์ฝ ๋ฐํ์ ์์ธ๊ฐ ๋ฐ์ํ๋ฉด ๋กค๋ฐฑํ๋ค.
- JPA๋ฅผ ํตํ ๋ชจ๋ ๋ฐ์ดํฐ ์ ์ฅ ๋ฐ ๋ณ๊ฒฝ์ ํธ๋์ญ์ ์์์ ์คํํด์ผ ํ๋ค
4) JPA ๋ฆฌํฌ์งํ ๋ฆฌ ๊ตฌํ
package hello.hello.spring.repository;
import hello.hello.spring.domain.Member;
import javax.persistence.EntityManager;
import java.util.List;
import java.util.Optional;
public class JpaMemberRepository implements MemberRepository {
private final EntityManager em;
public JpaMemberRepository(EntityManager em) {
this.em = em;
}
@Override
public Member save(Member member) {
// insert ์ฟผ๋ฆฌ, DB ์ ์ฅ, SetID ๋ฑ ๋ชจ๋ ๊ธฐ๋ฅ์ JPA๊ฐ ์ฒ๋ฆฌํ๋ค.
em.persist(member);
return member;
}
@Override
public Optional<Member> findById(Long id) {
Member member = em.find(Member.class, id);
return Optional.ofNullable(member);
}
@Override
public Optional<Member> findByName(String name) {
// pk ๊ธฐ๋ฐ์ด ์๋๋ผ ์ฟผ๋ฆฌ ์์ฑ์ด ํ์ํ๋ค.
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 List<Member> findAll() {
// ๊ฐ์ฒด(์ํฐํฐ) ์์ฒด๋ฅผ select ํ๋ค.
return em.createQuery("select m from Member m", Member.class)
.getResultList();
}
}
package hello.hello.spring;
import hello.hello.spring.repository.*;
import hello.hello.spring.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
@Configuration
public class SpringConfig {
private EntityManager em;
@Autowired
public SpringConfig(EntityManager em) {
this.em = em;
}
@Bean
public MemberService memberService() {
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
//return new MemoryMemberRepository();
//return new JdbcMemberRepository(dataSource);
//return new JdbcTemplateMemberRepository(dataSource);
return new JpaMemberRepository(em);
}
}