SpringBoot, JPA, H2 database ์…‹ํŒ…

๋ชฉํ‘œ

์ด๋ฒˆ ์‹œ๊ฐ„์—๋Š” SpringBoot, JPA, H2(DB)๋ฅผ ํ†ตํ•œ ๊ฐ„๋‹จํ•œ Member ์—”ํ‹ฐํ‹ฐ๋ฅผ ๋งŒ๋“ค๊ณ , Junit ํ…Œ์ŠคํŠธ๋กœ ๊ฒ€์ฆํ•˜๋Š” ์ƒ˜ํ”Œ ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์˜์กด์„ฑ ์ถ”๊ฐ€

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>runtime</scope>
</dependency>

spring-data-jpa ์™€ h2(์ธ๋ฉ”๋ชจ๋ฆฌ) ๋””ํŽœ๋˜์‹œ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

application.properties ์ถ”๊ฐ€

# H2 ์„ค์ •
spring.h2.console.enabled=true
spring.h2.console.path=/h2

# Datasource ์„ค์ •
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:test
spring.datasource.username=sa
spring.datasource.password=

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ํ•˜๊ณ , localhost:8080/h2 ์ฃผ์†Œ๋กœ ์ ‘์†ํ•˜๋ฉด, ์ธ๋ฉ”๋ชจ๋ฆฌ DB์ธ H2 ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌผ๋ก  ์ธ๋ฉ”๋ชจ๋ฆฌ ์ด๊ธฐ ๋•Œ๋ฌธ์— ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์žฌ ์‹คํ–‰ํ•˜๋ฉด ๋ฐ์ดํ„ฐ๊ฐ€ ๋‚ ๋ผ๊ฐ‘๋‹ˆ๋‹ค.(ํœ˜๋ฐœ์„ฑ ~ )

Member ์—”ํ‹ฐํ‹ฐ

@Data
@Table(name = "MEMBER")
@Entity
public class Member {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

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

    @Column(name = "AGE")
    private Integer age;

}

JpaRepository ๋ฅผ ์ƒ์† ๋ฐ›๋Š”๋‹ค.

@Repository
public interface MemberRepository extends JpaRepository<Member, Long> {
}

JpaRepository(์ธํ„ฐํŽ˜์ด์Šค)๋ฅผ ์ƒ์†๋ฐ›์Œ์œผ๋กœ์จ Jpa๊ฐ€ ๊ตฌํ˜„ํ•ด ๋†“์€ ๊ตฌํ˜„์ฒด ์ค‘์—์„œ SimpleJpaRepository๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ํ•ด๋‹น ํด๋ž˜์Šค๋Š” ๊ธฐ๋ณธ์ ์ธ CRUD ๋ฉ”์„œ๋“œ๋ฅผ ์ด๋ฏธ ๊ตฌํ˜„ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๋ฉด ๋งค์šฐ ํŽธ๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

## Hibernate
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

์ถ”๊ฐ€์ ์œผ๋กœ application.properties์— ์ฟผ๋ฆฌ๊ฐ€ ๋‚ ๋ผ๊ฐˆ ๋•Œ, console์— formatting๋œ sql๋ฌธ์„ ๋ณด๊ธฐ ์œ„ํ•ด์„œ ์„ค์ •์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ์ž‘์„ฑ

@RunWith(SpringRunner.class)
@SpringBootTest
@Rollback(false)
public class MemberServiceTests {

    @Autowired
    private MemberRepository memberRepository;

    @Test
    public void saveMemberTest() {

        //given
        Member member = new Member();
        member.setName("andrew");
        member.setAge(32);
        memberRepository.save(member);

        // when
        Member retrivedMember = memberRepository.findById(member.getId()).get();

        // then
        Assert.assertEquals(retrivedMember.getName(), "andrew");
        Assert.assertEquals(retrivedMember.getAge(), Integer.valueOf(32));
    }

์ด๋ฆ„๊ณผ ๋‚˜์ด๋ฅผ ๊ฐ–๋Š” Member๋ฅผ ์ €์žฅํ•˜๊ณ , DB๋กœ ๋ถ€ํ„ฐ ๋ถˆ๋Ÿฌ์˜ค๊ณ  ์กฐํšŒ ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ์กด์˜ ๋ฐ์ดํ„ฐ์™€ ๋น„๊ตํ•˜๋Š” ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค

Hibernate:
    drop table member if exists
Hibernate:
    drop sequence if exists hibernate_sequence
Hibernate: create sequence hibernate_sequence start with 1 increment by 1
Hibernate:

    create table member (
       id bigint not null,
        age integer,
        name varchar(255),
        primary key (id)
    )

์ฒ˜์Œ์— memberํ…Œ์ด๋ธ”์ด ์กด์žฌํ•˜๋ฉด ํ…Œ์ด๋ธ”์„ ์‚ญ์ œํ•˜๊ณ  ๋‹ค์‹œ ๋งŒ๋“œ๋Š” ์ฟผ๋ฆฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ์‹ ๊ธฐํ•œ๊ฒŒ application.properties์— spring.jpa.hibernate.ddl-auto=create-drop ์ด๋Ÿฐ ์˜ต์…˜์„ ์ฃผ์ง€ ์•Š์•˜์Œ์—๋„ H2 dbํŠน์„ฑ์ƒ(์ธ๋ฉ”๋ชจ๋ฆฌ) ๊ธฐ์กด์˜ ํ…Œ์ด๋ธ”์„ ์ „๋ถ€ ๋‚ ๋ฆฌ๊ณ  ๋‹ค์‹œ ์ƒ์„ฑํ•˜๋Š” ๊ฐ€ ๋ณด๋‹ค?

2020-01-09 ์ถ”๊ฐ€ ์„ค๋ช…,

Spring Boot chooses a default value for you based on whether it thinks your database is embedded (default create-drop) or not (default none).

Hibernate:
    insert
    into
        member
        (age, name, id)
    values
        (?, ?, ?)
Hibernate:
    select
        member0_.id as id1_0_0_,
        member0_.age as age2_0_0_,
        member0_.name as name3_0_0_
    from
        member member0_
    where
        member0_.id=?

์ฟผ๋ฆฌ๋ฅผ ํ™•์ธํ•ด ๋ณด๋ฉด, 1) ๋“ฑ๋ก ์ฟผ๋ฆฌ, 2) ์กฐํšŒ ์ฟผ๋ฆฌ ๋‘๊ฐœ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์—ฐ๊ด€ ํฌ์ŠคํŠธ