Post

[Spring/Database] Spring JPA์™€ Spring Data JPA

โœ… ๐Ÿ๏ธ Fairy-Tale Island ๐Ÿ๏ธ ๋ฆฌํŒฉํ† ๋ง!

Spring Database ์ ‘๊ทผ ๋ฐฉ์‹

Spring์—์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ์‹๋“ค์„ ์•Œ์•„๋ณธ๋‹ค. ORM ์ด์ „์˜ ์ ‘๊ทผ ๋ฐฉ๋ฒ•๋“ค๊ณผ ๋‹จ์ ์„ ์•Œ์•„๋ณด๊ณ , ์ด๋ฅผ ๋ณด์™„ํ•˜๊ธฐ ์œ„ํ•ด ๋“ฑ์žฅํ•œ ORM์˜ ๊ฐœ๋…๊ณผ Spring์—์„œ ์‚ฌ์šฉํ•˜๋Š” Java ORM ๊ธฐ์ˆ ์„ ์•Œ์•„๋ณธ๋‹ค.

#1 [Database] ORM ์ •์˜, ๋“ฑ์žฅ ๋ฐฐ๊ฒฝ, ์žฅ๋‹จ์ 

#2 [Spring/Database] JDBC์™€ JDBCTemplate

#3 [NOW] [Spring/Database] Spring JPA์™€ Spring Data JPA

#4 ์ „์ฒด ์ฝ”๋“œ ์ €์žฅ์†Œ : Various way of Spring Database Access


๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ ‘๊ทผ : Spring JPA

JPA(Java Persistence API)๋Š” Java ORM ๊ธฐ์ˆ ์— ๋Œ€ํ•œ API ํ‘œ์ค€ ๋ช…์„ธ ์ธํ„ฐํŽ˜์ด์Šค์ด๋‹ค. ์ •์˜์—์„œ ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด, ํŠน์ • ๊ธฐ๋Šฅ์„ ํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์•„๋‹ˆ๋ผ, ์ธํ„ฐํŽ˜์ด์Šค์ด๋‹ค. ๋‹จ์ˆœํžˆ Java ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ •์˜ํ•œ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์—, ๊ตฌํ˜„์ด ์•„๋‹ˆ๋‹ค. Hibernate์™€ ๊ฐ™์€ ORM ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์ด์šฉ ๊ฐ€๋Šฅํ•œ ๊ณตํ†ต API๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

Java์—์„œ ์ธํ„ฐํŽ˜์ด์Šค : ๊ตฌํ˜„์ฒด ๊ด€๊ณ„์ฒ˜๋Ÿผ, JPA : Hibernate๋„ ์ธํ„ฐํŽ˜์ด์Šค์™€ ๊ตฌํ˜„์ฒด ๊ด€๊ณ„๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค. Java ORM ๊ธฐ์ˆ ์— ๋Œ€ํ•œ ๋ช…์„ธ๋ฅผ ํ–ˆ์œผ๋ฏ€๋กœ, ORM์˜ ์žฅ์ ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ์ฆ‰, Hibernate๊ฐ€ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด Java์—์„œ Entity์˜ attribute๋ฅผ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค Table์˜ Column๊ณผ ๋งคํ•‘์„ ์ง€์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ๊ฐœ๋ฐœ์ž๊ฐ€ ์ผ์ผ์ด ๋งคํ•‘์„ ์œ„ํ•ด SQL๋ฌธ์„ ์ž‘์„ฑํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.

Spring JPA ์‚ฌ์šฉ ๋ฐฉ๋ฒ•

build.gradle์— ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

1
2
3
4
5
6
7
dependencies {
    ...

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

    ...
}


Spring JPA๋Š” EntityManager ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•œ๋‹ค. EntityManger๋„ JPA์—์„œ ์ •์˜๋œ ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ผ๋ถ€์ด๊ณ , ๋ช…์‹œ์ ์œผ๋กœ Java์— ๋“ฑ๋ก๋œ ๊ฐ์ฒด๋ฅผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ์™€ ๋งคํ•‘ํ•œ๋‹ค. JpaMemberRepository์—์„œ EntityManager ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ์ž์— ์ฃผ์ž… ๋ฐ›์•„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

๋ช…์‹œ์ ์œผ๋กœ ๊ฐ์ฒด๋ฅผ ๋“ฑ๋กํ•˜๋ ค๋ฉด, ๋„๋ฉ”์ธ์— @Entity ์–ด๋…ธํ…Œ์ด์…˜์„ ๋‹ฌ์•„์ค€๋‹ค. EntityManager๋Š” @Entity ์–ด๋…ธํ…Œ์ด์…˜์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฐ์ฒด๋“ค์„ ๊ด€๋ฆฌํ•˜๊ณ , ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ…Œ์ด๋ธ”๊ณผ ๋งคํ•‘ํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ Create / Update / Save ํ•˜๋Š” ๊ธฐ๋Šฅ๋“ค์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

