데이터베이스의 접근하는 객체
프로젝트 서비스 모델에 해당하는 부분과 데이터베이스를 연결한다.
직접 데이터베이스로 접근하여 데이터의 CRUD 작업을 수행함
DB에 접근하기 위한 로직 & 비즈니스 로직을 분리하기 위해 사용
DAO 코드 예시
public class TestDao {
public void add(TestDto dto) throws ClassNotFoundException, SQLException {
private static final String DRIVER = "com.mysql.jdbc.Driver";
private static final String URL = "jdbc:mysql://localhost:3306/dao_Db";
private static final String USER = "root";
private static final String PASSWORD = "1234";
String sql = "SELECT * FROM vouchers";
try {
con = DriverManager.getConnection(URL, USER, PASSWORD);
stmt = con.createStatement();
res = stmt.executeQuery(sql);
while (res.next()) {
System.out.println(res.getString("id") + " ");
System.out.println(res.getString("value") + " ");
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
preparedStatement.setString(1, dto.getName());
preparedStatement.setInt(2, dto.getValue());
preparedStatement.setString(3, dto.getData());
preparedStatement.executeUpdate();
preparedStatement.close();
connection.close();
}
}
Dto를 매개변수로 받아서 Driver, URL, username, password를 입력하여 데이터베이스의 접근하여 Create를 해주는 것을 확인할 수 있다.
스프링 프로젝트를 할 때 많이 사용화는 JpaRepository<>를 상속받는 Repository 객체들도 DAO라고 볼 수 있다.
public interface UserRepository extends JpaRepository<Item, Long> {
....
}
실제 DB와 매핑되는 클래스
@Entity, @Column, @Id 등과 같은 annotation 사용
DB테이블 내에 존재하는 칼럼만 필드로 가져야 하고 상속받거나 구현체서는 안된다.
로직을 가지지 않는 순수한 데이터 객체 (getter, setter만 가지는 클래스)
여러 레이어간 데이터를 주고받을 때 사용하고 주로 View Controller 사이에서 활용
DB를 저장할 때는 Entity에 저장하고 계층간 데이터 이동에는 DTO 이용.
왜 그렇게 사용할까?
데이터 전달만을 위한 객체이기 때문에 getter, setter만 필요하고 나머지 필요 없음
구현 방식에 따라 가변 객체, 불변 객체 가능
가변 객체 예시(getter + setter메소드 가능)
// 가변 객체 DTO
// 기본생성자로 생성 후 값을 유동적으로 변경
public class DtoEx {
private String name;
private int age;
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
}
// 불변 객체 DTO
// 생성시 지정했던 값이 변하지 않고 getter() 메소드만 사용 가능
public class DtoEx {
private final String name;
private final int age;
public DtoEx(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
// VO예제
// 값을 표현만 하기 때문에 setter()메소드는 사용하지 않는다.
public class VoEx {
static class Money{
private final int value;
Money(int value) {
this.value = value;
}
public int getValue() {
return value;
}
// 사용자 생성 메소드이지만 setter형태의 메소드가 아니므로 무관함
public String printMoney(){
return this.value + "원";
}
// 두 객체의 모든 필드 값들이 모두 같으면 같은 객체이도록 만들기 위한 오버라이딩
@Override
public int hashCode() {
return Objects.hash(value);
}
@Override
public boolean equals(Object obj) {
if(this == obj)
return true;
if(obj == null || getClass() != obj.getClass())
return false;
Money money = (Money) obj;
if(value == money.value)
return true;
else
return false;
}
}
}
domain == vo, repository == dao
이렇게 똑같이 봐도 괜찮은 건가요?
같은 것이라면 왜 vo, dao가 아닌 다른 이름을 사용한 것인지,
다른 것이라면 (vo, dao)와 (domain, repository)의 차이점에 대해서도 알려주시면 감사하겠습니다.
domain != vo 입니다.
vo는 2가지 의미로 사용됩니다.
1. 단순히 데이터 값을 전달하기 위한 용도로 사용되는 객체라는 뜻 (DTO와 같은 뜻으로 혼용해서 사용합니다. 저는 이 경우 DTO라고 합니다. DTO = 데이터를 전송하는 목적으로 사용하는 객체이지요.)
2. 도메인 주도 설계에서 이야기하는 값 객체(Value Object)의 의미가 있습니다. 이 부분에 대한 자세한 내용은 JPA 기본편 강의에서 자세히 설명드립니다.(저는 vo라고 하면 이 의미로 사용합니다.)
//이부분은 찾아보니 equals를 오버라이딩 해야한다는 vo를 의미하는듯.
repository := dao (비슷함)
이 둘은 거의 같다고 생각하셔도 무방합니다. 좀 더 깊이있게 차이를 설명하면, repotiroy는 엔티티 객체를 보관하고 관리하는 저장소이고, dao는 데이터에 접근하도록 DB접근 관련 로직을 모아둔 객체입니다. 둘다 개념의 차이일뿐 실제로 개발할 때는 비슷하게 사용됩니다.