DAO

허성재's avatar
Aug 21, 2024
DAO
DAO(Data Access Object)는 데이터베이스나 다른 영구 저장소에 대한 접근을 추상화하여, 비즈니스 로직과 데이터 접근 로직을 분리하는 설계 패턴입니다. DAO 패턴은 애플리케이션의 데이터 저장 및 조회 기능을 담당하는 객체들을 정의하고, 이들을 통해 데이터베이스의 데이터를 조작하는 역할을 합니다.

DAO의 주요 개념

  1. 데이터 접근 추상화: DAO는 데이터베이스와 같은 영구 저장소에 접근하는 방법을 추상화하여, 데이터 접근 로직을 비즈니스 로직으로부터 분리합니다. 이를 통해 비즈니스 로직은 데이터가 어디에서 어떻게 저장되는지 신경 쓰지 않고, 오직 DAO를 통해서만 데이터를 조작할 수 있습니다.
  1. CRUD 작업: DAO는 주로 Create, Read, Update, Delete (CRUD) 작업을 수행합니다. 데이터베이스와 상호작용하여 엔티티를 생성, 조회, 수정, 삭제하는 기능을 제공합니다.
  1. 재사용성: DAO는 데이터 접근 로직을 중앙화하여 코드의 재사용성을 높입니다. 또한, 데이터베이스와 상호작용하는 코드를 한 곳에서 관리할 수 있어 유지보수가 용이합니다.
  1. 데이터베이스 독립성: DAO 패턴을 사용하면 데이터베이스에 대한 의존성을 줄일 수 있습니다. 데이터베이스를 교체하거나 수정할 때 DAO만 수정하면 되므로, 애플리케이션의 다른 부분에 영향을 주지 않습니다.

DAO 패턴의 구성 요소

  1. DAO 인터페이스: 데이터 접근 객체가 수행해야 할 메서드를 정의합니다. 예를 들어, save(), findById(), findAll(), update(), delete() 등의 메서드가 포함될 수 있습니다.
  1. DAO 구현 클래스: DAO 인터페이스를 구현하여 실제 데이터베이스 작업을 수행하는 클래스입니다. 예를 들어, JDBC, JPA, Hibernate 등을 사용하여 데이터베이스와 상호작용합니다.
  1. 엔티티 클래스: 데이터베이스 테이블과 매핑되는 클래스입니다. DAO는 이 엔티티 객체를 사용하여 데이터베이스와 데이터를 주고받습니다.

DAO의 예제 코드 (Java)

간단한 예제로, User 엔티티를 관리하는 DAO를 만들어 보겠습니다.
// User 엔티티 클래스 public class User { private Long id; private String name; private String email; // getters and setters } // DAO 인터페이스 public interface UserDao { void save(User user); User findById(Long id); List<User> findAll(); void update(User user); void delete(Long id); } // DAO 구현 클래스 (JDBC 사용 예) public class UserDaoImpl implements UserDao { private Connection connection; public UserDaoImpl(Connection connection) { this.connection = connection; } @Override public void save(User user) { String sql = "INSERT INTO users (name, email) VALUES (?, ?)"; try (PreparedStatement stmt = connection.prepareStatement(sql)) { stmt.setString(1, user.getName()); stmt.setString(2, user.getEmail()); stmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } } @Override public User findById(Long id) { String sql = "SELECT * FROM users WHERE id = ?"; try (PreparedStatement stmt = connection.prepareStatement(sql)) { stmt.setLong(1, id); ResultSet rs = stmt.executeQuery(); if (rs.next()) { User user = new User(); user.setId(rs.getLong("id")); user.setName(rs.getString("name")); user.setEmail(rs.getString("email")); return user; } } catch (SQLException e) { e.printStackTrace(); } return null; } @Override public List<User> findAll() { List<User> users = new ArrayList<>(); String sql = "SELECT * FROM users"; try (Statement stmt = connection.createStatement()) { ResultSet rs = stmt.executeQuery(sql); while (rs.next()) { User user = new User(); user.setId(rs.getLong("id")); user.setName(rs.getString("name")); user.setEmail(rs.getString("email")); users.add(user); } } catch (SQLException e) { e.printStackTrace(); } return users; } @Override public void update(User user) { String sql = "UPDATE users SET name = ?, email = ? WHERE id = ?"; try (PreparedStatement stmt = connection.prepareStatement(sql)) { stmt.setString(1, user.getName()); stmt.setString(2, user.getEmail()); stmt.setLong(3, user.getId()); stmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } } @Override public void delete(Long id) { String sql = "DELETE FROM users WHERE id = ?"; try (PreparedStatement stmt = connection.prepareStatement(sql)) { stmt.setLong(1, id); stmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } } }

DAO 패턴의 장점

  • 유지보수성: 데이터 접근 로직이 분리되어 있어 변경이 필요할 때 비즈니스 로직에 영향을 주지 않습니다.
  • 재사용성: DAO 클래스는 다양한 곳에서 재사용될 수 있습니다.
  • 테스트 용이성: DAO 패턴을 사용하면 데이터베이스와의 상호작용을 모의(Mock) 객체로 대체할 수 있어 단위 테스트가 용이합니다.

DAO 패턴의 단점

  • 복잡성 증가: 애플리케이션 규모가 커질수록 DAO 클래스가 많아져 복잡성이 증가할 수 있습니다.
  • 추상화에 따른 성능 손실: 높은 수준의 추상화는 때때로 성능 손실을 야기할 수 있습니다.

결론

DAO는 데이터 접근 로직을 캡슐화하고, 비즈니스 로직과 분리하여 코드를 더 유지보수하기 쉽게 만드는 유용한 패턴입니다. 특히 데이터베이스와의 상호작용이 많은 애플리케이션에서 DAO 패턴을 사용하면, 코드의 재사용성, 모듈화, 테스트 가능성을 크게 높일 수 있습니다.
Share article

heo-gom