Java 일반적인 폴더 구조Java 폴더 구조Java 패턴Java MVC PatternJava MVC 패턴

Java 일반적인 폴더 구조

KUKJIN LEE
KUKJIN LEE
2024년 5월 2일
154
src/
└── main/
    └── java/
        └── com/
            └── example/
                └── myproject/
                    ├── controller/    # HTTP 요청을 처리
                    ├── repository/    # 데이터베이스 접근 로직
                    ├── service/       # 비즈니스 로직
                    ├── model/         # 도메인 모델 (또는 entity)
                    └── dto/           # 데이터 전송 객체

 

Java 프로젝트에서 널리 채택된 폴더 구조와 관련하여, Spring Boot와 함께 JPA와 PostgreSQL을 사용하는 경우를 예로 들어 설명하겠습니다.

 

1. Controller

Controller는 클라이언트의 HTTP 요청을 받아 처리하고, 응답을 반환하는 역할을 합니다.

 

package com.example.myproject.controller;
import com.example.myproject.dto.UserDto;
import com.example.myproject.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserService userService;
    @GetMapping("/{id}")
    public UserDto getUserById(@PathVariable Long id) {
        return userService.getUserById(id);
    }
    @PostMapping
    public UserDto createUser(@RequestBody UserDto userDto) {
        return userService.createUser(userDto);
    }
}

 

2. Repository

Repository는 데이터베이스와의 상호작용을 담당합니다. Spring Data JPA를 사용하면 인터페이스만 정의하면 기본 CRUD 연산을 자동으로 구현해줍니다.

 

Repository와 DAO의 차이

UserRepository가 별도의 구현 코드를 명시하지 않아도 JpaRepository를 상속받음으로써 자동으로 여러 CRUD 관련 메서드들을 사용할 수 있게 됩니다. 이는 Spring Data JPA의 큰 장점 중 하나로, 기본적인 데이터 접근 작업을 위한 구현 코드를 작성할 필요가 없게 만들어 줍니다.

  • Repository: Spring Data JPA에서 사용하는 개념으로, 데이터베이스와의 상호작용을 추상화한 인터페이스입니다. Repository 인터페이스를 정의하고, Spring Data JPA가 제공하는 JpaRepository 인터페이스를 상속받으면, Spring이 자동으로 구현체를 생성해줍니다. 이를 통해 데이터 접근 로직을 쉽게 구현할 수 있습니다.

  • DAO (Data Access Object): 데이터 접근 객체라고 하며, 데이터베이스의 CRUD 연산을 수행하는 메서드를 제공합니다. 전통적인 DAO 패턴에서는 DAO 클래스가 직접 구현되며, JDBC 코드나 JPA 코드를 포함할 수 있습니다. Repository는 DAO의 개념을 더 발전시킨 것으로 볼 수 있으며, DAO보다 더 고수준의 추상화를 제공합니다.

 

package com.example.myproject.repository;
import com.example.myproject.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
}

 

3. Service

Service 계층은 비즈니스 로직을 포함합니다. 이곳에서 데이터의 검증, 변환 등의 작업을 수행합니다.

 

package com.example.myproject.service;
import com.example.myproject.dto.UserDto;
import com.example.myproject.model.User;
import com.example.myproject.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;
    public UserDto getUserById(Long id) {
        User user = userRepository.findById(id).orElseThrow(() -> new RuntimeException("User not found"));
        return new UserDto(user.getId(), user.getName(), user.getEmail());
    }
    public UserDto createUser(UserDto userDto) {
        User user = new User();
        user.setName(userDto.getName());
        user.setEmail(userDto.getEmail());
        user = userRepository.save(user);
        return new UserDto(user.getId(), user.getName(), user.getEmail());
    }
}

 

4. Model (Entity)

Model 또는 Entity는 데이터베이스의 테이블에 해당하는 Java 클래스입니다.

 

