Post

[Spring] DAO 패턴 vs Repository 패턴

[Spring] DAO 패턴 vs Repository 패턴

이번 글에서는 데이터 접근 로직과 비즈니스 로직을 분리하는 대표적인 디자인 패턴인 Dao패턴과 Repository패턴에 대해 간단히 알아보겠습니다.

Repository 패턴


레퍼지토리 패턴은 객체 지향 설계의 원칙을 따르며, 데이터 접근 로직과 비즈니스 로직을 분리하는 데 중점을 둡니다. 이는 주로 도메인 주도 설계(DDD)에서 사용되며, 도메인 객체의 컬렉션을 관리하는 개념을 제공합니다. 레퍼지토리는 데이터베이스의 구체적인 구현 세부 사항을 추상화하여 비즈니스 로직이 데이터 접근 방법에 종속되지 않도록 합니다.

예시 (Java, Spring Data JPA 사용)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// User 엔티티 클래스
@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String email;
    
    // Getters and Setters
}

// UserRepository 인터페이스
public interface UserRepository extends JpaRepository<User, Long> {
    // 추가적인 사용자 정의 메서드
}

// UserService 클래스
@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;
    
    public User registerUser(String name, String email) {
        User user = new User();
        user.setName(name);
        user.setEmail(email);
        return userRepository.save(user);
    }
    
    public List<User> getAllUsers() {
        return userRepository.findAll();
    }
    
    public User getUserById(Long id) {
        return userRepository.findById(id).orElse(null);
    }
}

// UserController 클래스
@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserService userService;
    
    @PostMapping
    public User registerUser(@RequestBody User user) {
        return userService.registerUser(user.getName(), user.getEmail());
    }
    
    @GetMapping
    public List<User> getAllUsers() {
        return userService.getAllUsers();
    }
    
    @GetMapping("/{id}")
    public User getUserById(@PathVariable Long id) {
        return userService.getUserById(id);
    }
}


DAO 패턴


DAO 패턴은 데이터베이스와 상호작용하는 코드를 추상화하고 분리하는 데 중점을 둡니다. DAO는 데이터 접근 로직을 캡슐화하여, 데이터베이스와의 직접적인 상호작용을 서비스나 비즈니스 로직으로부터 분리합니다. 이는 주로 데이터베이스 테이블이나 쿼리에 대한 추상화를 제공합니다.

예시 (Java, JPA 사용)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// User 엔티티 클래스
@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String email;

    // Getters and Setters
}

// UserDao 인터페이스
public interface UserDao {
    void save(User user);
    User findById(Long id);
    List<User> findAll();
    void update(User user);
    void deleteById(Long id);
}

// UserDaoImpl 클래스
@Repository
@Transactional
public class UserDaoImpl implements UserDao {
    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public void save(User user) {
        entityManager.persist(user);
    }

    @Override
    public User findById(Long id) {
        return entityManager.find(User.class, id);
    }

    @Override
    public List<User> findAll() {
        return entityManager.createQuery("from User", User.class).getResultList();
    }

    @Override
    public void update(User user) {
        entityManager.merge(user);
    }

    @Override
    public void deleteById(Long id) {
        User user = findById(id);
        if (user != null) {
            entityManager.remove(user);
        }
    }
}

// UserService 클래스
@Service
public class UserService {
    @Autowired
    private UserDao userDao;

    public User registerUser(String name, String email) {
        User user = new User();
        user.setName(name);
        user.setEmail(email);
        userDao.save(user);
        return user;
    }

    public List<User> getAllUsers() {
        return userDao.findAll();
    }

    public User getUserById(Long id) {
        return userDao.findById(id);
    }

    public void updateUser(User user) {
        userDao.update(user);
    }

    public void deleteUser(Long id) {
        userDao.deleteById(id);
    }
}

// UserController 클래스
@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserService userService;

    @PostMapping
    public User registerUser(@RequestBody User user) {
        return userService.registerUser(user.getName(), user.getEmail());
    }

    @GetMapping
    public List<User> getAllUsers() {
        return userService.getAllUsers();
    }

    @GetMapping("/{id}")
    public User getUserById(@PathVariable Long id) {
        return userService.getUserById(id);
    }

    @PutMapping
    public void updateUser(@RequestBody User user) {
        userService.updateUser(user);
    }

    @DeleteMapping("/{id}")
    public void deleteUser(@PathVariable Long id) {
        userService.deleteUser(id);
    }
}


공통점과 차이점


  • 공통점

    • 비즈니스 로직과 데이터 접근 로직의 분리

      두 패턴 모두 비즈니스 로직과 데이터 접근 로직을 분리하여 유지 보수성을 높입니다.

    • 추상화

      데이터베이스와 상호작용하는 코드를 추상화하여, 서비스 계층이 데이터베이스 접근 방법에 종속되지 않도록 합니다.


  • 차이점

    • 객체 지향 설계의 원칙

      • 레퍼지토리 패턴

        객체 지향 설계 원칙을 더욱 엄격하게 따르며, 도메인 모델과의 상호작용을 추상화합니다. 주로 도메인 주도 설계(DDD)에서 사용됩니다.

      • DAO 패턴

        데이터 접근 로직을 단순히 추상화하는 데 중점을 둡니다. 데이터베이스 테이블이나 쿼리에 더 가까운 추상화를 제공합니다.


읽어주셔서 감사합니다. 😊

Reference
ChatGPT - OpenAI

This post is licensed under CC BY 4.0 by the author.