JPA(Java Persistence API)

  • 제품의 이름이 아니고, API 표준의 이름이다.

  • JPA 표준 규격대로 만들어진 제품 중에서 유명한 것이 Hibernate 오픈소스 라이브러리이다.

  • 우리가 사용하는 Spring JPA에 Hibernate 라이브러리가 포함되어 있다.

장점

  • SQL 명령을 구현할 필요가 없다. DBMS 제품을 교체하더라도 소스코드를 수정할 필요가 없다.

  • 자동으로 처리되는 부분이 많아서, 구현할 소스코드의 양이 상대적으로 적다.

  • 관계형 데이터베이스가 아니더라도 적용할 수 있다.

단점

  • 복잡한 조회 명령을 구현해야 할 때, 익숙한 SQL 명령으로 구현할 수가 없고,
  • JPA의 고급 기능을 공부해야 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
employeeRepository.findAll() 메소드
employee 테이블에서 레코드 전체 목록을 조회한다.
List<Employee> 객체가 리턴된다.

employeeRepository.findById(id)
employee 테이블에서 기본키 필드 값이 id인 레코드를 조회한다.
Optional<Employee> 타입의 객체가 리턴된다. 이 객체의 get 메소드를 호출하면 Employee 객체가 리턴된다.
예: Employee employee = employeeRepository.findById(id).get();

employeeRepository.save(employee)
Employee 객체를 employee 테이블에 저장한다.
Employee 객체의 id(기본키) 속성값이 0 이면 INSERT 되고, 0 이 아니면 UPDATE 된다.

employeeRepository.saveAll(employeeList)
Employee 객체 목록을 employee 테이블에 저장한다.

employeeRepository.delete(employee)
Employee 객체의 id(기본키) 값과 일치하는 레코드가 삭제된다.

employeeRepository.deleteAll(employeeList)
Employee 객체 목록을 테이블에서 삭제한다.

employeeRepository.count()
employee 테이블의 전체 레코드 수를 리턴한다.

employeeRepository.exists(id)
employee 테이블에서 id에 해당하는 레코드가 있는지 true/false를 리턴한다.

employeeRepository.flush()
지금까지 employee 테이블에 대한 데이터 변경 작업들이 디스크에 모두 기록되도록 한다.

Rest API

REST API 서비스라는 것은,
클라이언트의 URL 요청에 대해서 JSON 형태의 데이터를 출력하는 서버의 메소드를 말한다.

Spinrg MVC 프레임웍에서 REST API 서비스를 구현할 때,
컨트롤러에 @RestController 어노테이션을 붙인다.

RestController의 액션 메소드가 리턴하는 Java 객체는 자동으로 JSON 포멧으로 변환되어
클라이언트에 전송된다.

RestController

RestController의 액션 메소드는, 데이터를 클라이언트에 전송하기 때문에, 뷰(view)가 필요 없다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

// 변환전
@Controller
public class StudentController {
public @ResponseBody List<Student> students() {
List<Student> list = ...;
return list;
}

// 변환후
@RestController
public class StudentController {
public List<Student> students() {
List<Student> list = ...;
return list;
}
}

Request Method

  • 클라이언트가 서버에 요청(request)을 전달하는 방식(method)을 request method 라고 한다.

  • REST API 서비스를 구현할 때, request method(get,post,put,delete) 들을 전부 잘 활용하는 것이 바람직한다.

  • 서버에 데이터를 요청할 때는 GET 방식

  • 서버에 저장할 새 데이터를 전송할 때는 POST 방식

  • 서버의 기존 데이터를 수정하기 위해 전송할 때는 PUT 방식

  • 서버의 데이터 삭제를 요청할 때는 DELETE 방식을 사용하는 것이 바람직하다.

REST API URL 패턴

@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() 메소드가 호출될 때 이 절차를 실행한다.