개발/도서

백엔드 서비스 아키텍처 - 2

괴발자-K 2022. 8. 10. 13:23

1. 서비스 레이어 : 비즈니스 로직

서비스 레이어는 컨트롤러와 퍼시스턴스 사이에서 지즈니스 로직을 수행하는 역할을 한다

즉, 컨트롤러와 분리돼 있고 퍼시스턴스와도 분리돼 있다. 따라서 개발하는 로직에 집중이 가능하다

 

TodoService

@Service
public class TodoService {

	public String testService() {
		 
         return "test Service";
	}

@Service 어노테이션은 스테레오타입 어노테이션이다.

기능적으로 비즈니스로직을 수행하는 서비스 레이어임을 알려주는 어노테이션이다.

 

TodoController

@RestController
@RequestMapping("todo")
public class TodoController {

	@Autowired
	private TodoService service;

	@GetMapping("/test")
	public ResponseEntity<?> testTodo() {
		String str = service.testService(); // 테스트 서비스 사용
		List<String> list = new ArrayList<>();
		list.add(str);
		ResponseDTO<String> response = ResponseDTO.<String>builder().data(list).build();
		// ResponseEntity.ok(response) 를 사용해도 상관 없음
		return ResponseEntity.ok().body(response);
	}

TodoController 오브젝트를 생성할 때 TodoController 내부에 선언된  @Autowired 어노테이션은 빈을 찾은

다음 그 빈을 인스턴스 멤버 변수에 연결하라는 뜻이다. 그러므로 TestController를 초기화할 때 스프링은

알아서 TodoService를 초기화 또는 검색해 TodoController에 주입 한다.

 

2. 퍼시스턴스 레이어 : 스프링 데이터 JPA

스프링 JPA + 알파, JPA를 더 사용하기 쉽게 도와주는 스프링의 프로젝트인데 기술적으로 이를 추상화 했다고 

한다. 추상화했다는 것은 사용하기 쉬운 인터페이스를 제공한다는 것이다. 

 

설정

데이터베이스는 Spring Intializr에서 추가 했던 H2를 사용

H2는 In-Memroy 데이터베이스로 로컬 환경에서 메모리상에 데이터베이스를 구축

runtimeOnly 'com.h2database:h2'

 

스프링 데이터 JPA를 사용하려면 spring-boot-starter-jpa 라이브러리가 필요

implementation 'org.springframework.boot::spring-boot-starter-data-jpa'

 

TodoEntity

Todo 테이블에 사응하는 TodoEntity가 존재

하나의 엔티티 인스턴스는 데이터베이스 테이블의 한 행에 해당

자바 클래스를 엔티티로 정의할 때 주의점 

  • 매개변수가 없는 생성자. NoArgConstrutor 필요
  • Getter/Setter가 필요
  • 기본키 지정
package com.example.demo.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.GenericGenerator;

@Builder
@NoArgsConstructor
@AllArgsConstructor
@Data
@Entity
@Table(name = "Todo")
public class TodoEntity {
	@Id
	@GeneratedValue(generator="system-uuid")
	@GenericGenerator(name="system-uuid", strategy = "uuid")
	private String id;
	private String userId;
	private String title;
	private boolean done;
}
  • @Table(name="Todo") : 이 엔티티는 데이터베이스의 Todo 테이블에 매핑된다는 의미
    • @Table 명시하지 않거나 name을 주지 않으면 @Entity 이름으로 지정
    • @Entity의 이름을 지정하짐 않으면 클래스의 이름을 테이블 이름으로 자동 간주
  • @Id는 기본키 필드명에 지정
  • @GeneratedValue : ID를 자동으로 생성하겠다. generator로 어떤 방식으로 ID를 생성할지 지정
    • INCREMENTAL, SEQUENCE, IDENTITY 등 
  •  system-uuid는 hibernate가 제공하는 기본 Generator가 아니라 커스텀으로 만들어서 사용
  • @GenericGenerator의 매개변수 strategy로 "uuid", uuid를 사용하는 "system-uuid" 라는 이름의 GenericGenerator를 만들었고, @GenerateValue 참조해 사용

TodoRepository

package com.example.demo.persistence;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.example.demo.model.TodoEntity;

import java.util.List;

@Repository
public interface TodoRepository extends JpaRepository<TodoEntity, String>{
	List<TodoEntity> findByUserId(String userId);
}
  • JpaRepository는 인터페이스다.  인터페이스를 사용하기 위해서는 확장(extends)필요.
  • JpaRepostiory<T, ID> : 첫 번째 매개변수 T는 테이블에 매핑될 엔티티 클래스, 두번째 ID는 기본키 필드의 타입을 넣어준다.
  • @Repository : DB 접근하는 모든 코드가 모여있는 곳을 의미

TodoService에서 TodoRepository 사용

@Service
public class TodoService {

	@Autowired
	private TodoRepository repository;

	public String testService() {
		// TodoEntity 생성
		TodoEntity entity = TodoEntity.builder().title("My first todo item").build();
		// TodoEntity 저장
		repository.save(entity);
		// TodoEntity 검색
		TodoEntity savedEntity = repository.findById(entity.getId()).get();
		return savedEntity.getTitle();
	}
}

 

 

이상