DAO(Data Access Object)는 데이터베이스나 다른 영구 저장소에 대한 접근을 추상화하여, 비즈니스 로직과 데이터 접근 로직을 분리하는 설계 패턴입니다. DAO 패턴은 애플리케이션의 데이터 저장 및 조회 기능을 담당하는 객체들을 정의하고, 이들을 통해 데이터베이스의 데이터를 조작하는 역할을 합니다.
DAO의 주요 개념
- 데이터 접근 추상화: DAO는 데이터베이스와 같은 영구 저장소에 접근하는 방법을 추상화하여, 데이터 접근 로직을 비즈니스 로직으로부터 분리합니다. 이를 통해 비즈니스 로직은 데이터가 어디에서 어떻게 저장되는지 신경 쓰지 않고, 오직 DAO를 통해서만 데이터를 조작할 수 있습니다.
- CRUD 작업: DAO는 주로 Create, Read, Update, Delete (CRUD) 작업을 수행합니다. 데이터베이스와 상호작용하여 엔티티를 생성, 조회, 수정, 삭제하는 기능을 제공합니다.
- 재사용성: DAO는 데이터 접근 로직을 중앙화하여 코드의 재사용성을 높입니다. 또한, 데이터베이스와 상호작용하는 코드를 한 곳에서 관리할 수 있어 유지보수가 용이합니다.
- 데이터베이스 독립성: DAO 패턴을 사용하면 데이터베이스에 대한 의존성을 줄일 수 있습니다. 데이터베이스를 교체하거나 수정할 때 DAO만 수정하면 되므로, 애플리케이션의 다른 부분에 영향을 주지 않습니다.
DAO 패턴의 구성 요소
- DAO 인터페이스: 데이터 접근 객체가 수행해야 할 메서드를 정의합니다. 예를 들어, save(),findById(),findAll(),update(),delete()등의 메서드가 포함될 수 있습니다.
- DAO 구현 클래스: DAO 인터페이스를 구현하여 실제 데이터베이스 작업을 수행하는 클래스입니다. 예를 들어, JDBC, JPA, Hibernate 등을 사용하여 데이터베이스와 상호작용합니다.
- 엔티티 클래스: 데이터베이스 테이블과 매핑되는 클래스입니다. 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