개발 1년차. 요즘 기본기와 기초가 많이 부족한 거 같다는 생각을 많이한다. 누구는 그렇게까지 깊게 공부하지 않아도 GPT가 다 해준다라는 속 편한 말을 하는 직장 동료도 있지만 꾸준히 하다보면 GPT보다는 덜 하겠지만 스스로가 뿌듯해지는 순간이 오지 않을까하여 기본기를 다지기 위해 다시 공부를 하려고 한다.
오늘 처음 공부할 부분은 DAO ( Data Access Object ) 이다.
1. DAO ( Data Access Object )
DAO는 DB를 사용해 데이터를 조회하거나 조작하는 기능을 전담하도록 만든 오브젝트로, DB와 직접적인 관계를 가지고 있다고 생각하면 된다.
1.1. DAO의 수행 절차
- 데이터베이스 연결을 위한 Connection을 가져온다.
- SQL을 담은 Statement ( 또는 preparedStatement) 를 만든다.
- 만들어진 statement를 실행한다.
- 조회의 경우 SQL 쿼리의 실행 결과를 ResultSet으로 받아서 정보를 저장할 오브젝트에 옮겨준다.
- 작업 중에 생성된 Connection, Statement, ResultSet 같은 리소스는 작업을 마친 후에 반드시 닫아준다(close).
- 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을 사용하시던 분들이라면 이걸 바로 사용하면 되지?!라는 답을 바로 찾을 실 수 있겠지만, 지금의 문서를 작성하는 나는 모르는 척 하기로 했다.
위와 같은 두 가지 의문으로 인해서 우리가 공통으로 관리하는 관심사란 무엇인가를 찾고 그것을 어떻게 분리하느냐에 대해 공부하려고 한다.
'Programming > Spring' 카테고리의 다른 글
[오브젝트와 의존관계] - DAO의 확장 (1) | 2025.05.03 |
---|---|
[오브젝트와 의존관계] - 관심사의 분리 (0) | 2025.05.03 |
[Spring] 파일 업로드 (0) | 2024.05.26 |
[Spring] AOP, 관점 지향 프로그래밍 (0) | 2024.05.26 |
[Spring] Session, 세션 (0) | 2024.05.26 |