(์—ฌ๊ธฐ์„œ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ‘๊ทผํ•˜๋Š” ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•๋“ค์„ ์†Œ๊ฐœํ•˜๋Š”๋ฐ ์ค‘์ ์„ ๋‘๋ฏ€๋กœ, Spring JPA์˜ EntityManager์— ๋Œ€ํ•ด์„œ๋Š” ๋‹ค๋ฅธ ๊ธ€์—์„œ ์ž์„ธํžˆ ๋‹ค๋ฃจ๊ฒ ๋‹ค.)

1
2
3
4
5
6
7
8
9
10
@Entity
public class Member {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    ...
}

์•ž์„  ์ˆœ์ˆ˜ JDBC, JDBCTemplate์—์„œ๋Š” ์ฝ”๋“œ๊ฐ€ ๋„ˆ๋ฌด ๊ธธ์–ด ๋ฉ”์„œ๋“œ ํ•˜๋‚˜, ๋‘ ๊ฐœ๋งŒ ์ฒจ๋ถ€ํ•˜์˜€๋‹ค. ํ•˜์ง€๋งŒ Spring JPA ์‚ฌ์šฉํ•˜๋ฉด, ๋„ค ๊ฐœ ๋ฉ”์„œ๋“œ ์ฝ”๋“œ๋ฅผ ์ „๋ถ€ ์ฒจ๋ถ€ํ•  ์ˆ˜ ์žˆ์„ ์ •๋„๋กœ ์ฝ”๋“œ๊ฐ€ ๊ฐ„๊ฒฐํ•˜๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class JpaMemberRepository implements MemberRepository {

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

    public Member save(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();
    }
}

์ด์ „ JDBCTemplate์—์„œ๋Š” ๋ฐ˜๋ณต์ ์ธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์ง€ ์•Š์•„๋„ ๋˜์—ˆ์ง€๋งŒ, SQL๋ฌธ์€ ์ง์ ‘ ์ž‘์„ฑํ•ด์•ผ ํ–ˆ๋‹ค. Spring JPA์—์„œ๋Š” SQL๋ฌธ๋„ ์ž๋™์œผ๋กœ ์ž‘์„ฑํ•œ๋‹ค. ํ•˜์ง€๋งŒ findAll, findByName์„ ๋ณด๋ฉด ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด, ๋ชจ๋“  ๊ฒƒ์„ JPA๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.

๊ฐœ๋ฐœ์„ ํ•˜๋‹ค๋ณด๋ฉด JPA์˜ Query Method ๋งŒ์œผ๋กœ๋Š” ์กฐํšŒ๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ๊ฐ€ ์กด์žฌํ•œ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ JPQL(Java Persistence Query Language)๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

(EntityManager์˜ createQuery๋ฅผ ์ด์šฉํ•˜๋Š” ๋ฐฉ๋ฒ• ์™ธ ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์ด ์กด์žฌํ•˜๋Š”๋ฐ, ์ด๋Š” ๋‹ค๋ฅธ ๊ธ€์—์„œ ์ž์„ธํžˆ ์†Œ๊ฐœํ•˜๋„๋ก ํ•˜๊ฒ ๋‹ค.)


๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ ‘๊ทผ : Spring Data JPA

Spring Data JPA ์‚ฌ์šฉ ๋ฐฉ๋ฒ•

Spring JPA์™€ ๊ฐ™์€ ํ™˜๊ฒฝ์„ค์ •์ด๋‹ค. build.gradle์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•œ๋‹ค.

์•ž์„  Spring JPA๋งŒ ์‚ฌ์šฉํ•ด๋„ SQL๋ฌธ์„ ์ง์ ‘ ์ž‘์„ฑํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งค์šฐ ์ค„์–ด๋“ค๊ณ , ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ๋„ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ๊ฐœ๋ฐœ์— ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์—ฌ๊ธฐ์— ์ถ”๊ฐ€์ ์œผ๋กœ Spring Data JPA๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, ๊ตฌํ˜„์ฒด ์—†์ด ์ธํ„ฐํŽ˜์ด์Šค๋งŒ์œผ๋กœ ๊ฐœ๋ฐœ์„ ์™„๋ฃŒํ•  ์ˆ˜ ์žˆ๋‹ค!

์•„๋ž˜ ์ฝ”๋“œ๊ฐ€ ์ •๋ง ๊ตฌํ˜„์˜ ์ „๋ถ€์ด๋‹ค!!

