글 작성자: beaniejoy

 지난번에는 JDBC 연결과 함께 기본적인 SQL문을 날리는 방법에 대해서 정리해보았습니다. 지난 시간에 이어서 이번에는 JDBC를 더욱 효율적으로 작동하게 만드는 DAO와 DTO에 대해서 정리해보고자 합니다. 혹시 지난 JDBC의 기본에 대한 정리글을 아직 못보신 분들이라면

[Java] JDBC를 통한 database 접근(MariaDB) 링크를 클릭하셔서 먼저 보시고 이번 게시글을 보시는 것을 추천합니다! 한번 시작해볼까요?

 

[Java] JDBC를 통한 database 접근(MariaDB)

Java는 정말 다양한 기능을 수행할 수 있다는 장점이 있는데 JDBC도 그 중 하나다. JDBC(Java Database Connectivity)는 자바가 DB에 접근해서 데이터를 처리할 수 있도록 연결해주는 인터페이스라고 할 수

beaniejoy.tistory.com

 

 

📌 1. DAO, DTO의 개념

 저는 이제 개발을 시작하려는 초보자이기도 하고 교육을 듣는 과정에 있기 때문에 교육시간에 배웠던 DAO, DTO를 쉽게 정리해보려 합니다. 틀린 내용이 있을 수 있으니 언제든 피드백해주시면 정말 감사하겠습니다! 

 

 

🔖 DAO (Data Access Object): 하나로 통합해서 관리하자!

 우선 DAO의 개념부터 볼까요? DAO는 Data Access Object의 약자입니다. 뭔가 "데이터를 접근하는데 쓰이는 객체"라는 뜻을 내포하는 것 같아 보이지 않나요? 저만 그런가요? 실제로 그런 뜻을 가지고 있는 것 같습니다. 저번 시간에 SQL을 보내기 위한 과정을 살펴보았는데 그런 과정에서 어찌됐든 SQL을 보내기 위해 클래스 객체를 지정해야 할 것입니다. 그런데 SQL문을 보낼 때마다 새로운 객체를 만들어서 DB에 접근한다면 어떻게 될까요? 다음 그림처럼 되지 않을까 싶습니다.

 DB에 접근하기 위해서는 객체에서 access를 하기 위한 화살을 날려야 합니다. 그런데 쿼리를 보낼때마다 이러한 객체들을 새로 만들어 DB에 access한다면 DB입장에서는 이 많은 객체들의 요청에 응답하기 위한 많은 문들을 개방해야 할 것입니다. 테이블 하나에 접근하고 수정하기 위해 수많은 문들을 개방해야 한다는 것은 상당히 비효율적입니다. 현업에서는 무수히 많은 테이블에 접근해야하기 때문에 하나의 테이블에 쓸데없이 많은 비용을 들일 수 없기 때문입니다. 그래서 고안한 것이 DAO입니다.

 DAO는 앞에서 나온 모형의 비효율성을 개선한 형태입니다. SQL문을 보내는 여러개의 객체들을 하나로 통합해 DB에 접근하는 방식입니다. 이렇게 하면 상당히 좋은 것이 테이블 하나에 DB입장에서는 문 하나만 개방해도 된다는 것입니다. 그렇게 되면 다른 테이블에 접근하기 위한 객체들을 더 많이 수용할 수 있고 DB입장에서도 효율적으로 쿼리를 받아들일 수 있습니다.

 

 

🔖 DTO (Data Transfer Object): DAO에서 데이터를 주고받고 할 때 쓰이는 객체

 DTO의 약자는 Data Transfer Object입니다. 이 역시 이름에서 어느정도 어떤 역할을 하는지 가늠할 수 있습니다. DAO를 통해 DB에 접근할 때 데이터가 오고가고 할텐데 이 때 DTO가 매개체 역할을 해준다고 할 수 있습니다. 

 

 DTO는 테이블의 칼럼을 그대로 반영해 맴버변수화 시키고 getter & setter를 통해 접근하도록 구성합니다. 이렇게 만들어진 DTO는 테이블의 행(데이터) 하나를 가리키고 그것을 DAO를 경유하여 쿼리를 날리고 결과값을 받아오는데 사용됩니다. 어느정도 감은 익혔으니 코드를 한번 살펴볼까요?

 

 

