자바 개발에서 객체지향 설계를 사용할 때, 데이터 처리와 데이터베이스 접근을 효율적으로 관리하기 위해 **DTO(Data Transfer Object)**와 DAO(Data Access Object) 패턴은 중요한 역할을 합니다. 이 두 가지 패턴은 서로 밀접하게 연관되어 있지만 그 목적과 기능은 다릅니다. 이번 글에서는 DTO와 DAO의 개념, 차이점, 그리고 실제 활용 예시를 통해 이들이 어떻게 사용되는지에 대해 알아보겠습니다. 또한, SQL과 데이터베이스 연결을 다루는 예제 코드를 통해 보다 쉽게 이해할 수 있도록 설명하겠습니다.
1. DTO (Data Transfer Object)란?
DTO는 "데이터 전송 객체"로, 계층 간 데이터 교환을 위해 사용되는 자바빈즈(JavaBeans) 객체를 의미합니다. 주로 데이터만 담는 객체로서 getter와 setter 메소드를 통해 데이터를 전달합니다. DTO는 값 객체(Value Object, VO)와 혼용되어 사용되기도 하는데, VO는 읽기 전용 객체로 데이터를 변경할 수 없는 특성이 있습니다.
DTO는 순수한 데이터의 집합체이므로, 비즈니스 로직이나 기능은 포함되지 않습니다. 예를 들어, 단어장을 다룰 때 단어의 정보(영어, 한국어, 레벨 등)를 DTO 객체에 담아 다른 계층으로 전달할 수 있습니다.
2. DAO (Data Access Object)란?
DAO는 "데이터 접근 객체"로, 데이터베이스의 데이터를 관리하는 객체입니다. DAO의 주 목적은 데이터베이스와의 상호작용을 분리하여 코드의 간결화와 유지보수를 용이하게 만드는 것입니다. DAO는 DB에 접속하여 CRUD(생성, 읽기, 갱신, 삭제) 작업을 처리하는 역할을 합니다.
DAO를 사용하면 데이터베이스와의 연결을 관리하고, SQL 쿼리를 실행하는 작업을 전담할 수 있어 비즈니스 로직과 데이터 접근 로직을 구분할 수 있습니다. 예를 들어, 단어장 프로그램에서 단어를 삽입, 수정, 삭제하는 등의 기능을 DAO가 처리합니다.
3. SQL: LIKE 검색 예시
SQL에서 LIKE 구문을 사용하면 문자열을 포함한 검색을 쉽게 할 수 있습니다. 예를 들어, 사용자가 입력한 'a'를 포함하는 ID를 검색하려면 아래와 같은 쿼리를 사용합니다:
- 'a'를 포함한 ID 검색:
select mem_idx, mem_userid, mem_name, mem_hp
from tb_member
where mem_userid like '%a%';
- 'a'로 시작하는 ID 검색:
select mem_idx, mem_userid, mem_name, mem_hp
from tb_member
where mem_userid like '%a';
- 'a'로 끝나는 ID 검색:
select mem_idx, mem_userid, mem_name, mem_hp
from tb_member
where mem_userid like 'a%';
4. 테이블 생성 SQL
단어장과 같은 시스템에서 데이터베이스 테이블을 생성하는 SQL은 아래와 같습니다. 예를 들어, 단어 정보를 저장할 tb_vocabulary 테이블을 생성하려면 다음과 같은 SQL을 사용할 수 있습니다:
create table tb_vocabulary(
vo_idx bigint auto_increment primary key,
vo_eng varchar(100) not null,
vo_kor varchar(50) not null,
vo_level int not null,
vo_regdate datetime default now()
);
5. DB Connection 클래스 예시
DB와 연결을 관리하는 클래스는 Dbconn과 같이 작성할 수 있습니다. 이 클래스는 MySQL 데이터베이스와 연결하고 종료하는 메소드를 포함합니다. 예시는 다음과 같습니다:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class Dbconn {
private static Connection conn;
// SQLException, ClassNotFoundException 예외 발생 시 상위 메소드로 책임전가
public static Connection getConnection() throws SQLException, ClassNotFoundException {
String url = "jdbc:mysql://127.0.0.1/aiclass?useSSL=false";
String userid = "root";
String userpw = "1234";
Class.forName("com.mysql.cj.jdbc.Driver");
conn = DriverManager.getConnection(url, userid, userpw);
return conn;
}
public static void dbclose() {
try {
conn.close();
conn = null;
}catch (Exception e) {
e.printStackTrace();
}
}
}
6. DTO와 DAO 활용 예시: 단어장
단어장 프로그램에서 DTO와 DAO의 활용 예시는 다음과 같습니다. 먼저, VocaDTO 클래스는 단어 정보를 담는 DTO입니다:
public class VocaDTO {
private int idx;
private String eng;
private String kor;
private int lev;
private String rdate;
public VocaDTO(int idx, String eng, String kor, int lev, String rdate) {
this.idx = idx;
this.eng = eng;
this.kor = kor;
this.lev = lev;
this.rdate = rdate;
}
public int getIdx() {
return idx;
}
public void setIdx(int idx) {
this.idx = idx;
}
public String getEng() {
return eng;
}
public void setEng(String eng) {
this.eng = eng;
}
public String getKor() {
return kor;
}
public void setKor(String kor) {
this.kor = kor;
}
public int getLev() {
return lev;
}
public void setLev(int lev) {
this.lev = lev;
}
public String getRdate() {
return rdate;
}
public void setRdate(String rdate) {
this.rdate = rdate;
}
@Override
public String toString() {
return "VocaDTO{" +
"idx=" + idx +
", eng='" + eng + '\'' +
", kor='" + kor + '\'' +
", lev=" + lev +
", rdate='" + rdate + '\'' +
'}';
}
}
DAO 클래스에서는 단어를 삽입, 조회, 수정, 삭제하는 메소드를 포함하여 데이터베이스와 상호작용합니다:
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;
public class VocaDAO {
Connection conn;
Scanner sc;
StringBuilder sql;
PreparedStatement pstmt;
ResultSet rs;
public void insert() throws SQLException { // 단어 등록
sc = new Scanner(System.in);
System.out.print("단어를 입력하세요 > ");
String eng = sc.next();
System.out.print("단어의 뜻을 입력하세요 > ");
String kor = sc.next();
System.out.print("레벨을 입력하세요 > ");
int lev = sc.nextInt();
try {
conn = Dbconn.getConnection();
sql = new StringBuilder();
sql.append("insert into tb_vocabulary (vo_eng, vo_kor, vo_level)");
sql.append("values (?, ?, ?)");
pstmt = conn.prepareStatement(sql.toString());
pstmt.setString(1, eng);
pstmt.setString(2, kor);
pstmt.setInt(3, lev);
int result = pstmt.executeUpdate();
if (result >= 1) System.out.println("단어등록 성공");
else System.out.println("단어등록 실패");
} catch (Exception e) {
e.printStackTrace();
} finally {
Dbconn.dbclose();
pstmt.close();
pstmt = null;
}
}
public void list() throws SQLException{ // 등록한 단어 리스트
try {
conn = Dbconn.getConnection();
sql = new StringBuilder();
sql.append("select vo_eng, vo_kor, vo_level, vo_regdate from tb_vocabulary order by vo_eng asc");
pstmt = conn.prepareStatement(sql.toString());
rs = pstmt.executeQuery();
while (rs.next()) {
String eng = rs.getString("vo_eng");
String kor = rs.getString("vo_kor");
int lev = rs.getInt("vo_level");
String regdate = rs.getString("vo_regdate");
System.out.println(eng + " : " + kor + "(" + lev + ", " + regdate + ")");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
Dbconn.dbclose();
pstmt.close();
pstmt = null;
rs.close();
rs = null;
}
}
public void search() throws SQLException { // 단어 검색
sc = new Scanner(System.in);
System.out.print("검색할 단어를 입력하세요 > ");
String word = sc.next();
Boolean isFind = false;
try {
conn = Dbconn.getConnection();
sql = new StringBuilder();
// sql.append("select vo_eng, vo_kor, vo_level, vo_regdate from tb_vocabulary where vo_eng = ?");
sql.append("select vo_eng, vo_kor, vo_level, vo_regdate from tb_vocabulary where vo_eng like ?");
pstmt = conn.prepareStatement(sql.toString());
pstmt.setString(1, "%" + word + "%"); // 입력받은 word를 포함한 모든 단어 검색.
rs = pstmt.executeQuery();
while (rs.next()) {
isFind = true;
String eng = rs.getString("vo_eng");
String kor = rs.getString("vo_kor");
int lev = rs.getInt("vo_level");
String regdate = rs.getString("vo_regdate");
System.out.println(eng + " : " + kor + "(" + lev + ", " + regdate + ")");
}
if (!isFind) System.out.println("찾는 단어가 없습니다.");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
Dbconn.dbclose();
pstmt.close();
pstmt = null;
rs.close();
rs = null;
}
}
public void edit() throws SQLException { // 단어 수정
sc = new Scanner(System.in);
System.out.print("수정할 단어를 입력하세요 > ");
String eng = sc.next();
System.out.print("단어의 뜻을 입력하세요 > ");
String kor = sc.next();
System.out.print("레벨을 입력하세요 > ");
int lev = sc.nextInt();
try {
conn = Dbconn.getConnection();
sql = new StringBuilder();
sql.append("update tb_vocabulary set vo_kor = ?, vo_level = ? where vo_eng = ?");
pstmt = conn.prepareStatement(sql.toString());
pstmt.setString(1, kor);
pstmt.setInt(2, lev);
pstmt.setString(3, eng);
int result = pstmt.executeUpdate();
if (result >= 1) System.out.println("단어수정 성공");
else System.out.println("단어수정 실패");
} catch (Exception e) {
e.printStackTrace();
} finally {
Dbconn.dbclose();
pstmt.close();
pstmt = null;
}
}
public void delete() throws SQLException { // 단어 삭제
sc = new Scanner(System.in);
System.out.print("삭제할 단어를 입력하세요 > ");
String word = sc.next();
try {
conn = Dbconn.getConnection();
sql = new StringBuilder();
sql.append("delete from tb_vocabulary where vo_eng = ?");
pstmt = conn.prepareStatement(sql.toString());
pstmt.setString(1, word);
int result = pstmt.executeUpdate();
if (result >= 1) System.out.println("단어삭제 성공");
else System.out.println("단어삭제 실패");
} catch (Exception e) {
e.printStackTrace();
} finally {
Dbconn.dbclose();
pstmt.close();
pstmt = null;
}
}
}
실행 클래스
import java.sql.SQLException;
import java.util.Scanner;
public class Main1 {
// VocaDAO의 메소드를 호출하는 곳이기 때문에 메소드에서 책임전가한 예외처리를 해주어야 함. JVM에 책임전가.
public static void main(String[] args) throws SQLException {
Scanner sc = new Scanner(System.in);
VocaDTO vocaDTO;
VocaDAO vocaDAO = new VocaDAO();
while (true) {
System.out.println("🌠🌠🌠 단어장 🌠🌠🌠");
System.out.println("1.등록 2.리스트 3.검색 4.수정 5.삭제 6.종료");
int input = sc.nextInt();
if (input == 6) {
System.out.println("프로그램을 종료합니다");
break;
}
switch (input) {
case 1:
vocaDAO.insert();
break;
case 2:
vocaDAO.list();
break;
case 3:
vocaDAO.search();
break;
case 4:
vocaDAO.edit();
break;
case 5:
vocaDAO.delete();
break;
}
}
}
}
실행결과
요약
DTO와 DAO는 자바 개발에서 중요한 설계 패턴입니다. DTO는 데이터를 담고 전달하는 역할을 하며, DAO는 데이터베이스와의 상호작용을 관리합니다. 이 두 패턴을 적절히 사용하면 코드의 유지보수성과 가독성을 향상시킬 수 있습니다. 또한, SQL의 LIKE 구문을 사용하여 효율적인 검색이 가능하며, 데이터베이스 연결 및 테이블 생성 등을 통해 실제로 데이터를 다룰 수 있습니다.
'Java' 카테고리의 다른 글
DTO, DAO를 이용한 sql CRUD 예제 2 (학생 관리 프로그램) (0) | 2022.04.26 |
---|---|
[Java] ResultSet, PreparedStatement 인터페이스 (0) | 2022.04.26 |
[Java] Statement 인터페이스를 이용한 Table delete (0) | 2022.04.21 |
[Java] Statement 인터페이스를 이용한 Table update (0) | 2022.04.21 |
[Java] Statement 인터페이스를 이용한 Table insert (0) | 2022.04.21 |