티스토리 뷰

Web

JPA, ORM, Hibernate, JPQL

nooblette 2021. 9. 9. 02:23

1. JPA(Java Persistant API) & Hibernate

자바 ORM 기술에 대한 표준명세.

JPA는 ORM을 위한 인터페이스를 모아둔 것이며, 구현은 Hibernate, EclipseLink 등 ORM 프레임 워크를 사용해야한다.

 

스프링부트에서 DB에 접근할때 JDBC를 사용하는것보다 mybatis를 사용할때 코드가 간결해지고, 유지보수가 편해짐.

여기서, Hibernate를 사용하면 mybatis보다 더 코드가 간결해지고 객체지향과 생산성을 높일 수 있음. 

(JPA를 사용한다고 해서 JDBC를 사용하지 않는 것은 아님, 내부에서 JDBC API가 동작함)

 

 

2. ORM(Object Realtional Mapping)

객체와 테이블을 매핑 시켜주는 것.

sql query가 아닌 method로 데이터를 조작할 수 있다 

 

e.g.) user 테이블의 데이터를 출력하기위해서 sql을 작성한다면 "select * from user;"라고 작성해야하지만,

ORM을 사용하면 user.findAll() 이라는 메소드 호출로 가능

 

이를 통해,

➡️ DB 접근을 더 객체지향적으로 할 수 있다.

➡️ 메소드 호출만으로 query를 수행할 수 있어, 생산성이 높아진다.

 

sql 문을 사용하지 않는다고 해서 몰라도 된다는 것은 아님.

메소드가 호출하는 SQL을 상시 모니터링 하여 의도와 다르게 실행되지는 않는지, 매핑이 잘못 되지는 않았는지 확인해야 함.

 

하지만, ORM으로 복잡한 query를 표현하고 성능(속도)상 한계가 있다.

이를 jpql로 표현하여 해결할 수 있다.

혹은 mybatis와 JPA를 함께 사용하여 해결하기도 한다(프로젝트의 기능에 따라 어떻게 할지를 판단).

 

 

3. JPQL(Java Persistance Query Language)

    - SQL과 비슷한 문법을 갖는 객체 지향 쿼리.

    - SQL을 추상화 하였기 때문에 특정 벤더(mysql, oracle ...) 에 종속되지 않음.

    - JPA가 이 JPQL을 해석해서 SQL을 생성하여 DB에서 조회.

    - 복잡한 검색(select)를 위해 사용, insert/update/delete 쿼리는 엔티티 매니저가 직접 호출하는 것이 좋다.

 

  • 기본 문법

 

1
String jpql = "select c from Category c ";
cs

 

특징 ) 엔티티와 속성은 대소문자를 구분 / select, from과 같은 jpql 키워드는 대소문자 구분 x 

 

 

  • 타입

 

- TypedQuery

반환되는 엔티티가 정해져 있을 때 사용.

1
2
String jpql = "SELECT b FROM Book b ";
TypedQuery<Book> query = em.createQuery(jpql, Book.class);
cs

 

 

- Query

데이터 검색 결과의 타입을 명시하지 않음.

엔티티에서 필요한 칼럼만 선택할 수 있음.

1
2
String jpql = "SELECT b.no, b.title FROM Book b";
Query<Book> query = em.createQuery(jpql, Book.class);
cs

TypedQuery<Book> 타입으로 선언하면 에러가 발생한다.

 

 

 

  • 파라미터 바인딩

 

1
2
3
4
public static void namedParameter(EntityManager em, String param1) {
    String jpql = "SELECT b FROM Book b WHERE title = :foo";
    TypedQuery<Book> query = em.createQuery(jpql, Book.class);
    query.setParameter("foo", param1);
cs

 

jpql의 어떠한 동적인 조건을 통해 데이터를 조회하고 싶다면 setParameter() 메소드를 호출한다.

 

 

1
String jpql = "SELECT b FROM Book b WHERE title = " + param1;
cs

 

이런식으로 직접 바인딩 하는 경우 SQL injection 공격을 받을 수 있으니, 반드시 setParameter() 메소드를 통해야 한다.

 

 

  • DTO 사용

 

DB에서 가져온 데이터를 전송하는데 Entity를 사용한다.

하지만 만약, Entity에 정의되지 않은 필드가 필요한 경우 DTO라는 객체를 사용한다.

(테이블의 정의 되지 않은 칼럼을 Entity에 임의로 추가하는 것은 테이블-객체 간 완전한 매핑을 이루지 않게 만들기 때문에 바람직하지 않음.)

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class BookDTO {
    private Integer no;
    private String title;
    
    public BookDTO() {}
    
    public BookDTO(Integer no, String title    ) {
        this.no = no;
        this.title = title;
    }
}
 
// DTO 사용 ( new 명령어 )
public static void useDTO (EntityManager em) {
    String jpql = "SELECT new com.victolee.example.dto.BookDTO(b.no, b.title) FROM Book b";
    TypedQuery<BookDTO> query = em.createQuery(jpql, BookDTO.class);
    
    List<BookDTO> list = query.getResultList();
    for( BookDTO dto : list) {
        System.out.println(dto.getTitle());
    }
}
cs

 

JPQL에서 지원하는 new 키워드를 통해

new com.victolee.example.dto.BookDTO(b.no, b.title) 

DTO 객체를 생성하는 것 처럼 표현한다.

 


출처

https://victorydntmd.tistory.com/195

 

[Spring JPA] ORM과 JPA 그리고 Hibernate

2020.03.06 수정 1. JPA ( Java Persistent API )와 ORM ( Object Relational Mapping ) JPA JPA란 자바 ORM 기술에 대한 API 표준 명세를 의미합니다. JPA는 ORM을 사용하기 위한 인터페이스를 모아둔 것이며, J..

victorydntmd.tistory.com

- https://victorydntmd.tistory.com/205

 

[Spring JPA] JPQL ( Java Persistence Query Language )

JPQL ( Java Persistence Query Language ) JPQL은 SQL과 비슷한 문법을 가진 객체 지향 쿼리입니다. JPQL의 탄생 배경은 JPA에서 제공하는 메서드 호출만으로 섬세한 쿼리 작성이 어렵다는 것에 있습니다. 이

victorydntmd.tistory.com

'Web' 카테고리의 다른 글

Jackson과 Gson (Java에서 json 사용하기)  (0) 2021.09.09
JPA에서 데이터 접근  (0) 2021.09.09
Apache Tomcat과 Apache  (0) 2021.08.14
웹 브라우저의 기본 원리  (0) 2021.07.26
URL과 URI의 차이  (0) 2021.07.26
Comments