Skip to content

Latest commit

ย 

History

History
157 lines (129 loc) ยท 6.07 KB

File metadata and controls

157 lines (129 loc) ยท 6.07 KB

Spring Data JPA

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;
    }
}
  1. @Entity
    • ํ…Œ์ด๋ธ”๊ณผ ๋งํฌ๋  ํด๋ž˜์Šค
    • ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ํด๋ž˜์Šค์˜ ์นด๋ฉœ์ผ€์ด์Šค ์ด๋ฆ„์„ ์–ธ๋”์Šค์ฝ”์–ด ๋„ค์ด๋ฐ์œผ๋กœ ํ…Œ์ด๋ธ” ์ด๋ฆ„์„ ๋งค์นญ (SalesManger.java -> sales_manager table)
  2. @Id
    • ํ•ด๋‹น ํ…Œ์ด๋ธ”์˜ PK ํ•„๋“œ
  3. @GeneratedValue

์›ฌ๋งŒํ•˜๋ฉด Entity์˜ PK๋Š” Long ํƒ€์ž…์˜ Auto_increment๋ฅผ ์ถ”์ฒœ

  1. FKํ‚ค๋ฅผ ๋งบ์„ ๋•Œ ๋‹ค๋ฅธ ํ…Œ์ด๋ธ”์—์„œ ๋ณตํ•ฉํ‚ค ์ „๋ถ€๋ฅผ ๊ฐ–๊ณ  ์žˆ๊ฑฐ๋‚˜, ์ค‘๊ฐ„ ํ…Œ์ด๋ธ”์„ ํ•˜๋‚˜ ๋” ๋‘ฌ์•ผ ํ•˜๋Š” ์ƒํ™ฉ์ด ๋ฐœ์ƒ
  2. ์ธ๋ฑ์Šค์— ์ข‹์€ ์˜ํ–ฅ์„ ๋ผ์น˜์ง€ ๋ชปํ•จ
  3. ์œ ๋‹ˆํฌํ•œ ์กฐ๊ฑด์ด ๋ณ€๊ฒฝ๋  ๊ฒฝ์šฐ PK ์ „์ฒด๋ฅผ ์ˆ˜์ •ํ•ด์•ผ ํ•˜๋Š” ์ผ์ด ๋ฐœ์ƒ

์ฃผ๋ฏผ๋“ฑ๋ก๋ฒˆํ˜ธ, ๋ณตํ•ฉํ‚ค ๋“ฑ์€ ์œ ๋‹ˆํฌ ํ‚ค๋กœ ๋ณ„๋„๋กœ ์ถ”๊ฐ€ํ•˜๋Š”๊ฒƒ์„ ์ถ”์ฒœ

Entity ํด๋ž˜์Šค์—๋Š” Setter ๊ธˆ์ง€

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 ์ฟผ๋ฆฌ๋ฅผ ๋‚ ๋ ค์ค€๋‹ค. ๋”ํ‹ฐ ์ฒดํ‚น์ด๋ž€?

CRUD API

Spring Layer

  • 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;
}

ํ™”๋ฉด์— ๋„˜๊ธฐ๋Š” Data์— DTO๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ 

Entity ํด๋ž˜์Šค๋Š” Database์™€ ๋งž๋‹ฟ์•„์žˆ๋Š” ํ•ต์‹ฌ ํด๋ž˜์Šค์ด๋‹ค. Entity ํด๋ž˜์Šค๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํ…Œ์ด๋ธ”์ด ์ƒ์„ฑ๋˜๊ณ , ์Šคํ‚ค๋งˆ๊ฐ€ ๋ณ€๊ฒฝ๋œ๋‹ค. ํ™”๋ฉด ๋ณ€๊ฒฝ์€ ์•„์ฃผ ์žฆ๊ณ  ์‚ฌ์†Œํ•œ ๋ณ€๊ฒฝ๋“ค์ด ๋งŽ์•„ Entity๋ฅผ ๊ณ„์† ์ˆ˜์ •ํ•˜๋Š”๊ฒƒ์€ ๋ฌธ์ œ๊ฐ€๋œ๋‹ค.

Querydsl

  1. ํƒ€์ž… ์•ˆ์ •์„ฑ์ด ๋ณด์žฅ
    • ๋‹จ์ˆœํ•œ ๋ฌธ์ž์—ด๋กœ ์ฟผ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ๋ฉ”์†Œ๋“œ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ฟผ๋ฆฌ๋ฅผ ์ƒ์„ฑ
    • ์˜คํƒ€๋‚˜ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ์ปฌ๋Ÿผ๋ช…์„ ๋ช…์‹œํ•  ๊ฒฝ์šฐ IDE์—์„œ ์ž๋™์œผ๋กœ ๊ฒ€์ถœ
    • ์ด ์žฅ์ ์€ jooq์—์„œ๋„ ์ง€์›ํ•˜๋Š” ์žฅ์ ์ด์ง€๋งŒ MyBatis์—์„œ๋Š” ์ง€์›ํ•˜์ง€ ์•Š์Œ
  2. ๊ตญ๋‚ด ๋งŽ์€ ํšŒ์‚ฌ์—์„œ ์‚ฌ์šฉ ์ค‘
    • ์ฟ ํŒก, ๋ฐฐ๋ฏผ ๋“ฑ JPA๋ฅผ ์ ๊ทน์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ํšŒ์‚ฌ์—์„œ๋Š” Querydsl๋ฅผ ์ ๊ทน์ ์œผ๋กœ ์‚ฌ์šฉ
  3. ๋งŽ์€ ๋ ˆํผ๋Ÿฐ์Šค
    • ๋งŽ์€ ํšŒ์‚ฌ์™€ ๊ฐœ๋ฐœ์ž๋“ค์ด ์‚ฌ์šฉํ•˜๋‹ค๋ณด๋‹ˆ ๊ทธ๋งŒํผ ๊ตญ๋‚ด ์ž๋ฃŒ๊ฐ€ ๋งŽ์Œ