본문 바로가기
Programming/Spring

[오브젝트와의존관계] - DAO

by 공부합시다홍아 2025. 5. 3.

개발 1년차. 요즘 기본기와 기초가 많이 부족한 거 같다는 생각을 많이한다. 누구는 그렇게까지 깊게 공부하지 않아도 GPT가 다 해준다라는 속 편한 말을 하는 직장 동료도 있지만 꾸준히 하다보면 GPT보다는 덜 하겠지만 스스로가 뿌듯해지는 순간이 오지 않을까하여 기본기를 다지기 위해 다시 공부를 하려고 한다. 


오늘 처음 공부할 부분은 DAO ( Data Access Object ) 이다.

 

1. DAO ( Data Access Object )

DAO는 DB를 사용해 데이터를 조회하거나 조작하는 기능을 전담하도록 만든 오브젝트로, DB와 직접적인 관계를 가지고 있다고 생각하면 된다. 

1.1. DAO의 수행 절차

  1. 데이터베이스 연결을 위한 Connection을 가져온다.
  2. SQL을 담은 Statement ( 또는 preparedStatement) 를 만든다.
  3. 만들어진 statement를 실행한다.
  4. 조회의 경우 SQL 쿼리의 실행 결과를 ResultSet으로 받아서 정보를 저장할 오브젝트에 옮겨준다.
  5. 작업 중에 생성된 Connection, Statement, ResultSet 같은 리소스는 작업을 마친 후에 반드시 닫아준다(close).
  6. JDBC API가 만들어내는 예외(Exception)를 잡아서 직접 처리하거나, 메소드에 Throws를 선언해 예외가 발생하면 메소드 밖으로 던지게 한다.

DAO의 수행절차에 대해 직관적으로 알아보기 위해 아래와 같은 UserVO와 UserDAO 그리고 Main에서의 동작과정을 설명할 수 있다.

 

User VO

UserVO에는 사용자 ID와 이름 그리고 비밀번호를 나타내는 변수를 선언한다.

그리고 나는 lombok을 이용해 Setter나 Getter 그리고 생성자는 어노테이션을 이용해서 간단하게 설정하였다.

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class User {
	
	String id;
	String name;
	String password;
	
}

UserDAO

DAO는 사용자를 추가하는 메서드 ADD와 사용자를 조회하는 메서드 GET을 만들어주었다.

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.example.tobi.vo.User;

public class UserDAO {
	
	// 사용자 추가
	public void add(User user) throws ClassNotFoundException, SQLException {
		
		Class.forName("com.mysql.jdbc.Driver");
		// 연결문자열 , DB_ID, DB_PW
		Connection c = DriverManager.getConnection("jdbc:mysql://localhost:3306/jspdb", "root", "1234" );
		PreparedStatement ps = c.prepareStatement("insert into users(id,name,password) values (?,?,?)" );
		ps.setString(1, user.getId());
		ps.setString(2, user.getName());
		ps.setString(3, user.getPassword());
		
		// update 의 반환자는 int 형으로 0 또는 1이다.
		ps.executeUpdate();
		
		ps.close();
		
		c.close();
		
	}
	
	// 사용자 조회
	public User get(String id) throws ClassNotFoundException, SQLException{
		Class.forName("com.mysql.jdbc.Driver");
		// 연결문자열 , DB_ID, DB_PW
		Connection c = DriverManager.getConnection("jdbc:mysql://localhost:3306/jspdb", "root", "1234" );
		PreparedStatement ps = c.prepareStatement("select * from users where id = ?" );
		
		ps.setString(1, id);
		
		ResultSet rs = ps.executeQuery();
		rs.next();
		User user = new User();
		user.setId(rs.getString("id"));
		user.setName(rs.getString("name"));
		user.setPassword(rs.getString("password"));
		
		rs.close();
		ps.close();
		c.close();
		
		return user;
	}
	
	
}

DAO의 구성을 보면 앞서 설명했듯이 사용자를 추가 ( 데이터베이스에 저장 ) 하는 메서드인 add와 사용자를 조회 ( 데이터베이스의 데이터를 조회 ) 하는 메서드인 get이 있는데, 두 메서드의 공통점을 찾아볼 수가 있다.

 

바로 데이터베이스 연결을 담당하는 Connection과 쿼리를 실행하는 인터페이스인 PrepareStatement 그리고 결과를 저장하는 ResultSet이 똑같이 사용되는 것을 볼 수 있다.

 

Main

메인에서는 사용자를 추가하고 조회하는 결과를 나타낸다.

import java.sql.SQLException;
import com.example.tobi.dao.UserDAO;
import com.example.tobi.vo.User;

@SpringBootApplication
public class TobiApplication {

	public static void main(String[] args) throws ClassNotFoundException, SQLException {
		
		UserDAO dao = new UserDAO();
		
		User user = new User();
		user.setId("user002");
		user.setName("user002");
		user.setPassword("1234");
		
		dao.add(user);
		
		System.out.println(user.getId() + " 등록 성공!!");
		
		User user2 = dao.get(user.getId());
		System.out.println(user2.getName() + "조회 성공");
		
	}

}

 

이렇게 일반적인 DAO의 동작과정에 대해서 살펴봤다. 개발자라면 여기서 여러 의문이 들어야 정상이라고 생각한다.

첫 번째. 매번 데이터베이스와 연결을 해야 하나?

두 번째, 사용하던 DB가 변경되면 어떻게 하지?

 

사실 첫 번째의 경우는 application.properties나, application.yml을 사용하시던 분들이라면 이걸 바로 사용하면 되지?!라는 답을 바로 찾을 실 수 있겠지만, 지금의 문서를 작성하는 나는 모르는 척 하기로 했다.

 

위와 같은 두 가지 의문으로 인해서 우리가 공통으로 관리하는 관심사란 무엇인가를 찾고 그것을 어떻게 분리하느냐에 대해 공부하려고 한다.

728x90