다오 패턴(DAO Pattern)
1. 목적
- 업무와 DBMS를 분리하기 위해 사용
- 업무와 데이터 2계층을 분리, 서로 그 상태를 동일하게 유지(Persistence)
- 업무: 고객, 주문, 유통 같은 업무 절차 및 규칙
- 데이터: 정보를 어떻게 저장할지 예를 들어 고객 ID는 몇 자리로 할 것인지, 숫자 또는 문자인지 등 물리적인 문제
요소 | 설명 |
이름 | 다오(DAO) |
문제 | DB를 사용하는 방법이 변경되면 클라이언트의 수정이 많아진다 |
해결방안 | 사용 방법의 분리 |
결과 | loose coupling, 확장성 |
2. 문제
- 데이터를 저장하는 방식이 다양함(데이터베이스, 파일, XML, CSV 파일 등)
- 사용하는 방법이 다르면 변경 부분이 많아진다.(DBMS에 따라서 SQL문이 달라질 수 있는 등의 문제)
👉 데이터를 저장하는 방식을 분리해서 변경 부분을 최소화 시켜야 한다. (DB를 다루는 부분을 분리하여 캡슐화 시키는 것을 의미한다.)
3. 설계
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);
}
}
}
'Java > 고급객체지향' 카테고리의 다른 글
고급객체지향 프로그래밍 - 퍼사드 패턴(Facade Pattern) (0) | 2021.12.12 |
---|---|
고급객체지향 프로그래밍 - 어댑터 패턴(Adapter Pattern) (0) | 2021.12.12 |
고급객체지향 프로그래밍 - 싱글턴 패턴(Singleton Pattern), 반복자 패턴(Iterator Pattern) (0) | 2021.10.19 |
고급객체지향 프로그래밍 - 팩토리 메소드 패턴(Factory Method Pattern) (0) | 2021.10.19 |
고급객체지향 프로그래밍 - 데코레이터 패턴 (Decorator Pattern) (0) | 2021.10.19 |