스프링 JPA
JPA(Java Persistence API)
제품의 이름이 아니고, API 표준의 이름이다.
JPA 표준 규격대로 만들어진 제품 중에서 유명한 것이 Hibernate 오픈소스 라이브러리이다.
우리가 사용하는 Spring JPA에 Hibernate 라이브러리가 포함되어 있다.
장점
SQL 명령을 구현할 필요가 없다. DBMS 제품을 교체하더라도 소스코드를 수정할 필요가 없다.
자동으로 처리되는 부분이 많아서, 구현할 소스코드의 양이 상대적으로 적다.
관계형 데이터베이스가 아니더라도 적용할 수 있다.
단점
- 복잡한 조회 명령을 구현해야 할 때, 익숙한 SQL 명령으로 구현할 수가 없고,
- JPA의 고급 기능을 공부해야 한다.
1 | employeeRepository.findAll() 메소드 |
Rest API
REST API 서비스라는 것은,
클라이언트의 URL 요청에 대해서 JSON 형태의 데이터를 출력하는 서버의 메소드를 말한다.
Spinrg MVC 프레임웍에서 REST API 서비스를 구현할 때,
컨트롤러에 @RestController
어노테이션을 붙인다.
RestController의 액션 메소드가 리턴하는 Java 객체는 자동으로 JSON 포멧으로 변환되어
클라이언트에 전송된다.
RestController
RestController의 액션 메소드는, 데이터를 클라이언트에 전송하기 때문에, 뷰(view)가 필요 없다.
예
1 |
|
Request Method
클라이언트가 서버에 요청(request)을 전달하는 방식(method)을 request
method
라고 한다.REST API 서비스를 구현할 때, request method(get,post,put,delete) 들을 전부 잘 활용하는 것이 바람직한다.
서버에 데이터를 요청할 때는
GET
방식서버에 저장할 새 데이터를 전송할 때는
POST
방식서버의 기존 데이터를 수정하기 위해 전송할 때는
PUT
방식서버의 데이터 삭제를 요청할 때는
DELETE
방식을 사용하는 것이 바람직하다.
REST API URL 패턴
query string 사용하지 않기
REST API 서비스의 URL에 query string을 사용하지 않는 것이 관례이다.예를 들어 아래 URL은 바람직하지 않다.
http://localhost:8080/studentServer/api/student?id=3아래와 같은 형태이어야 한다.
http://localhost:8080/studentServer/api/student/3
Request Method = GET동사 사용하지 않기
REST API 서비스의 URL에 동사를 사용하지 않는 것이 관례이다.예를 들어 아래 URL은 바람직하지 않다.
http://localhost:8080/studentServer/studentDelete?id=3아래와 같은 형태이어야 한다.
http://localhost:8080/studentServer/api/student/3
Request Method = DELETE
@PathVariable
요청된 URL이 아래와 같다면
http://localhost:8080/jpa10/api/student/3
URL에 들어있는 id 값 3을 받기 위한 액션 메소드는 다음과 같이 구현한다.
@RequestMapping(“api/student/{id}”)
public Student student(@PathVariable(“id”) int id)
JPA Entity 클래스
JPA Entity 클래스는, 데이터베이스 테이블의 레코드에 해당하는 Java 클래스이다.
데이터베이스 조회 결과가 자동으로 엔터티 클래스 객체에 채워져 리턴된다.
@Entity
JPA Entity 클래스 앞에 @Entity 어노테이션을 붙여야 한다.
@Id
기본키(primary key)에 해당하는 멤버 변수에 @Id 어노테이션을 붙여야 한다.
@GeneratedValue(strategy = GenerationType.IDENTITY)
기본키가 Auto Increment 필드이거나 Identity 필드인 경우에
이 어노테이션을 붙여야 한다.
@ManyToOne
@JoinColumn(name = “departmentId”)
Department department;
Employee 테이블의 departmentId 필드가 외래키(foreign key)이고,
이 외래키가 Department 테이블의 레코드를 한 개 가르킨다면,
Employee 테이블에 int departmentId 멤버 변수를 만드는 대신에
Department department 멤버 변수를 만들고, 위 어노테이션들을 붙어야 한다.
Employee 테이블과 Department 테이블의 관계가 다 대 1 이면, @ManyToOne 어노테이션을 붙이고,
1 대 1 이면 @OneToOne 어노테이션을 붙인다.
Eager Loading, Lazy Loading
위와 같이 departmentId 외래키 대신 Department department 멤버 변수를
Employee 엔터티 클래스에 정의하면 다음과 같은 일이 자동으로 일어난다.
(1) DB 에서 Employee 레코드가 조회되면,
(2) Employee 엔터티 클래스 객체가 생성되고,
(3) 이 객체에, 조회된 Employee 레코드가 채워지고,
(4) 그 Employee 의 departmentId 외래키가 가르키는 Department 레코드도 같이 조회되고,
(5) Department 엔터티 클래스 객체가 생성되고,
(6) 이 객체에, 조회된 Department 레코드가 채워지고
(7) 이 Department 객체가 Employee 객체의 department 멤버 변수에 대입된다.
Eager Loading
DB 에서 Employee 레코드를 조회할 때,
(1) ~ (7) 절차가 자동으로 실행되는 정책을 Eager Loading 이라고 부른다.
보통 Eager Loading 이 기본 정책이다.
Lazy Loading
DB 에서 Employee 레코드를 조회할 때,
(1) ~ (3) 절차만 즉시 자동으로 실행되고 (4) ~ (7) 절차의 실행은 최대한 뒤로 미루는 것을
Lazy Loading 정책이라고 부른다.
Employee 클래스의 getDepartment() 메소드가 호출되기 전에는 (4) ~ (7) 절차의 실행을 미루다가
최초로 getDepartment() 메소드가 호출될 때 이 절차를 실행한다.