Java/고급객체지향

고급객체지향 프로그래밍 - 다오 패턴(DAO Pattern)

얄루몬 2021. 12. 12. 15:10

다오 패턴(DAO Pattern)

1. 목적

  • 업무와 DBMS를 분리하기 위해 사용
  • 업무와 데이터 2계층을 분리, 서로 그 상태를 동일하게 유지(Persistence)

 

  • 업무: 고객, 주문, 유통 같은 업무 절차 및 규칙
  • 데이터: 정보를 어떻게 저장할지 예를 들어 고객 ID는 몇 자리로 할 것인지, 숫자 또는 문자인지 등 물리적인 문제 
요소 설명
이름 다오(DAO)
문제 DB를 사용하는 방법이 변경되면 클라이언트의 수정이 많아진다
해결방안 사용 방법의 분리
결과  loose coupling, 확장성

 

2. 문제

  • 데이터를 저장하는 방식이 다양함(데이터베이스, 파일, XML, CSV 파일 등)
  • 사용하는 방법이 다르면 변경 부분이 많아진다.(DBMS에 따라서 SQL문이 달라질 수 있는 등의 문제)

👉 데이터를 저장하는 방식을 분리해서 변경 부분을 최소화 시켜야 한다. (DB를 다루는 부분을 분리하여 캡슐화 시키는 것을 의미한다.)

 

3. 설계

DAO Pattern 설계

 

4. 사례 1 - 주소록

CRUD를 구현

 

5. JDBC(Java Database Connectivity) / ODBC

데이터베이스 비종속적인 표준 자바 API

  • 다양한 데이터베이스를 동일한 인터페이스로 사용할 수 있도록 한다.
  • 각종 데이터베이스는 JDBC Driver를 통해 연결하고 사용한다.

 

주 사용 방법

  • 데이터베이스에 연결한다.
  • SQL 쿼리 작성 후 데이터베이스에서 실행한다
  • 결과로 반환되는 데이터를 수정하거나 화면에 출력한다.

ODBC -> 윈도우용

 

 


웹사이트의 아이디와 비밀번호를 관리하는 프로그램을 DAO 패턴을 이용해서 작성. 

웹사이트 URL, 아이디 비밀번호를 DB에 저장, 수정, 삭제 및 검색 가능

Sqlite를 이용해서 다음에 해당되는 테이블 생성 

이름 자료형 비고
url text PRIMARY KEY
id text  
password text  

-> DB 파일 이름과 테이블 이름은 본인이 결정

 

Main()에서 할 일 

DB에 다음 데이터 추가

- https://www.smu.ac.kr, "smu", "abcde"
- https://www.smu2.ac.kr, "smu2", "abcde"
package java;

public class PasswordInfo {
	private String url;
	private String id;
	private String password;
	PasswordInfo(String url, String id, String pw){
		this.url = url;
		this.id = id;
		this.password = pw;
	} 
	public String toString() {
		return "" + url + ", " + id + ", " + password;
	} 
	public String getUrl() { return url; } 
	public void setName(String url) { this.url = url; }
	public String getId() { return id; }
	public void setId(String id) { this.id = id; }
	public String getPassword() { return password; }
	public void setPassword(String pw) {
		this.password = pw;
	}
}
package java;

import java.util.List;

public interface passwordInfoDao {
	public void insert(PasswordInfo p);
	public List<PasswordInfo> findAll();
	public PasswordInfo findByUrl(String url);
	public void update(String url, PasswordInfo p);
	public void delete(String url);
	public void delete(PasswordInfo p);
}
package java;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class passwordInfoDaoImpl implements passwordInfoDao {
    final static String DB_FILE_NAME = "passwords.db";
    final static String DB_TABLE_NAME = "passwords";

    Connection connection = null;
    ResultSet rs = null;
    Statement statement = null;

    public passwordInfoDaoImpl() {
        try {
            connection = DriverManager.getConnection("jdbc:sqlite:" + DB_FILE_NAME);
            statement = connection.createStatement();
            statement.setQueryTimeout(30);  // set timeout to 30 sec.
            final String table = " (URL text PRIMARY KEY, id text, password text)";

            // create table
            statement.executeUpdate("DROP TABLE IF EXISTS " + DB_TABLE_NAME);
            statement.executeUpdate("CREATE TABLE " + DB_TABLE_NAME + table);
        }
        catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public void insert(PasswordInfo p) {
        try {
            String fmt = "INSERT INTO %s VALUES(%s, '%s', '%s')";
            String q = String.format(fmt, DB_TABLE_NAME, p.getUrl(), p.getId(), p.getPassword());
            
            statement.execute(q);
        }
        catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public List<PasswordInfo> findAll() {
        ArrayList<PasswordInfo> PasswordInfo = new ArrayList<PasswordInfo>();
        try {
            rs = statement.executeQuery("SELECT * FROM " + DB_TABLE_NAME);
            while (rs.next()) {
                PasswordInfo.add(new PasswordInfo(rs.getString("URL"), rs.getString("id"),
                                       rs.getString("password")));
            }
        }
        catch (SQLException e) {
            e.printStackTrace();
        }
        return PasswordInfo;
    }

    public PasswordInfo findByUrl(String url) {
    	PasswordInfo person = null;
        try {
            String fmt = "SELECT * FROM %s WHERE id = %s";
            String q = String.format(fmt, DB_TABLE_NAME, url);
            rs = statement.executeQuery(q);
            if (rs.next()) {
                person = new PasswordInfo(rs.getString("URL"), rs.getString("id"),
                                   rs.getString("password"));
            }
        }
        catch (SQLException e) {
            e.printStackTrace();
        }
        return person;
    }

    public void update(String url, PasswordInfo p) {
    	PasswordInfo person = findByUrl(url);
        if (person != null) {
            try {
                String fmt = "UPDATE %s SET URL = '%s', password = '%s' WHERE URL = '%s'";
                String q = String.format(fmt, DB_TABLE_NAME, p.getId(), p.getPassword(), p.getUrl());
                
                statement.execute(q);
            }
            catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    public void delete(String url) {
        try {
            String fmt = "DELETE FROM %s WHERE id = '%s'";
            String q = String.format(fmt, DB_TABLE_NAME, url);
            
            statement.execute(q);
        }
        catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public void delete(PasswordInfo p) {
        delete(p.getUrl());
    }
}
package java;

public class Main {
    public static void main(String[] args) {
        PasswordInfo p;
        passwordInfoDao passwordInfoDao = new passwordInfoDaoImpl();

        System.out.println("--- inserting...");
        p = new PasswordInfo("https://www.smu.ac.kr","smu", "abcde");
        passwordInfoDao.insert(p);
        p = new PasswordInfo("https://www.smu2.ac.kr", "smu2","abcde");
        passwordInfoDao.insert(p);

        System.out.println("--- finding all...");
        for (PasswordInfo pi : passwordInfoDao.findAll()) {
            System.out.println("reading... " + pi);
        }

        System.out.println("--- updating...");
        p = passwordInfoDao.findAll().get(1);
        p.setName("smu1");
        passwordInfoDao.update(p.getUrl(), p);

        System.out.println("--- see if updated...");
        p = passwordInfoDao.findByUrl("https://www.smu2.ac.kr");
        if (p != null) {
            System.out.println(p);
        }

        System.out.println("--- deleting...");
        passwordInfoDao.delete("https://www.smu2.ac.kr");  // or passwordInfoDao.delete(p);

        System.out.println("--- finding all after deleting...");
        for (PasswordInfo pi : passwordInfoDao.findAll()) {
            System.out.println("reading... " + pi);
        }
    }
}