JPA

2023. 5. 2. 14:31카테고리 없음

build.gradle 파일에 JPA, h2 데이터베이스 관련 라이브러리 추가

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
//implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'com.h2database:h2'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}

스프링 부트에 JPA 설정 추가(application.properties)

spring.datasource.url=jdbc:h2:tcp://localhost/~/test
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=none

JPA 엔티티 매핑

package com.example.demo.domain;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;

//orm object relational mapping
@Entity // 약간 자바에서 class 같은 역할. db에는 table로 바꾸는것
public class Member {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY) 
    // 우리가 db에 값을 넣으면 db가 id를 자동으로 생성. 그것이 IDENEITY
    private Long id;

    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;
    }
}

JPA 회원 레퍼지토리

package com.example.demo.Repository;

import com.example.demo.domain.Member;
import jakarta.persistence.EntityManager;

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

public class JpaMemberRepository implements MemberRepository {

    private final EntityManager em; // JPA를 사용하려면 엔티티매니저를 주입 받아야함.

    public JpaMemberRepository(EntityManager em) { //주입
        this.em = em;
    }
    @Override
    public Member save(Member member) {
        em.persist(member); // persist: 영구 저장
        return member;
    }

    @Override
    public Optional<Member> findById(Long id) {
        Member member = em.find(Member.class, id); // 해당 함수에 식별자 값을 찾기위해 class?
        return Optional.ofNullable(member);

    }


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

    @Override
    public List<Member> findAll() {
        return em.createQuery("select m from Member m", Member.class) //m 객체 자체를 select함.
        //result로 변수명을 지정해주고 호출한 값을 합친 코드.
                .getResultList(); // Inline
    }
}

JPA를 사용하도록 스프링 설정 변경

package com.example.demo;

import com.example.demo.Repository.*;
import com.example.demo.aop.TimeTraceAop;
import com.example.demo.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;

@Configuration
public class SpringConfig {
    private final MemberRepository memberRepository;
    private EntityManager em;
    @Autowired
    public SpringConfig(MemberRepository memberRepository, EntityManager em) {
        this.memberRepository = memberRepository;
        this.em = em;
    }


    @Bean// 스프링 빈에 내가 직접 입력해주어서 컨테이너에 넣는 방식.
    public MemberService memberService() { //spring bean에 저장되어서 memberService에 넣어주고
        return new MemberService(memberRepository); // 그 MemberService는 memberRespository를 사용할수있게끔하고
    }

    @Bean
    public MemberRepository memberRepository() { // 똑같이 빈에 올려주고
//        return new MemoryMemberRepository(); // 레퍼지토리에 빈을 넣어준다.
//        return new JdbcMemberRepository(dataSource);
//        return new JdbcTemplateMemberRepository(dataSource);
        return new JpaMemberRepository(em);
    }