its_jh_stroy

[Springboot] JPA와 ORM 본문

Java

[Springboot] JPA와 ORM

_J_H_ 2024. 8. 21. 23:52

JPA(Java Persistance API)

자바에서 표준으로 사용하는 ORM 인터페이스

내부적으로는 JDBC를 사용하여 데이터베이스와 상호작용한다.

 

JPA의 구현체 Hibernate

JDBC와 마찬가지로 JPA도 인터페이스 구성되어 있고, 인터페이스명은 EntityManager이다.

구현체는 주로 Hibernate라는 객체인데, 직접 구현하는 것이 아니라 스프링부트에서 자동으로 만들어진다.

스프링 빈을 관리하기 위해 스프링 컨테이너를 사용하는 것처럼, JPA 엔티티를 관리하는 공간으로 Entity Context가 있다.

Hibernate는 데이터베이스와 상호작용하는 메서드를 제공하고 Entity Context를 관리하는데, 엔티티의 라이브 사이클(생성~소멸)을 관리한다는 의미이다.

데이터베이스는 MySQL로 정하여 실습할 것이다.

 

의존성 추가

build.gradle에서 아래 의존성을 추가한다.

implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
// MySQL 의존성
runtimeOnly 'com.mysql:mysql-connector-j'

 

 

JPA를 통한 MySQL 연결

application.properties 파일은 JDBC와 유사하다.

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/shoppingmall
spring.datasource.username=root
spring.datasource.password=1234

# JPA가 실행하는 쿼리 출력, 디버깅을 위해 사용
spring.jpa.show-sql = true

 

 

모델 만들기

@Getter
@Setter
@Entity
public class Product {
    @Id
    private int id;
    private String name;
    private int price;
}

 

 

JPA로 데이터베이스 다루기

JPA에서 데이터베이스와 상호작용하는 코드이다.

// ProductRepository.java
@Repository
public class ProductRepository {
    @Autowired
    EntityManager entityManager;

    public List<Product> findProduct() {

        // import jakarta.persistence.EntityManager;
        // import jakarta.persistence.TypedQuery;
        TypedQuery<Product> query = entityManager.createQuery("SELECT p FROM Product p", Product.class);
        List<Product> products = query.getResultList();
        return products;
    }

    public void save(Product product) {
        entityManager.persist(product);
    }
}
// ProductService.java
@Service
public class ProductService {
    private ProductRepository productRepository;

    @Autowired
    ProductService(ProductRepository productRepository) {
        this.productRepository = productRepository;
    }

    public List<Product> findProduct()
    {
        return productRepository.findProduct();
    }

    // 저장하는데 트랜잭션 안 걸면 아래 예외 발생
    // InvalidDataAccessApiUsageException
    @Transactional
    public void saveProduct(Product product) {
        productRepository.save(product);
    }
}

 

 

핸들러 메서드는 서비스의 메서드 시그니처에 따라 호출하면 되므로 컨트롤러는 생략한다.

JDBC보다는 간단해진 것 같지만 findProduct 메서드를 보면 여전히 복잡하다.

다음에는 이걸 조금 더 쉽게 사용하기 위해 만든 Spring Data JPA를 알아볼 것이다.