DAO = Data Access Object의 약어로 실질적으로 DB에 접근하는 객체
저수준의 로직과 고급 비즈니스 로직을 분리하고, 도메인 로직으로 부터 persistence mechanism을 숨기기 위해 사용한다.
1. 효율적인 커넥션 관리와 보안성 때문에 사용
2. persistence 계층이란 DB영구저장소에 데이터를 CRUD 하는 계층
DB에 대한 접근을 담당 커넥션을 하나만 가져오고 커넥션을 가져온 객체가 모든 DB와의 연결을 하는것이 DAO이다.
DB에 대한 접근을 DAO가 담당하도록 하여 데이터 베이스 엑세스를 DAO에서만 하게 되면 다수의 원격 호출을 통한
오버헤드를 VO나 DTO를 통해 줄일 수 있고, 다수의 DB호출 문제를 해결할 수 있다.
커넥션풀 = 커넥션 객체를 미리 만들어 놓고 가져다 쓰고 반환하는 것 으로 웹서버가 DB와 연결하기 위해 매번 커넥션
객체를 생성하는 것을 해결하기 위해 나온 것이다.
커넥션풀은 커넥션을 또 만드는 오버헤드를 효율적으로 하기 위해 DB에 접속하는 객체를 전용으로 하나 만들고,
모든 페이지에서 그 객체를 호출해서 사용한다.
DTO와 VO = 계층간 데이터 교환을 위한 자바 빈즈 로써, DTO,(Data Transfer Object)는 VO(Value Object)로 바꿔 말할 수 있다.
여기서 계층이란, 컨트롤러, 뷰 비즈니스 계층, 퍼시스턴스 계층을 말한다.
VO는 DTO와 동일한 개념이지만, READ ONLY 속성을 가진다.
대표적인 DTO로는 폼 데이터 빈, 데이터베이스 테이블 빈 등이 있으며 각 폼 요소나 데이터 베이스 레코드 데이터를
매핑하기 위한 데이터 객체를 말한다.
즉, 폼 필드들의 이름을 그대로 가지고 있는 자바빈 객체를 폼 필드와 그대로 매핑하여 비즈니스 계층으로 보낼때 사용한다.
이런객체를 DTO 라고 부르며 VO 패턴이라고도 한다.
일반적인 DTO는 로직을 가지고 있지 않은 순수한 데이터 객체 이며 속성과 그 속성에 접근하기 위한 getter, setter 메소드만
가진 클래스를 말한다.
getter,setter외에 toString(), equals()등 Object 클래스 메소드 작성
DAO와 service의 차이
DAO는 단일 데이터 접근/갱신만 처리하지만, service는 여러 DAO를 호출하여 여러번의 데이터 접근/갱신 하고
그렇게 읽은 데이터에 대한 비즈니스 로직을 수행 하고 그것을 하나의(혹은 여러개의) 트랜잭션으로 묶는다.
만약 DAO와 Service 가 완전히 동일해진다면, 그것은 해당 비즈니스 로직이 단일 DB 접근으로 끝나기 때문이다.
DAO 메소드 하나에 다중 DB접근 로직이 들어갔고, Service 에서 단순히 그 DAO를 호출하는 역할만 한다면,
DAO 측의 모듈화가 제대로 되지 않은 접근 방식일 가능성이 높다.
MVC2 패턴 이란?
model, view, controller 세부분으로 코드를 나누어 개발
View 화면 출력부분 (jsp)
Model DB에 연동하는 부분
Controller View와 Model을 연결하는 부분(controller)
3가지 파일만 생성, 수정하여 웹페이지 하나를 구현해봄.
jsp, controller, xml
jsp는 서블릿으로 변환되어 실행됨
1. index.jsp 파일을 WEB-INF 아래에 생성. 화면출력 부분 view에 해당
이 상태로 서버를 런해도 404 오류가 뜬다.
index.jsp 파일에 직접 접근할 수는 없기때문, 그래서 Controller를 이용하여 접근해야함.
2. 모든 web application은 반드시 하나의 web.xml 파일을 가져야하고, WEB-INF폴더 아래에 있다.
URL패턴을 home.do로 두고 servlet class를 com.exam.controller 패키지 안의 HomeController 클래스로 설정
home.do 주소가 호출되었을때 com.exam.controller 패키지의 HomeController 클래스가 실행된것
3. java class를 생성. type을 HttpServlet으로 선택 controller.java
getRequestDispatcher 메소드는 받은 요청을 처리한 후 View 페이지로 처리하기 위하여 사용되는 메소드
매개값으로 경로를 주고 forward 메소드를 사용하면 해당 경로의 페이지를 화면에 출력
4. 결과물
서버를 실행하고 웹에서 localhost/(프로젝트명)newdeal01/home.do 를 치면 index.jsp 페이지가 구현된다! ! !
DAO (Data Access Object)
실질적으로 DB에 접근하여 CRUD 등을 조작하는 기능 수행
Service와 DB를 연결하는 역할
효율적인 커넥션 관리와 보안성 때문에 사용함.
DTO (Data Transfer Object)
DTO는 그저 계층간 데이터 교환이 이루어 질 수 있도록 하는 객체
Service와 Controller 사이에서 사용하는 데이터 교환
Getter/Setter 메소드만 갖는다.
사례)
사용자가 입력한 데이터를 DB에 넣는 과정
사용자가 자신의 브라우저에서 데이터를 입력하여 form에 있는 데이터를 DTO에 넣어서 전송합니다.
해당 DTO를 받은 서버가 DAO를 이용하여 데이터베이스로 데이터를 집어넣습니다.
VO (Value Object)
VO도 DTO와 동일한 개념이다. 다만 DTO와의 차이는, DTO는 데이터를 계층간 교환(Transfer)하는데 의미가 있고,
VO는 읽기만 가능한 read-only 속성을 가진 객체로서 데이터 그 자체에 의미를 두고 있다는 점이다.
DTO (Data Transfer Object)
▶ 데이터 교환을 하기 위해 사용하는 객체
▶ 로직을 가지지 않는 순수한 데이터 저장을 위한 클래스
▶ ▶ 데이터베이스의 테이블명과 컬럼을 그대로 이용
▶ ▶ getter & setter 만 가진 클래스
브라우저 : Form 데이터 → 컨트롤러에서 DTO로 데이터 받음 → DAO에서 DTO로 데이터베이스로 insert
브라우저 : 리스트 출력 ← 컨트롤러에서 DTO로 데이터 받음 ← DAO에서 DTO로 데이터베이스에서 select
VO (Value Object)
▶ VO는 값 그 자체를 표현하는 객체로 읽기 전용
▶ DTO와 유사하지만 DTO는 setter를 가지고 있어 값이 변할 수 있음
DAO (Data Access Object)
▶ 데이터베이스를 사용하기 위한 로직 & 비지니스 로직을 분리하기 위해 사용
▶ 스프링부트에서는 보통 @Repository 어노테이션을 사용
Service
Controller가 Request를 받으면 적절한 Service에 전달하고, 전달 받은 Service는 business logic을 처리한다.
Service가 DB에 DAO로 접근하고, 데이터를 DTO로 전달받은 다음, 데이터를 필요에 맞게 가공하여 반환한다.
DAO(Data Access Object)
- Database 접근을 위한 객체이다.
- Data 삽입(INSERT), 수정(UPDATE), 삭제(DELETE), 조회(SELECT)를 조작/수행한다.
- 보통 DB와 연결할 Connection까지 설정하는 경우가 많다.
DTO(Data Transfer Object)
- 일반적으로 DB(Database)에 접근한 뒤 가져오거나(SELECT) 삽입(INSERT)할 값들을 담기 위해서 만든다.
- 담긴 값들은 계층간 데이터 교환을 위해 쓰이는 자바빈즈(beans)이다. (계층의 예 : Controller, Service, View 등...)
- 보통 멤버변수는 DB 테이블의 컬럼들이며, getter와 setter를 갖는다.
VO(Value Object)
- DTO와 거의 유사하다. 차이점은 Read-Only라는 점이다.
- 특정 객체를 만들어 값을 전달하고자 할 때 사용된다.
DAO, DTO, Service
Spring Framework의 MVC에서 Model은 Service, DAO, DTO로 나눌 수 있다. 한 번 살펴보자.
DAO
Data Access Object의 줄임말이다. DB를 사용해 데이터를 조회하거나 조작하는 기능을 담당하는 것들을 DAO라고 부른다. domain logic (비즈니스 로직이나 DB와 관련없는 코드들)을 persistence mechanism과 분리하기 위해 사용한다.
•persistence layer: Database에 data를 CRUD(Create, Read, Update, Drop)하는 계층
이렇게 따로 분리해놓는 이유는 HTTP Request를 Web Application이 받게 되면 Thread를 생성하게 되는데 비즈니스 로직이 DB로부터 데이터를 얻어오기 위해 매번 Driver를 로드하고 Connection 객체를 생성하게 되면 엄청 많은 커넥션이 일어나므로 DAO를 하나 만들어 DB 전용 객체로만 쓰는 것이다. 이러면 부담이 줄어들게 된다.
이 개념은 DBCP(Database Connection Pool)로부터 나왔다. WAS(Web Application Server)이 실행되면 일정량의 DB Connection 객체를 Pool에다 저장해 두고, HTTP Request에 따라 필요할 때마다 Pool에서 Connection 객체를 가져다 쓰고 반환하는 것이다. 아래 그림 1과 같다.
보통 connection pool은 요청으로 생기는 thread(thread도 pool을 만들수도 있다.)보다 적게 만든다. 왜냐면 모든 Request가 DB에 관련된 것은 아니기 때문이다.
그럼 Spring에서 DAO는 어떻게 만들까? 우선 Spring에서 Singleton 패턴을 권장한다는 것을 기억하자. Spring에서 관리되는 Singleton 패턴이라 하면 당연히 Bean이다. Spring에서 DAO는 @Repository annotation으로 정의한다. class 선언 시 바로 @Repository annotation을 사용해도 되지만 참조한 글에 따르면 메소드 헤더만 정의한 interface를 정의하고 이것을 구현한 class에 annotation을 붙여 사용한다고 한다. 이유는 interface로 구성하면 확장성과 유연성이 높아지기 때문이다. 참조한 글 외에도 여러 잘하는 프로그래머 글에서도 이 방법으로 구현하는 것 같으니 한 번 따라해보자.
UserDao.java
public interface UserDao {
/**
* user 테이블에서 모든 유저의 정보를 가져온다.
*
* @return 모든 유저의 정보
*/
public List<User> getUsers();
}
UserDaoImpl.java
@Repository("userDao")
public class UserDaoImpl implements UserDao {
@Override
public List<User> getUsers()
{
// 리스트 생성
List<User> result = new ArrayList<User>();
// 데이터베이스에서 유저 목록을 가져온다.
result.add(...);
...
return result;
}
}
DTO
Data Transfer Object의 줄임말이다. VO(Value Object)라고도 표현하는데, 계층간 데이터 교환을 위한 자바빈즈(Java Beans)다.
이 객체는 데이터베이스 레코드의 데이터를 매핑하기 위한 데이터 객체를 말한다. DTO는 보통 로직을 가지고 있지 않고 data와 그 data에 접근을 위한 getter, setter만 가지고 있다.
정리하면 DTO는 Database에서 Data를 얻어 Service나 Controller 등으로 보낼 때 사용하는 객체를 말한다. 위 코드에서도 DAO가 Database로부터 Data를 얻은 뒤 List에 담아서 보내주고 있다. DTO는 아래 코드와 같이 쓰일 수 있다.
public class User {
private String name;
private int age;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public void getAge() {
return this.age;
}
public void setAge(int age)
{
this.age = age;
}
@Override
public String toString() {
return "name='" + name + "', age=" + age;
}
}
위와 같이 DTO는 데이터를 주고받을 포맷이라고 할 수 있다.
Service
마지막으로 Service에 대해서 살펴보자. Service는 비지니스 로직이 들어가는 부분이다. Controller가 Request를 받으면 적절한 Service에 전달하고, 전달 받은 Service는 비즈니스 로직을 처리한다. DAO로 데이터베이스를 접근하고, DTO로 데이터를 전달받은 다음, 적절한 처리를 해 반환한다. 아래 코드처럼 쓰일 수 있다.
public interface UserService {
/**
* 유저 정보를 텍스트 파일로 저장한다.
*
* @param path 저장할 파일의 경로
* @return 저장한 유저의 개수
*/
public int saveUsersAsTextFile(String path);
}
@Service("userService")
public class UserServiceImpl implements UserService {
private static final Logger LOGGER = Logger.getLogger("UserServiceImpl");
@Autowired
private UserDao userDao;
@Override
public int saveUsersAsTextFile(String path) {
List<User> users = userDao.getUsers();
// 비즈니스 로직
try (FileOutputStream fileOutputStream = new FileOutputStream(path)) {
StringBuilder result = new StringBuilder();
for(User user : users) {
result.append(user);
result.append('\n');
}
fileOutputStream.write(result.toString().getBytes());
} catch (IOException exception) {
LOGGER.log(Level.SEVERE, "파일을 쓸 수 없습니다.");
throw new IllegalStateException(String.format("Can't write a file. path: %s", path));
}
return users.size();
}
}
위 코드는 DAO로부터 DTO 리스트를 받고, DTO의 리스트를 파일로 저장하는 코드이다. @Autowired annotation으로 userDao bean을 찾아서 연결한 것을 볼 수 있다. (Spring에서는 DI(Dependency Injection, 의존성 주입)이라고 한다.)
Controller에서 서비스 호출은 아래 코드처럼 쓰일 수 있다.
@Controller
public class MainController {
@Autowired
private UserService userService;
@RequestMapping(value = "/save/users", method = RequestMethod.GET)
public ModelAndView saveUsers(ModelAndView mv) {
// 유저를 얻어와서 텍스트 파일로 저장한다.
int saveCount = userService.saveUsersAsTextFile("users.txt");
// 뷰에서 결과를 보여주기 위해 저장한 개수를 뷰에 넘긴다.
mv.addObject("saveCount", saveCount);
mv.setViewName("saveUsersResultView");
return mv;
}
}
'IT 및 공부 > Spring & JSP & PHP' 카테고리의 다른 글
전자정부 프레임워크 값넘기기 연습 (2) (0) | 2022.08.23 |
---|---|
전자정부 프레임워크 값넘기기 연습 (1) (0) | 2022.08.23 |
MVC2 패턴이란? (0) | 2022.08.22 |
DAO(service), DTO(vo), 커넥션풀 의 각각의 역할 (0) | 2022.08.22 |
전자정부 프레임워크 게시판 만들기 연습 (6) 파일 업로드, 다운로드 (0) | 2022.08.12 |