4 minute read

한 두달간 JPA를 써봤는데 처음 배웠을 때에는 너무 어려워서 왜 하지?! mybatis가 훨씬 낫지않나? 이렇게 생각했었는데 지금은 mybatis 쓰라고해도 못쓸거같다..

그렇다고 못쓸건 또 없지만… mybatis는 내가 잘 입력하면 오류 안나고 꼬아서 생각안해도 되서 편하긴하다…

쨌든… 요즘엔 계속 만들고 있던 것들이 생겨나서 복붙하고 막 그러고있는데

그러다 보니 jpa 기초적인 것도 까먹어서 native query문으로 쓸때가 많다 !!

그래서 다시 정리하고싶은 마음에 jpa기초부터 다시 정리해볼려고 한다 !!

1) Domain Model

데이터베이스를 설계할 때, 다이어그램으로 데이터베이스에 저장할 정보를 설계한다. 이런 설계 작업의 결과물을 모델이라고 부른다. 즉 데이터베이스 설계 작업에서 작성된 ER 다이어그램도 모델이다. 도메인 모델은 ER 다이어그램과 매우 유사하다. 그렇지만 보통 도메인 모델은 UML 다이어그램으로 작성된다.

2) JPA Repository 기본 Method (Spring JPA 자동구현 메소드)

  • findAll() : 테이블에서 레코드 전체 목록을 조회한다.
  • findById(id) : 기본키 필드값이 id인 레코드를 조회한다. ex) Employee employee = employeeRepository.findById(id).get();
  • save(employee) : Employee객체를 저장한다.
  • saveAll(employeeList) : Employee객체 목록을 저장한다.
  • delete(employee) : Employee객체의 id(기본키)값과 일치하는 레코드 삭제
  • deleteAll(employeeList) : Employee객체목록을 테이블에서 삭제
  • count() : 테이블 전체 레코드 수를 리턴한다.
  • exists(id) : id에 해당하는 레코드가 있는지 T/F로 리턴한다.
  • flush() : 데이터 변경작업들이 디스크에 모두 기록되도록 한다.

다시 보니 count로 0이아닌 수와 else로 나누곤 했는데 그게아닌 exist로 해도 될거같네…

역시 정리한번 하길 잘한거같당ㅎㅎ

3) REST API

안드로이드 앱을 위한 서버를 개발하거나 웹브라우저에서 실행되는 javascript로 개발한 앱을 위한 서버를 개발할 때, REST API 서비스를 제공하는 서버를 구현한다. 클라이언트의 URL 요청에 대해서 JSON형태의 데이터를 출력하는 서버의 메소드

4) JSON(Javascript Object Notation)

서버와 클라이언트 사이에 데이터를 주고 받을 때 흔히 사용되는 포멧 JSON 포맷은 Javascript언어의 객체나 배열의 문법과 동일하다.

ex)

  • 객체 { id: 1, name: “홍길동”, age:18 }
  • int 배열 [1, 2, 3, 4]
  • 객체배열 [{ id:1, name:”홍길동”, age:18 }, { id:2, name:”전우치”, age:19}]

5) RestController

Spinrg MVC 프레임웍에서 REST API 서비스를 구현할 때, 컨트롤러에 @RestController 어노테이션을 붙인다. RestController의 액션 메소드가 리턴하는 Java 객체는 자동으로 JSON 포멧으로 변환되어 클라이언트에 전송된다. RestController의 액션 메소드는, 데이터를 클라이언트에 전송하기 때문에, 뷰(view)가 필요 없다.

6) @ResponseBody

컨트롤러의 액션 메소드 앞에 @ResponseBody 어노테이션을 붙이면, 이 액션 메소드가 리턴하는 Java 객체는 자동으로 JSON 포멧으로 변환되어 클라이언트에 전송된다.

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

그런데 컨트롤러 앞에 @RestController 어노테이션을 붙이면 그 컨트롤러의 액션 메소드 앞에 @ResponseBody 어노테이션을 붙이지 않고 생략해도 된다.

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

7) @RequestBody

RestController의 액션 메소드가 액션 메소드를 호출할 때 전송하는 request parameter 데이터도 JSON 포멧으로 전송하는 것이 일관적이어서 좋다. 이렇게 JSON 포멧으로 전송된 request parameter 데이터를 받을 액션 메소드의 파라미터 변수에는 @RequestBody 어노테이션을 붙여주어야 한다

public String update(@RequestBody Student student) {
      ...
}

8) Request Method

클라이언트가 서버에 요청(request)을 전달하는 방식(method)을 request method라고 한다. 지금까지 우리가 사용한 request method는 GET, POST들 뿐이다. 그런데 GET, POST 뿐만 아니라 DELETE, PUT도 있다. REST API서비스를 구현할 때, request method들을 전부 잘 활용하는 것이 바람직하다.

  • GET: 서버에 데이터를 요청할 때
  • POST: 서버에 저장할 새로운 데이터를 전송할때
  • PUT : 서버의 기존 데이터를 수정하기 위해 전송할 때
  • DELETE: 서버의 데이터 삭제를 요청할 때

9) REST API URL 패턴

  • query string 사용하지 않기

Bad ex:

   http://localhost:8080/studentServer/api/student?id=3

Good ex:

   http://localhost:8080/studentServer/api/student/3
   Request Method = GET
  • 동사 사용하지 않기

Bad ex:

   http://:8080/studentServer/studentDelete?id=3

Good ex:

   http://localhost:8080/studentServer/api/student/3
   Request Method = DELETE

10) @PathVriable

요청된 URL이 http://localhost:8080/api/student/3 이라면, 구현은

   @RequestMapping("api/student/{id}")
   public Student student(@PathVariable("id") int id)

이렇게 해야된다.

11) 액션 메소드 URL

컨트롤러 클래스에도 @RequestMapping(“URL1”) 어노테이션 붙어있고 액션 메소드에도 @RequestMapping(“URL2”) 어노테이션이 붙어있다면, 그 액션 메소드를 호출하기 위한 URL은 “URL1/URL2” 이다. ex) student/list

@Controller
@RequestMapping("studnet")
public class StudentController {
   @RequestMapping("list")
   public String list(...) { 
      ...
   }
}

12) 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 어노테이션을 붙인다.

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

처음 배우기 시작할 때에 정리한것과 지금 사용을 하고있는 수준에서 다시 보니 더 이해가 잘되고 이런내용이었구나 싶다ㅎㅎ

오늘부터 다른 기초들도 한번 정리해보고 복습하는 시간을 가져야겠다ㅠ.ㅠ

근데 ITZY 노래 좋당 ♥ㅠ.ㅠ♥

Categories:

Updated:

Comments