📌 2. DAO, DTO 코딩

 

 

🔖 DAO

데이터의 접근을 관리하는 DAO 클래스

 전체적인 DAO의 코드입니다. 너무 길어서 어떻게 구성되어 있는지 보여드리기 위해 스크린샷을 가져왔습니다. 

 

 Singleton 방식

private static DeptDao single;

// 외부에서 객체생성X
private DeptDao() {

}

// 외부에서는 이걸 통해서만이 객체생성가능
public static DeptDao getInstance() {
    if (single == null) {
        single = new DeptDao();
    }
    return single;
}

 DAO는 하나의 객체에 여러 쿼리를 담는 것이기에 singleton 방식으로 객체를 생성해야 합니다. 즉 main에서 new 생성자를 통해서 객체를 만들 수 있는 길을 차단하고 메서드를 통해서 객체를 생성하도록 만들어야 합니다. 이와 더불어 생성된 객체는 static객체화를 통해 하나의 객체만이 존재하도록 만들어야 합니다. single이 null값이라는 것은 아예 아무것도 만들어지지 않은 맨 처음 실행단계라고 할 수 있고 그 이후에는 return single을 통해 이미 존재하는 객체를 계속해서 불러오는 방식으로 작성해야 합니다.

 

static 초기화로 Driver 호출

static {
    try {
        // forName은 static 클래스를 그대로 메모리에 올려놓기만 하는 것
        // 뒤에 .newInstance()를 하면 객체를 생성해준다.
        Class.forName("org.mariadb.jdbc.Driver");
    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

 앞선 JDBC 게시글에서 Class.forName을 통해 Driver를 호출한 것을 보았을 것입니다. singleton으로 객체를 생성하면 그 이후에 해당 DAO 객체를 통해 계속해서 쿼리를 날릴 것이기 때문에 Driver는 맨처음 한번만 호출해도 됩니다. CRUD 명령을 할 때마다 Driver를 호출할 필요가 없이 맨처음 한번만 호출해도 된다고 생각하면 됩니다. 그래서 이 부분은 static 초기화를 통해서 맨처음 한 번만 수행하도록 하는 것이 좋다고 할 수 있습니다.

(이외에 CRUD 쿼리에 대한 메서드는 전 게시물에 했던 내용이랑 같기 때문에 깃허브로 코드 공유하는 것으로 마무리하겠습니다. :)  )

 

 

🔖 DTO

// 테이블을 가져오려거든 DTO 파일부터 만들자.
// 날짜 같은 것도 String 으로 받자.
public class DeptDto {
    // 칼럼명을 그대로 식별자로 사용하지는 말자.
    private int no;
    private String name;
    private String loc;

    public DeptDto() {
        super();
        // TODO Auto-generated constructor stub
    }

    public DeptDto(int no, String name, String loc) {
        super();
        this.no = no;
        this.name = name;
        this.loc = loc;
    }

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getLoc() {
        return loc;
    }

    public void setLoc(String loc) {
        this.loc = loc;
    }
}

 DTO는 dept 테이블의 칼럼 (deptno, dname, loc)에 대해서 맴버변수화시키고 각 맴버변수에 대해서 setter & getter를 만듭니다. 이렇게 만들어두면 DTO객체를 가지고 테이블의 데이터 하나(혹은 새로 테이블에 담을 데이터)를 담고 그걸가지고 위의 DAO 객체가 이용하는 방식이 가능해집니다.



📌 정리

 

  • DAO는 DB에 쿼리를 보내는데 있어서 효율적으로 관리하기 위한 장치이다.
    (여러개의 객체를 통해 쿼리를 보낼 것을 하나의 객체로 통합) 
  • DTO는 DAO가 쿼리를 보내고 데이터를 뽑거나 새로 집어넣을 때 그 데이터를 운반해주는 역할을 한다.(DAO를 보조해주는 개념?)
    나중에 Connection pool과 연결이 되기 때문에 DAO, DTO 개념은 상당히 중요하다.

 

(github: DeptDao, DeptDto 코드참고)