1
2
3
4
5
public interface SpringDataJpaMemberRepository extends JpaRepository<Member, Long>, MemberRepository {

    Optional<Member> findByName(String name);
}

Spring Data JPA๋Š” ์–ด๋–ป๊ฒŒ ์ธํ„ฐํŽ˜์ด์Šค๋งŒ์œผ๋กœ ๊ฐœ๋ฐœ์„ ์™„๋ฃŒํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ผ๊นŒ? ์•„๋ž˜ ๊ทธ๋ฆผ์˜ 4๊ฐ€์ง€ ์š”์†Œ๋Š” ๋ชจ๋‘ ์ธํ„ฐํŽ˜์ด์Šค์ด๋‹ค. JpaRepository ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์Šคํ”„๋ง ๋ฐ์ดํ„ฐ JPA์—์„œ, PagingAndSortingReposiroty / CrudRepository / Repository ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์Šคํ”„๋ง ๋ฐ์ดํ„ฐ์—์„œ ์ œ๊ณตํ•œ๋‹ค. ๊ฐ€์žฅ ์•„๋ž˜์˜ JpaRepository์—์„œ ์ œ๊ณตํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์กด์žฌํ•˜๋ฏ€๋กœ, ์ด๋ฅผ ์ด์šฉํ•ด ์งœ์•ผ ํ•  ์ฝ”๋“œ๋ฅผ ํ™• ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.

Untitled

Spring์œผ๋กœ ๊ฐœ๋ฐœํ•˜๋ฉด์„œ ์•ž์„  Spring JPA์—์„œ ๋“ฑ์žฅํ•œ EntityManager๋ฅผ ์ง์ ‘ ๋‹ค๋ฃจ์ง€ ์•Š์•˜์—ˆ๋‹ค. ๋ถ„๋ช… ORM์œผ๋กœ JPA๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์—ˆ๋Š”๋ฐ, ์ง์ ‘ ๋‹ค๋ฃฐ ์ผ์ด ์™œ ์—†์„๊นŒ ์ƒ๊ฐํ•ด๋ณด๋‹ˆ, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ‘๊ทผํ•˜๋Š” ์ƒํ™ฉ์—์„œ Repository๋ฅผ ์ •์˜ํ•ด์„œ ์ ‘๊ทผํ–ˆ๊ธฐ ๋–„๋ฌธ์ด๋‹ค!

Spring Data JPA๋Š” JPA์— ์ถ”๊ฐ€์ ์ธ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ด ๊ฐœ๋ฐœ์„ ๊ฐ„ํŽธํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ/ํ”„๋ ˆ์ž„์›Œํฌ์ด๋‹ค. ์ด๋Š” Repository ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•จ์œผ๋กœ์จ ์ด๋ฃจ์–ด์ง„๋‹ค! Spring Data Jpa๊ฐ€ ๊ถ๊ทน์ ์œผ๋กœ ์ œ๊ณตํ•˜๋Š”, ๊ฐ€์žฅ ์œ— ๋‹จ์˜ Repository ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ด์šฉํ•จ์œผ๋กœ์จ JPA ๊ธฐ๋ฐ˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ์„ ๊ฐ„ํŽธํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ์—ˆ๋˜ ๊ฒƒ์ด๋‹ค.

๊ฐœ๋ฐœํ•˜๋ฉด์„œ Repository ์ธํ„ฐํŽ˜์ด์Šค์— ์ •์˜๋œ ๋Œ€๋กœ ์ฝ”๋“œ๋ฅผ ์งœ๋ฉด, Spring์ด ์•Œ์•„์„œ ๋ฉ”์„œ๋“œ ์ด๋ฆ„์— ์ ํ•ฉํ•œ ์ฟผ๋ฆฌ๋ฅผ ๋ณด๋‚ด๋Š” ๊ตฌํ˜„์ฒด๋ฅผ ๋งŒ๋“ค์–ด์„œ Bean์œผ๋กœ ๋“ฑ๋กํ•œ๋‹ค. ๊ทธ๋ฆผ์—์„œ Repository ์ธํ„ฐํŽ˜์ด์Šค์™€ JpaRepository ์ธํ„ฐํŽ˜์ด์Šค ์‚ฌ์ด์— ์žˆ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋“ค์„ ํ†ตํ•ด์„œ CRUD ์—ฐ์‚ฐ, ํŽ˜์ด์ง•, ์ •๋ ฌ์„ ์‰ฝ๊ฒŒ ํ•  ์ˆ˜ ์žˆ๊ณ , ์ฝ”๋“œ์˜ ์–‘์„ ํš๊ธฐ์ ์œผ๋กœ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.

์ด๋ฏธ์ง€ ์ถœ์ฒ˜

This post is licensed under CC BY 4.0 by the author.