이제부터 몇일간
Data Access 계층에 사용할
ORM을 배우게 된다.
JDBC와 JPA..
현업에서 많이 사용하는 JPA는
JDBC를 기반으로 만들어진 것이기 때문에
JDBC를 먼저 배워 원리나 구조에 대해 이해하고자
Spring Data JDBC에 대해 먼저 배웠다.
Java DataBase Connectivity의 약자로
db에 crud 기능을 Java 문법을 통해 작성할 수 있게 하는
ORM의 일종이고,
Java 기반의 어플리케이션에서 사용하는
Data Access 기술의 기본인 저수준 API이다.
Java application에서 JDBC API를 사용해 DB별 드라이버를 로딩하고, DB와 상호작용을 한다.
- JDBC 드라이버를 DriverManger를 사용해 로딩
- DriverManger를 통해 DB와 연결되는 Connection 객체 생성
- SQL을 실행하기 위한 Statement 객체 생성
- Query 실행하여 ResultSet 객체 생성
- 실행 결과 데이터 조회
- ResultSet, Statement, Connection 순으로 객체 close
Connection 객체를 생성하는 작업은
DB와의 연결, 인증 절차 및 권한 부여 등으로 인해
비용이 많이 드는 작업이라
SQL을 실행 할 때마다 Connection 객체를 생성하는 절차는
정말 비효율 적이다.
그래서,
Application 로딩 시점에 Connection 객체를 미리 생성하고
필요할 때 Connection 객체를 제공해주는 관리자를
Connection pool이라고 한다.
Spring Data JDBC는 데이터와 java 객체를
연계하기 위해 제공되는 Spring Data 라이브러리 중 하나로
Spring Data JPA보다는 덜 복잡하여 DB 접근엔
상대적으로 쉽다.
하지만 후에 JPA를 배우면 알게될
영속성이나 캐시를 지원하지 않는다고 한다.
import org.springframework.data.repository.CrudRepository;
import java.util.Optional;
public interface Repository extends CrudRepository<Entity, Long>{
@Query("SELECT * FROM ENTITY WHERE ENTITY_ID= :entityId")
Optional<Entity> findByEntity(Long entityId);
}
DB에 CRUD 기능을 사용하기 위한 class로
CrudRepository를 상속한 인터페이스는
Entity class와 식별자 (보통 Long)을
제너릭 타입으로 지정하여 DB에서 조회한 데이터를
Entity class로 변환시켜 준다.
@Service
public class ExService{
private final Repository repo;
public ExService(Repository repo){
this.repo = repo;
}
public Entity createEntity(Entity entity){
return repo.save(entity);
}
public Entity findEntity(long entityId){
// Repository interface에 작성한 findByEntity와 같은 결과
return repo.findById(entityId);
}
}
보통 Service class에서
Repository를 주입받아 사용하는거 같고,
기본적으로 findBy"필드명"을 통해
WHERE 절을 수행한다.
import lombok.*;
import org.springframework.data.annotation.*;
@Getter
@Setter
@Table("ENTITY") // 생략가능
public class Entity {
@Id
private Long entityId;
...
}
각 entity class는 table이고,
필드를 column으로 한다.
Table annotation을 통해 실제 DB에 table 명을
Entity class 명과 다르게 할 수도 있다.
public class Entity2 {
@Id
private Long entity2Id;
private Long entityId; // 외래키
...
}
외래키는 단순하게 참조하는
table의 Id값을 필드로 추가하면 되는거 같다.
그리고 Spring Data JDBC를 사용하면
각 Entity table은 따로 SQL을 짜서 CREATE 해야 하는거 같다.
아직까진 django의 orm이 훨씬 직관적이고
기능적으로도 좋고, 사용하기도 편한거 같다.
JPA는 어떨까??