백앤드/SpringBoot + Java 간간한 백앤드 예제

[SpringBoot + Java] 간단한 백엔드(JPA)

맏리믓 2023. 7. 20. 20:23

들어가며

- 이전에 했던 Jdbc 는 어떠한 상황에서는 개발자가 직접 SQL 문을 작성 해야 하였다.

- JPA 를 사용하게 되면 Jdbc 의 장점인 반복 제거와 더불어 기본적인 SQL 도 JPA 가 만들어 제공해 준다.

- 이러한 이유 덕분에 JPA 를 사용하면 SQL, data 중심의 설계에서 객체 중심의 설계로 전환이 가능 하다.


JPA

- JPA는 자바 진영에서 ORM(Object-Relational Mapping) 기술 표준으로 사용되는 인터페이스의 모음이다.

- 즉 실제로 구현 된 것이 아니라 구현된 class 와 맵핑을 위한 frame work 이다.

- JPA 는 PK 기반이 아닌 명령어는 SQL 명령어를 작성 해 주어야 한다.

- 또한 JPA 는 join 이 들어 올 때 모든 data 변경이 transaction 안에서 실행 되어야 한다.


Build.gradle

- 새로운 기능을 사용해야 하니 당연히 관련 라이브러리를 추가 해 주어야 한다.

- 4번째 줄 jpa 관련 dependencies 를 추가 해 준다.

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 'mysql:mysql-connector-java:8.0.33'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

application.properties

. 추가 부분을 추가 해 준다.

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://192.168.0.67:3306/MEMBER?serverTimezone=UTC&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=takeflame

# 추가
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=none # -> data class 를 보고 자동으로 table 을 생성 해 주는 기능
								   # -> 여기서는 none 으로 사요 하지 않음

Domain 수정

. 위에 data 부분에 annotation 을 추가 해 준다.

package com.example.springlearn.domain;

import jakarta.persistence.*;

@Entity
public class Member {
	//PK 라는 의미로 @Id annotation 추가, Identity type 을 사용 하기 때문에 뒷 부분 추가
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

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

    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }
}

JpaMemberRepository

- EntityManager 주입

 . Jpa 는 EntityManager 가 필요 하다.

public class JpaMemberRepository implements MemberRepository{

    private final EntityManager em;

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

 

- 쿼리문(전체 코드)

 . 위에서 설명 했듯 PK(id) 로 조작이 아닐 경우 SQL 명령어가 필요하다.

package com.example.springlearn.repository;

import com.example.springlearn.domain.Member;
import jakarta.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) {
        em.persist(member); //member를 저장 해 준다 -> sql insert + id 생성 해서 넣어 줌
        return member;
    }

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

    @Override
    public Optional<Member> findByName(String name) { //PK(id) 로 조작 하는것이 아닐 결우 Sql 명령어가 필요 함
        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)
                .getResultList();
    }
}

Config 파일 수정

- 생성자를 통해 EntityManager 를 주입 시켜 줌

- Service 가 방금 생성한 JpaMemberRepository를 사용 할 수 있도록 수정

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

}