Model (Entity): JPA를 사용할 때, 데이터베이스의 테이블과 매핑되는 Java 클래스를 말합니다. 이 클래스는 @Entity 어노테이션으로 표시되며, JPA가 이 클래스의 인스턴스를 데이터베이스 테이블의 레코드로 관리할 수 있도록 합니다. 필드명은 테이블의 컬럼에 대응됩니다.

 

package com.example.myproject.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import lombok.Getter;
import lombok.Setter;
@Entity
@Getter
@Setter
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String email;
}

5. DTO (Data Transfer Object)

DTO는 계층 간 데이터 전송에 사용되는 객체입니다. 예를 들어, 클라이언트와 서버 간의 데이터 교환에 사용됩니다.

 

DTO와 VO의 차이 (Data Transfer Object)와 (Value Object)

  • DTO (Data Transfer Object): 계층 간 데이터 교환을 위해 사용되는 객체입니다. 예를 들어, 클라이언트에서 서버로 데이터를 전송할 때 또는 서버에서 클라이언트로 데이터를 응답할 때 사용됩니다. DTO는 보통 데이터의 전송에 초점을 맞추어 설계됩니다.

  • VO (Value Object): 값 객체라고 하며, 도메인의 개념을 표현하는 데 사용됩니다. VO는 불변성(immutable)을 가질 수 있으며, 동등성(equality)이 객체의 식별성(identity)이 아니라 값에 의해 결정됩니다. VO는 때로 DTO와 유사한 역할을 수행할 수 있지만, 설계상의 목적과 사용 방식에서 차이가 있습니다.

@Getter@Setter 를 사용하면 혁명적으로 코드를 줄일 수 있습니다. Lombok 덕분에 별도로 Getter와 Setter를 작성하지 않아도 됩니다.

 

package com.example.myproject.dto;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@NoArgsConstructor  // 기본 생성자를 자동으로 생성합니다.
@AllArgsConstructor // 모든 필드 값을 파라미터로 받는 생성자를 자동으로 생성합니다.
public class UserDto {
    private Long id;
    private String name;
    private String email;
}

관련 글

[SQL 입문] 필요한 데이터만 콕 집어 가져올 수 있는 WHERE 절

사용자는 테이블에 있는 모든 데이터를 다 보고 싶어 하지는 않습니다. 오히려 특정 항목에 대한 데이터만 가져오고 싶을 때가 훨씬 많습니다. 예를 들어, 어떤 사용자의 이메일이나 ID는 알고 있는데, 그 사람이 언제 우리 앱에 가입했는지 확인하고 싶다고 가정해 봅시다...

2026년 1월 27일10

SQL에서 SELECT란 무엇인가?

데이터베이스를 거대한 서류 보관함이라고 생각하면 됩니다. 보관함 안에는 수많은 데이터가 차곡차곡 쌓입니다. SELECT는 이 보관함에서 "내가 원하는 정보를 찾아줘!"라고 요청하는 명령어입니다. 이 과정을 전문 용어로 '쿼리(Query)'라고 부릅니다. &amp;nbs...

2026년 1월 26일10

[SQL 기초] "언제 하나씩 다 넣어?" 데이터 한 번에 넣기

개발을 하다 보면 데이터베이스(DB)에 샘플 데이터를 대량으로 넣어야 할 때가 있습니다. 메뉴 100개를 추가해야 하는데 INSERT 문을 100번 쓰고 있다면? 너무 비효율적이죠! 오늘은 SQL에서 여러 데이터를 한 번에 넣는 '다중 삽입(Multiple Inse...

2026년 1월 21일13

SQL 데이터 삽입하기

데이터가 없는 데이터베이스는 연료 없는 로켓과 같습니다. 이제 'Missions' 테이블에 새로운 행(row)을 추가하는 방법을 알아보겠습니다. "삽입(Inserting)"은 '데이터 추가'를 의미합니다. 기존 Missions 테이블 ...

2026년 1월 20일12