์คํ๋ง JPA, ํ์ด์ง, ์ฐ๊ด๊ด๊ณ
์คํ๋ฅดํ ์ฝ๋ฉ ํด๋ฝ์ Spring ์ฌํ๋ฐ 4์ฃผ ์ฐจ ๋ด์ฉ์ธ ์คํ๋ง JPA, ํ์ด์ง, ์ฐ๊ด๊ด๊ณ
๋ฅผ ์ ๋ฆฌํ๋ค.
ํต์ฌ ๋ด์ฉ
- Spring Data JPA
- ํ์ด์ง
- JPA์ ์ฐ๊ด ๊ด๊ณ
Spring Data JPA
ORM
: ORM์ Object-Relation Mapping์ด๋ฉฐ ๋ง ๊ทธ๋๋ก ๊ฐ์ฒด(์ฌ๊ธฐ์ ์๋ฐ)์ DB(H2, MySQL)๋ฅผ ์ด์ด์ฃผ๋ ๊ธฐ์ ์ด๋ค.
- SQL์ ์์ฑ ์ค ์ค์ํ๊ธฐ๋ ์ฝ๊ณ ๊ฐ๋ฐ์๊ฐ ๋น์ฆ๋์ค ๋ก์ง ๊ฐ๋ฐ๋ณด๋ค SQL ์์ฑ์ ๋ ๋ง์ ๋ ธ๋ ฅ์ ๋ค์ด์ผ ํ์
- ๊ฐ์ฒด์งํฅ๊ณผ ๊ด๊ณํ DB๋ ์ฌ์ฉ ๋ชฉ์ ๋ฐ ์ฌ์ฉ ๋ฐฉ๋ฒ์ด ์ ์ด์ ๋ค๋ฆ
- ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ORM์ด ํ์
JPA
: JPA๋ Java Persistience API๋ก์จ ์๋ฐ ORM ๊ธฐ์ ์ ๋ํ ํ์ค ๋ช ์ธ์ด๋ค.
- ํ์ด๋ฒ๋ค์ดํธ : JPA๋ ํ์ค ๋ช ์ธ์ด๊ณ ์ด๋ฅผ ์ค์ ๊ตฌํํ ํ๋ ์์ํฌ๊ฐ ํ์ํ๋ฐ, ์ด ์ค ํ์ด๋ฒ๋ค์ดํธ๊ฐ ์ฌ์ค์ ํ์ค์ด๋ค.
Spring Data JPA
:Repository ์ธํฐํ์ด์ค
๋ฅผ ํตํด ํ์ํ ๊ตฌํ์ ์คํ๋ง์ด ๋์ ํด์ฃผ๋, JPA๋ฅผ ํธ๋ฆฌํ๊ฒ ์ฌ์ฉํ๊ธฐ ์ํด ๋งคํํ ๊ฒ- Spring Data JPA ์์ ์ฝ๋
@Entity public class Product extends Timestamped { @GeneratedValue(strategy = GenerationType.AUTO) @Id private Long id; private Long userId; private String title; private String image; private String link; private int lprice; private int myprice; }
public interface ProductRepository extends JpaRepository<Product, Long> { }
- Spring Data JPA ์์ ์ฝ๋
ํ์ด์ง
- ํ ๋ฒ์ ์๋ฐฑ ~ ์์ต ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ๋ ๋ฆฌ๋ฉด ์๋ฒ๋ ํด๋ผ์ด์ธํธ๋ ๊ณผ๋ถํ -> ๋๋ ์ ๋ณด๋ด์ผ๋
- ํ์ด์ง๋ค์ด์ (๊ตฌ๊ธ ๊ฒ์), ์ธํผ๋ํธ ์คํฌ๋กค(์ ํฌ๋ธ) ๋ฑ์ด ์์
์ค๊ณ (Server์์)
number
: ์กฐํํ ํ์ด์ง ๋ฒํธ (0๋ถํฐ ์์)size
: ํ ํ์ด์ง์ ๋ณด์ฌ์ค ์๋ฃ์ ๊ฐ์numberOfElements
: ์ค์ ์กฐํ๋ ์๋ฃ์ ๊ฐ์totalElement
: ์ ์ฒด ์๋ฃ ๊ฐ์totalPages
: ์ ์ฒด ํ์ด์ง ์first
: ์ฒซ ํ์ด์ง์ธ์ง? (boolean)last
: ๋ง์ง๋ง ํ์ด์ง์ธ์ง? (boolean)
๊ตฌํ
Controller
@GetMapping("/api/products")
public Page<Product> getProducts(
@RequestParam("page") int page,
@RequestParam("size") int size,
@RequestParam("sortBy") String sortBy,
@RequestParam("isAsc") boolean isAsc,
@AuthenticationPrincipal UserDetailsImpl userDetails
) {
Long userId = userDetails.getUser().getId();
page = page - 1;
return productService.getProducts(userId, page , size, sortBy, isAsc);
}
ํ๋ผ๋ฏธํฐ๋ฅผ ํตํด ํด๋ผ์ด์ธํธ๊ฐ ์ํ๋ ํ์ด์ง ์, ํ์ด์ง๋น ์ฌ์ด์ฆ, ๋ฐฐ์ด์ ๋ํ ์ต์ ์ ๋ฐ๋๋ค.
Service
public Page<Product> getProducts(Long userId, int page, int size, String sortBy, boolean isAsc) {
Sort.Direction direction = isAsc ? Sort.Direction.ASC : Sort.Direction.DESC;
Sort sort = Sort.by(direction, sortBy);
Pageable pageable = PageRequest.of(page, size, sort);
return productRepository.findAllByUserId(userId, pageable);
}
์ปจํธ๋กค๋ฌ์์ ๋ฐ์ ํ๋ผ๋ฏธํฐ๋ฅผ ์ด์ฉํ์ฌ Sort
๋ก ํตํด Pageable
๊ฐ์ฒด๋ฅผ ์์ฑํ ๋ ํ์ํ ํ๋ผ๋ฏธํฐ๋ฅผ ๋ง๋ค์ด์ค๋ค.
Repository
public interface ProductRepository extends JpaRepository<Product, Long> {
Page<Product> findAllByUserId(Long userId, Pageable pageable);
}
Page<Product>
๋ฅผ ๋ฐํํ์ผ๋ก, Pageable
๊ฐ์ฒด๊ฐ ํ๋ผ๋ฏธํฐ๋ก ๋ค์ด๊ฐ๋ ๋ฉ์๋๋ฅผ ๋ฆฌํฌ์งํฐ๋ฆฌ์์ ๋ง๋ค์ด์ค๋ค.
JPA์ ์ฐ๊ด๊ด๊ณ
- JPA๋ Entity ํด๋์ค์ ํ๋ ์์ ์ฐ๊ด๊ด๊ณ ์ด๋
ธํ
์ด์
(@)
์ ์ค์ ํด ์ฃผ๋ ๊ฒ๋ง์ผ๋ก ์ฐ๊ด๊ด๊ณ๊ฐ ํ์ฑ๋๋ค. - ์ด๋ ธํ ์ด์ ์ ํตํด ๊ฐ์ฒด๋ผ๋ฆฌ์ ๊ด๊ณ๋ฅผ ๋งบ์ด์ฃผ๋ฉด, DB์์๋ ์ธ๋ํค๋ฅผ ํตํ ๊ด๊ณ๋ฅผ ํ์ฑํด์ค๋ค.
๊ตฌํ์ ์ฐ์ด๋ ์ด๋ ธํ ์ด์
@OneToMany
: ์ผ๋๋ค ๊ด๊ณ- ex) ํ์ 1๋ช ์ด ์ฌ๋ฌ ๊ฐ์ ํด๋๋ฅผ ๊ฐ์ง ์ ์์
@OneToOne
: ์ผ๋์ผ ๊ด๊ณ- ex) ๋ฐฐ๋ฌ ์ฃผ๋ฌธ 1๊ฐ ์ฃผ๋ฌธ ์, ์ฟ ํฐ 1๊ฐ๋ง ํ ์ธ ์ ์ฉ ๊ฐ๋ฅ
@ManyToOne
: ๋ค๋์ผ ๊ด๊ณ- ex) ํด๋ ์ฌ๋ฌ ๊ฐ๋ฅผ ํ์ 1๋ช ์ด ๊ฐ์ง ์ ์์
@ManyToMany
: ๋ค๋๋ค ๊ด๊ณ- ex) ๊ณ ๊ฐ์ ์์์ ์ฌ๋ฌ๊ฐ ์ฐ ๊ฐ๋ฅ, ์์์ ์ ๊ณ ๊ฐ ์ฌ๋ฌ๋ช ์๊ฒ ์ฐ ๊ฐ๋ฅ
ManyToMany
๊ณ ๊ฐ๊ณผ ์์์ ๊ณผ ๊ฐ์ ๋ค๋๋ค ๊ด๊ณ์์๋ ๊ณ ๊ฐ์ ID, ์์์ ์ ID์ ๋ค๋ฅธ ๋ถ๊ฐ์ ์ธ ์ ๋ณด๋ฅผ ๋ด์ ํ
์ด๋ธ์ ๋ฐ๋ก ๋ง๋ค์ด์ค์ผํ๋ค.@ManyToMany
์ด๋
ธํ
์ด์
์ผ๋ก ์์ฑ ์, JPA๊ฐ ์์ฑํด์ค๋ค.
์ฐ๊ด๊ด๊ณ ์นผ๋ผ ์ค์
@ManyToOne
@JoinColumn(name = "USER_ID", nullable = false)
private User user;
- name: ์ธ๋ํค ๋ช
- nullable: ์ธ๋ํค null ํ์ฉ ์ฌ๋ถ
'Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Spring AOP, ํธ๋์ญ์ , ์์ธ ์ฒ๋ฆฌ (0) | 2022.03.17 |
---|---|
ํ ์คํธ์ ์ข ๋ฅ, ์คํ๋ง ํ ์คํธ ํ๋ ์์ํฌ (0) | 2022.03.17 |
์ธ์ฆ, ์ธ๊ฐ, ์ฟ ํค, ์ธ์ , OAuth2 (0) | 2022.03.16 |
Spring์ DI, IoC ์ปจํ ์ด๋, ์คํ๋ง ๊ณ์ธต๊ตฌ์กฐ (0) | 2022.03.16 |
@ControllerAdvice๋ฅผ ์ด์ฉํ ์์ธ ์ฒ๋ฆฌ (0) | 2022.03.16 |