Spring์์ Spring Data JPA ์ฌ์ฉํ๋ ์ด์
- ๊ตฌํ์ฒด ๊ต์ฒด์ ์ฉ์ด์ฑ : Hibernate ์ธ์ ๋ค๋ฅธ ๊ตฌํ์ฒด๋ก ์ฝ๊ฒ ๊ต์ฒดํ๊ธฐ ์ํจ
- ์ ์ฅ์ ๊ต์ฒด์ ์ฉ์ด์ฑ : RDB ์ธ์ ๋ค๋ฅธ ์ ์ฅ์๋ก ์ฝ๊ฒ ๊ต์ฒดํ๊ธฐ ์ํจ
SpringDataJpa ์ฌ์ฉ์ค์ SpringDataMongoDB๋ก ๋ณ๊ฒฝํ์ฌ๋ ์ธํฐํ์ด์ค๊ฐ ๋์ผํ์ฌ ๋ฌธ์ ๊ฐ ์์
@Getter
@NoArgsConstructor
@Entity
public class posts {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(length = 500, nullable = false)
private String title;
@Column(columnDefinition = "TEXT", nullable = false)
private String content;
private String author;
@Builder
public posts(Long id, String title, String content, String author) {
this.id = id;
this.title = title;
this.content = content;
this.author = author;
}
}- @Entity
- ํ ์ด๋ธ๊ณผ ๋งํฌ๋ ํด๋์ค
- ๊ธฐ๋ณธ๊ฐ์ผ๋ก ํด๋์ค์ ์นด๋ฉ์ผ์ด์ค ์ด๋ฆ์ ์ธ๋์ค์ฝ์ด ๋ค์ด๋ฐ์ผ๋ก ํ ์ด๋ธ ์ด๋ฆ์ ๋งค์นญ (SalesManger.java -> sales_manager table)
- @Id
- ํด๋น ํ ์ด๋ธ์ PK ํ๋
- @GeneratedValue
- ์คํ๋ง ๋ถํธ 2.0์์๋ GenerationType.IDENTITY ์ต์ ์ ์ถ๊ฐํด์ผ๋ง auto_increment๊ฐ ๋จ
- ์คํ๋ง ๋ถํธ 2.0 ๋ฒ์ ๊ณผ 1.5๋ฒ์ ์ ์ฐจ์ด
์ฌ๋งํ๋ฉด Entity์ PK๋ Long ํ์ ์ Auto_increment๋ฅผ ์ถ์ฒ
- FKํค๋ฅผ ๋งบ์ ๋ ๋ค๋ฅธ ํ ์ด๋ธ์์ ๋ณตํฉํค ์ ๋ถ๋ฅผ ๊ฐ๊ณ ์๊ฑฐ๋, ์ค๊ฐ ํ ์ด๋ธ์ ํ๋ ๋ ๋ฌ์ผ ํ๋ ์ํฉ์ด ๋ฐ์
- ์ธ๋ฑ์ค์ ์ข์ ์ํฅ์ ๋ผ์น์ง ๋ชปํจ
- ์ ๋ํฌํ ์กฐ๊ฑด์ด ๋ณ๊ฒฝ๋ ๊ฒฝ์ฐ PK ์ ์ฒด๋ฅผ ์์ ํด์ผ ํ๋ ์ผ์ด ๋ฐ์
์ฃผ๋ฏผ๋ฑ๋ก๋ฒํธ, ๋ณตํฉํค ๋ฑ์ ์ ๋ํฌ ํค๋ก ๋ณ๋๋ก ์ถ๊ฐํ๋๊ฒ์ ์ถ์ฒ
Entity ํด๋์ค์์๋ ์ ๋ Setter ๋ฉ์๋๋ฅผ ๋ง๋ค์ง ์์ผ๋ฉฐ ํด๋น ํ๋์ ๊ฐ ๋ณ๊ฒฝ์ด ํ์ํ๋ฉด ๋ช ํํ ๊ทธ ๋ชฉ์ ๊ณผ ์๋๋ฅผ ๋ํ๋ผ ์ ์๋ ๋ฉ์๋๋ฅผ ์ถ๊ฐํด์ผํจ.
// ========= ์์ข์ ์ฌ์ฉ์ ์ =========
public class Order {
public void setStatus(boolean status) {
this.status = status;
}
}
public void ์ฃผ๋ฌธ์๋น์ค์_์ทจ์์ด๋ฒคํธ() {
order.setStatus(false);
}
// ========= ์ฌ๋ฐ๋ฅธ ์ฌ์ฉ ์ =========
public class Order {
public void cancelOrder() {
this.status = false;
}
}
public void ์ฃผ๋ฌธ์๋น์ค์_์ทจ์์ด๋ฒคํธ() {
order.cancelOrder(false);
}๊ธฐ๋ณธ์ Setter๋ฅผ ์์์ผ๋ก์จ ์๋์ผ๋ก ๋๋น์ ๋ฐ์์ด ์๋์ง๋ง ๊ธฐ๋ณธ์ ์ธ ๊ตฌ์กฐ๋ ์์ฑ์๋ฅผ ํตํด ์ต์ข ๊ฐ์ ์ฑ์ด ํ DB์ ์ฝ์ ํ๋ ๋ฐฉ์์ผ๋ก ๋ณ๊ฒฝํ๋ฉฐ ํด๋น ์ด๋ฒคํธ์ ๋ง๋ public ๋ฉ์๋๋ฅผ ํธ์ถ ํ์ฌ ๋ณ๊ฒฝํ๋ ๊ฒ์ ์ ์ ๋กํ๋ค.
Entity์ ๊ฐ์ด ๋ณ๊ฒฝ๋๋ฉด JPA์ ์์์ฑ ์ปจํ ์คํธ์์ ๋ํฐ ์ฒดํน์ํ์ฌ ์๋์ผ๋ก update ์ฟผ๋ฆฌ๋ฅผ ๋ ๋ ค์ค๋ค. ๋ํฐ ์ฒดํน์ด๋?
- Web Layer
์ปจํธ๋กค๋ฌ(@Controller),JSP/Freemarker๋ฑ์ ๋ทฐ ํ ํ๋ฆฟ ์์ญ- ์ด์ธ์๋
ํํฐ(@Filter),์ธํฐ์ ํฐ,์ปจํธ๋กค๋ฌ ์ด๋๋ฐ์ด์ค(@ControllerAdvice)๋ฑ ์ธ๋ถ ์์ฒญ๊ณผ ์๋ต์ ๋ํ ์ ๋ฐ์ ์ธ ์์ญ
- Service Layer
- @Service์ ์ฌ์ฉ๋๋ ์์ญ
- Controller, Dao ์ค๊ฐ์์ญ
- @Transactional์ด ์ฌ์ฉ๋์ด์ผ ํ๋ ์์ญ
- Repository Layer
- Database์ ๊ฐ์ด ๋ฐ์ดํฐ ์ ์ฅ์์ ์ ๊ทผํ๋ ์์ญ == DAO (Data Access Object)
- Dtos
- Dto(Data Transfer Object)๋ ๊ณ์ธต๊ฐ์ ๋ฐ์ดํฐ ๊ตํ์ ์ํ ๊ฐ์ฒด๋ฅผ ์ด์ผ๊ธฐํ๋ฉฐ Dtos๋ ์ด๋ค์ ์์ญ
- Domain Model
- ๋๋ฉ์ธ์ด๋ผ ๋ถ๋ฆฌ๋ ๊ฐ๋ฐ ๋์์ ๋ชจ๋ ์ฌ๋์ด ๋์ผํ ๊ด์ ์์ ์ดํดํ ์ ์๊ณ ๊ณต์ ํ ์ ์๋๋ก ๋จ์ํ ์ํจ ๊ฒ
- Entity๊ฐ ์ฌ์ฉ๋ ์์ญ์ด ๋๋ฉ์ธ ๋ชจ๋ธ
- ๋ฌด์กฐ๊ฑด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํ ์ด๋ธ๊ณผ ๊ด๊ณ๊ฐ ์์ด์ผ๋ง ํ๋ ๊ฒ์ ์๋ (VO์ฒ๋ผ ๊ฐ ๊ฐ์ฒด๋ค๋ ์ด ์์ญ์ ํด๋น)
๋น์ง๋์ค ๋ชจ๋ธ์ ์ฒ๋ฆฌํด์ผ ํ๋ ์์ญ์ Domain์ด๋ค.
// ์๋น์ค ํด๋์ค์์ ๋น์ฆ๋์ค ๋ก์ง์ ์ฒ๋ฆฌํ ์์ข์ ์
@Transactional
public Order cancelOrder(int orderId) {
OrdersDto order = ordersDao.selectOrders(orderId);
BillingDto billing = billingDao.selectBillint(orderId);
DeliveryDto delivery = deliveryDao.selectDelivery(orderId);
String deliveryStatus = delivery.getStatus();
if ("IN_PROGRESS".equals(deliveryStatus)) {
delivery.setStatus("CANCEL");
deliveryDao.update(delivery);
}
order.setStatus("CANCEL");
orderDao.update(order);
billing.setStatus("CANCEL");
deliveryDao.update(billing);
return order;
}์ ์ฝ๋๋ ๋ชจ๋ ๋ก์ง์ด ์๋น์ค ํด๋์ค ๋ด๋ถ์์ ์ฒ๋ฆฌ๋๋ค. ๊ทธ๋ฌ๋ค๋ณด๋ ์๋น์ค ๊ณ์ธต์ด ๋ฌด์๋ฏธํ๋ฉฐ, ๊ฐ์ฒด๋ ๋จ์ํ ๋ฉ์ด๋ฆฌ ์ญํ ๋ง ํ๊ฒ๋จ. ๋ฐ๋ฉด ๋๋ฉ์ธ ๋ชจ๋ธ์์ ์ฒ๋ฆฌํ ๊ฒฝ์ฐ ๋ค์๊ณผ ๊ฐ์ ์ฝ๋๋ก ๋ณํ์ด ๋๋ค.
@Transactional
public Order cancelOrder(int orderId) {
Orders order = orderRepository.findById(orderId);
Billing billing = billingRepository.findByOrderId(orderId);
Delivery delivery = deliveryRepository.findByOrderId(orderId);
delivery.cancel();
order.cancel();
billing.cancel();
return order;
}Entity ํด๋์ค๋ Database์ ๋ง๋ฟ์์๋ ํต์ฌ ํด๋์ค์ด๋ค. Entity ํด๋์ค๋ฅผ ๊ธฐ์ค์ผ๋ก ํ ์ด๋ธ์ด ์์ฑ๋๊ณ , ์คํค๋ง๊ฐ ๋ณ๊ฒฝ๋๋ค. ํ๋ฉด ๋ณ๊ฒฝ์ ์์ฃผ ์ฆ๊ณ ์ฌ์ํ ๋ณ๊ฒฝ๋ค์ด ๋ง์ Entity๋ฅผ ๊ณ์ ์์ ํ๋๊ฒ์ ๋ฌธ์ ๊ฐ๋๋ค.
- ํ์
์์ ์ฑ์ด ๋ณด์ฅ
- ๋จ์ํ ๋ฌธ์์ด๋ก ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๋ ๊ฒ์ด ์๋๋ผ, ๋ฉ์๋๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ฟผ๋ฆฌ๋ฅผ ์์ฑ
- ์คํ๋ ์กด์ฌํ์ง ์๋ ์ปฌ๋ผ๋ช ์ ๋ช ์ํ ๊ฒฝ์ฐ IDE์์ ์๋์ผ๋ก ๊ฒ์ถ
- ์ด ์ฅ์ ์ jooq์์๋ ์ง์ํ๋ ์ฅ์ ์ด์ง๋ง MyBatis์์๋ ์ง์ํ์ง ์์
- ๊ตญ๋ด ๋ง์ ํ์ฌ์์ ์ฌ์ฉ ์ค
- ์ฟ ํก, ๋ฐฐ๋ฏผ ๋ฑ JPA๋ฅผ ์ ๊ทน์ ์ผ๋ก ์ฌ์ฉํ๋ ํ์ฌ์์๋ Querydsl๋ฅผ ์ ๊ทน์ ์ผ๋ก ์ฌ์ฉ
- ๋ง์ ๋ ํผ๋ฐ์ค
- ๋ง์ ํ์ฌ์ ๊ฐ๋ฐ์๋ค์ด ์ฌ์ฉํ๋ค๋ณด๋ ๊ทธ๋งํผ ๊ตญ๋ด ์๋ฃ๊ฐ ๋ง์