- ORM, SQL, MVC -
올 것이 왔다. 빠지지 않는 멘트. 핵심을 알아보기 전에 미리 알아둬야한다는 멘트.
시작해보겠다.
ORM에 들어가기전에 영속성에 대한 개념 정리.
영속성(Persistence)
- 데이터를 생성한 프로그램이 종료되더라도 사라지지 않는 데이터 특성
- 영속성이 없는 데이터는 단지 메모리에서만 존재하므로, 프로그램 종료 시 모두 사라짐.
- Object Persistence(영구적인 객체)
- 메모리 상의 데이터를 File이나 DB를 활용해서 영속성을 부여함.
- 자바에서 데이터를 저장하는 방법 -
- JDBC
- Spring JDBC
- Persistence Framework(Hibernate, Mybatis...)
Persistence Framework
Persistence Layer
- 데이터 베이스에 데이터를 저장(Create), 데이터베이스에서 데이터를 읽어(Read) 객체화하거나, 수정(Update), 삭제(Delete)하는 역할
Persistence Framework
- JDBC 프로그래밍의 복잡함이나 번거로움 없이 간단한 작업만으로
데이터베이스와 연동되는 시스템을 빠르게 개발할 수 있음.
- 일반적으로 SQL Mapper와 ORM으로 나눠짐.
1) ORM (Object-Relational Mapper) :
ORM(Object-relational mapping)은 객체(클래스)와 관계(RDB, Relational Database)와의 설정을 말함.
객체 지향 프로그래밍은 클래스를 사용하고 관계형 데이터 베이스는 테이블을 사용하며,
여기서 객체 모델과 관계형 모델간에 불일치가 발생하게 되는데,
ORM은 이러한 불일치를 객체간의 관계를 바탕으로 SQL을 자동으로 생성하여 불일치를 해결한다.
Object와 DB 데이터 사이에서 매핑함.
장점
- 객체 지향적 코드를 사용해 직관적이며 비지니스 로직에 집중할 수 있도록 도와줌.
- CRUD를 위한 SQL문을 작성할 필요 없지만 쿼리 작성은 필요함.
- 각 객체(Model) 별로 코드를 작성하므로 가독성이 높음.
- 재사용 및 유지 보수의 편리성.
- ORM은 독립적으로 작성이 되어 있고 해당 객체들은 재사용이 가능.
- DBMS에 대한 종속성이 줄어듬.
- 대부분의 ORM은 DB에 비종속적임.
단점
- 완벽한 ORM만으로는 구현하기가 어려움.
- 사용하기는 편하지만 설계는 신중해야함.
- 프로젝트의 복잡성이 높아질 경우, 난이도도 높아짐.
- 잘못 구현하는 경우 속도 저하 및 심한 경우, 일관성이 무너질 수 있음.
- 프로시저가 많은 시스템에서는 ORM의 객체 지향적인 장점 활용도 낮음.
- ORM 종류 -
1. Flask : SQLAlchemy
2. Django : 내장 ORM
3. Node.js : Sequalize
4. Java : Hybernate, JPA
5. GraphQL : Prisma
2) SQL (Structed Query Language):
SQL은 Structed Query Language의 줄임말로 관계형 데이터 베이스의 데이터를 관리 및 처리하기 위해 설계된 언어.
SQL은 관계형 데이터베이스 관리 시스템(RDBMS)의 데이터를 관리 및 처리하기 위해 설계된 특수 목적의 프로그래밍 언어이며
질의(Query) 언어라고 불리기도 하며, 관계형 데이터 베이스 관리 시스템에서 자료의 검색과 관리, 데이터베이스 스키마 생성과 수정,
데이터 베이스 객체 접근 조정 관리를 위해 고안되었다.
MySQL, MariaDB, MSSQL, 오라클 등의 데이터베이스 관련 프로그램들이 SQL을 표준으로 채택한다.
- 객체와 SQL을 매핑함.
- 단순 필드 매핑이 목적.
- 개발자가 SQL문을 작성해서 직접 DB를 조작함.
ex) iBatis, MyBatis(ORM X)
- 데이터베이스가 SQL을 받아들이는 방식 -
1. 띄어쓰기 단위로 구분
2. 예약어 매칭
3. 예약어 규칙
- SQL 언어 특성 -
- SQL은 기본적으로 대소문자를 구분하지 않지만, 서버 환경이나 DBMS 종류에 따라 데이터베이스 또는 필드명에 대해 대소문자 구분.
- SQL 명령은 반드시 세미콜론(;).
- 고유값은 따옴표(").
- SQL에서 객체를 나타낼 땐 백틱(` `).
- 주석은 문장 앞에 --을 붙여 사용하고, 여러 줄의 주석은 /* */
- SQL 명령어 -
SQL 명령어는 크게 3가지로 나눠봤다.
-DDL (Data Definition Language, 데이터 정의 언어)
: DDL은 데이터베이스 스키마와 설명을 처리하도록 정의하는 언어입니다. 데이터베이스나 테이블 생성/변경/삭제 등의 작업 포함됨.
*CREATE (데이터베이스 개체(테이블, 인덱스, 제약조건 등)의 정의
*DROP (데이터베이스 개체 삭제)
*ALTER (데이터베이스 개체 정의 변경)
-DML (Data Manipulation Language, 데이터 조작 언어)
: 데이터 검색, 삽입, 변경, 삭제 수행을 조작하는 언어입니다. 실질적으로 저장된 데이터를 관리하고 처리할 때 사용함.
*SELECT (테이블 데이터의 검색 결과 집합의 취득)
*INSERT (행 데이터 또는 테이블 데이터의 삽입)
*DELETE (데이터의 삭제)
*UPDATE (표 업데이트)
-DCL (Data Control Language, 데이터 제어 언어)
: 사용자 관리 및 사용자별로 릴레이션 또는 데이터를 관리, 접근 권한을 다루는 언어.
*COMMIT : 트랜잭션의 작업 결과를 반영
*ROLLBACK : 트랜잭션의 작업을 취소 및 원래대로 복구
*GRANT : 사용자에게 권한 부여
*REVOKE : 사용자 권한 취소
MVC (Model-View-Controlle):
Model : 어플리케이션 계층의 정보, 데이터 의미
View : 화면 출력 로직을 담당
Controller : Model과 View의 연결하는 제어 로직을 담당.
- MVC 처리 순서 -
전체 흐름 :
요청 -> 프론트 컨트롤러 -> 핸들러 매핑 -> 핸들러 어댑터 -> 컨트롤러 ->
로직 수행(서비스) -> 컨트롤러 -> 뷰 리졸버 -> 응답(jsp, html)
- DispatcherServlet -
- Spring Framework가 제공하는 Servlet 클래스
- Spring MVC의 핵심 구성 요소
- 사용자의 Request 을 관리
- Dispatcher가 받은 Request 을 HandlerMapping에게 위임
- Spring에서는 front controller는 DispatcherServlet 이라고 하고 controller는 handler라고 말함
- HandlerMapping -
- requestURL과 Controller 클래스의 맵핑을 관리 ( @RequestMapping )
- HandlerMapping 인스턴스의 정보로 맵핑된 Controller에게 위임
- Controller -
- 요청에 맵핑 된 Controller 위임됨 ( @Controller )
- @RequestMapping 을 통하여 요청을 처리할 메서드에 호출
- 필요한 비즈니스 로직을 호출
- 해당 요청을 처리할 Service를 주입(DI)받아 Service에게 위임 ( @Service )
- Service에서는 비즈니스 로직을 구현
- connection pool를 담당하는 DAO가 주입(DI)받아 대신 DB에 접근한다. ( @Repository )
- 결과 데이터를 다시 Controller에 전달
- View에 전달 할 결과 데이터(Model)와 이동할 화면(View) 정보를 스프링 MVC가 제공하는 ModelAndView 인스턴스에 담 아 DispatherServlet에 반환된다.
- DispatherServlet는 ViewResolver에게 뷰 논리정보(View Name)를 전달
- ModelAndView -
- Controller에서 처리 결과를 View에 전달 할 결과 데이터(Model)와 이동할 화면(View) 정보를 담는 클래스
- Controller 메서드에서 리턴타입이 String이여도 핸들러에서 ModelAndView 인스턴스에 View정보를 넣는다.
- ViewResolver -
- ViewResolver는 View Name를 이용해 알 맞는 view객체를 찾는다.
- View에 model을 rendering하여 View 인스턴스를 다시 DispatherServlet에 보냄
- DispatcherServlet은 최종 결과를 클라이언트에 응답
- View -
- 결과데이터인 Model 객체를 보여한다.
-----------------------이해하기 조금 더 수월하게------------------------
- 컨트롤러 중에서도, 맨 앞단에서 유저의 유청을 받는 컨트롤러를 프론트 컨트롤러라고 함.
- DispatcherServlet 객체가 이 역할을 함.
- 본격적으로 로직에 들어오기 전에, 요청에 대한 선처리 작업을 수행함.
- ex. 지역 정보 결정, 멀티파트 파일 업로드 처리 등
- 프론트 컨트롤러는 요청을 핸들러 매핑을 통해 해당 요청을 어떤 핸들러가 처리해야하는지를 매핑함.
- HandlerMapping 객체가 핸들러 매핑에 대한 정보를 담고있음.
- 이렇게 매핑된 핸들러를 실제로 실행하는 역할은 핸들러 어댑터가 담당함.
- HandlerAdapter 객체가 이 역할을 함
- 컨트롤러는 해당 요청을 처리하는 로직을 담고있음.
- 보통 요청의 종류 혹은 로직의 분류에 따라 내부적으로 Service 단위로 나누어 모듈화 함.
- 각 서비스에서는 DB 접근할 수 있는 Repository 객체를 이용하여 데이터에 접근할 수 있음.
- 컨트롤러는 서비스에서의 로직 처리 후, 결과를 뷰 리졸버를 거쳐 뷰 파일을 렌더링하여 내보냄.
- ViewResolver 객체가 이 역할을 함.
Spring MVC 구현
1. DispatcherServlet 프론트 컨트롤러로 세팅
2. 전반적인 모듈 구성
- config -
- 각종 설정 클래스 파일들을 담고 있음.
- 클래스 앞에 @Configuration 이 붙음.
- WebMvc 설정 관련 Config 를 제외하고 나머지는 모듈화한 뒤 Application 에서 모두 import
- @Controller 관련 빈들은 WebMvcContextConfiguration 에서 @ComponentScan 으로 찾아줘야하고,
- @Service, @Service, @Component 관련 빈들은 ApplicationConfig 에서 찾아줘야 함.
- 예를 들어 ApplicationConfig 는 다음과 같음.
- controller -
- 각종 컨트롤러 클래스 파일들을 담고 있음.
- 클래스 앞에 @Controller 가 붙음.
- 각 컨트롤러 코드는 URI 매핑을 담당.
- Serivce 인스턴스를 가져와 로직을 실행하고, View 단에 나가기 전후 작업을 담당
- 예를 들어 GuestbookController 는 다음과 같음.
- dao -
- DB 에 대해 접근할 때 사용하는 클래스 파일들을 담고 있음.
- 클래스 앞에 @Repository 가 붙음.
- 실제 dao 클래스와, 사용할 SQL 만을 담고있는 클래스가 따로 모듈화해서 사용함.
- 예를 들어 GuestbookDao 와 GuestbookDaoSqls 는 다음과 같이 생음.
- dto -
- 데이터를 모델링한 클래스 파일들을 담고있음.
- 필드(프로퍼티)와 Getter, Setter 를 가짐.
- 예를 들어 Guestbook 는 다음과 같이 같음.
- service -
- 서비스 로직을 담는 클래스 파일들을 담고있음.
- 클래스 앞에 @Service 가 붙음.
- Interface로 핵심 로직 먼저 정의한 후, 클래스로 구현.
- 필요한 경우, Dao 를 직접 사용하는 클래스임.
- 예를 들어 GuestbookServiceImpl 는 다음과 같음
- webapp/WEB-INF/views -
- 렌더링 되는 뷰 관련 파일(.jsp)들을 담고있음.
- 이 파일들은 뷰 리졸버를 거쳐, 최종적으로 렌더링 되기 직전의 파일임.
- 레이어드(Layered) 아키텍처 -
여러 모듈들을 일종의 레이어 단위로 나누는 설계 방식을 말함.
크게 다음 레이어들로 구성됨.
- Presentation Layer
- 화면 조작 또는 사용자 입력을 처리하는 레이어
- Service Layer (Domain)
- 비즈니스와 관련된 도메인 로직을 처리하는 레이어
- 하나의 비즈니스 로직은 하나의 트랜잭션 단위로 동작.
- Repository Layer (Data source)
- 도메인에서 필요로 하는 데이터를 조작하기 위한 레이어
회고를 작성하며 공부하게 됬는데 따로 찾아보며 공부할 때보다 정리하며 공부하는 것이
이해가 더 잘 되는 것 같고 원리도 알게 되니 회고를 통해 오늘도 배운 점이 컸다.