[spring] 스프링 MVC 프로젝트의 기본 구성
업데이트:
일반적으로 웹 프로젝트는 3-tier
방식으로 구성된다.
Presentation Tier(화면 계층)
- 화면에 보여주는 기술을 사용하는 영역(Servlet/JSP or 스프링 MVC)
- Presentation Tier는 프로젝트의 성격에 맞춰 앱으로 제작하거나, CS(Client-Server)로 구성되는 경우도 있다.
Business Tier(비즈니스 계층)
- 순수한 비즈니스 로직을 담고 있는 영역
- 고객이 원하는 요구 사항을 반영하는 계층
- 고객의 요구 사항과 정확히 일치해야 함
- 주로 ‘xxxService’와 같은 이름으로 구성
- 메서드의 이름은 고객들이 사용하는 용어 그대로 사용
Persistence Tier(영속 계층 혹은 데이터 계층)
- 데이터를 어떤 방식으로 보관하고, 사용하는 가에 대한 설계
- 일반적인 경우에는 데이터베이스를 많이 이용하지만, 경우에 따라서는 네트워크 호출이나 원격 호출 등의 기술이 접목
- MyBatis와 mybatis-spring
계층에 대한 설명을 스프링 MVC와 맞춰서 설명해보면 다음과 같은 구조가 된다.
스프링 영역은 Presentation Tier를 구성하게 되는데, 각 영역은 사실 별도의 설정을 가지는 단위라고 볼 수 있다. 스프링 Core 영역은 흔히 POJO(Plain-Old-Java-Object)의 영역이다. 스프링의 의존성 주입을 이용해서 객체 간의 연관구조를 완성해서 사용한다. MyBatis 영역은 현실적으로는 mybatis-spring을 이용해서 구성하는 영역이며, SQL에 대한 처리를 담당하는 구조이다.
각 영역의 Naming Convention(명명규칙)
프로젝트를 위와 같이 3-tier로 구성하는 가장 일반적인 이유는 유지 보수
에 대한 필요성 때문이다. 각 영역은 독립적으로 설계되어 나중에 특별한 기술이 변하더라도 필요한 부분을 전자제품의 부품처럼 쉽게 교환할 수 있게 하자는 방식이다. 따라서 각 영역은 설계 당시부터 영역을 구분하고, 해당 연결 부위는 인터페이스를 이용해서 설계하는 것이 일반적인 구성방식이다.
네이밍 규칙
- xxxController : 스프링 MVC에서 동작하는 Controller 클래스를 설계할 때 사용
- xxxService, xxxServiceImpl : 비즈니스 영역을 담당하는 인터페이스는 ‘xxxService’, 인터페이슬 구현한 클래스를 ‘xxxServiceImpl’ 사용
- xxxDAO, xxxRepository : DAO(Data-Access-Object)나 Repository(저장소)라는 이름으로 영역을 따로 구성하는 것이 보편적이다. 여기서는 DAO 대신 MyBatis의 Mapper 인터페이스 활용
- VO, DTO : VO와 DTO는 일반적으로 유사한 의미로 사용하는 용어이다. 데이터를 담고 있는 객체를 의미한다는 공통점이 있다.
- VO : 주로
Read Only
의 목적이 강하고, 데이터 자체도 Immutable(불변)하게 설계한다. - DTO : 주로 데이터 수집 용도의 목적으로 사용한다. 예를 들어, 로그인 정보를 DTO로 처리하는 방식을 사용한다.
- VO : 주로
패키지의 Naming Convention
패키지의 구성은 프로젝트의 크기나 구성원들의 성향으로 결정한다.
- 규모가 작은 프로젝트 : Controller 영역을 별도의 패키지로 설계, Service 영역등을 하나의 패키지로 설계
- 규모가 큰 프로젝트 : 비즈니스를 단위별로 구분, 다시 내부에서 Controller 패키지, Service 패키지 등으로 다시 나누는 방식을 이용한다.
프로젝트를 위한 요구사항
프로젝트를 진행하기 전에 고객의 요구사항을 인식하고, 이를 설계하는 과정이 필요하다. 이를 흔히 요구사항 분석 설계
라고 한다.
요구사항은 온전한 문장으로 정리하는 것이 좋다. 주어는 ‘고객’ 목적어는 ‘대상’이 된다. 여기서의 ‘대상’은 결국 데이터의 베이스 설계와 시스템 설계에서 가장 중요한 용어가 된다.
- 고객은 새로운 게시물을 등록할 수 있어야 한다.
- 고객은 특정한 게시물을 조회할 수 있어야 한다.
- 고객은 작성한 게시물을 삭제할 수 있어야 한다.
- 기타 등등
요구사항에 따른 화면 설계
요구사항을 기준으로 테이블이나 클래스의 멤버 변수(인스턴스 변수)들을 설계하게 된다. 실제 프로젝트에서는 ‘스토리보드’를 만들게 된다.
이러한 화면을 설계할 때는 주로 Mock-up(목업)
툴을 이용하는 경우가 많다. 대표적으로는 PowerPoint, Balsamiq studio, Pencil Mockup, 카카오오븐 등의 SW를 이용한다.
각 화면을 설계하는 단계에서는 사용자가 입력해야 하는 값과 함께 전체 페이지의 흐름이 설계 된다. 이 화면의 흐름을 URL
로 구성하게 되는데 이 경우 GET/POST 방식을 사용하게 된다.
예제 프로젝트 구성
예제 프로젝트 생성
pom.xml 수정
- 스프링 버전, Java 버전 수정
<java-version>1.8</java-version>
<org.springframework-version>5.0.7.RELEASE</org.springframework-version>
- 라이브러리 추가(spring-tx, spring-jdbc, spring-test)
<!-- spring-test -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- spring-tx -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${org.springframework-version}</version>
</dependency>
- MyBatis 관련 라이브러리 추가(HikariCP, MyBatis, mybatis-spring, Log4jdbc)
<!-- HikariCP -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>4.0.3</version>
</dependency>
<!-- mybatis -->
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.bgee.log4jdbc-log4j2/log4jdbc-log4j2-jdbc4 -->
<dependency>
<groupId>org.bgee.log4jdbc-log4j2</groupId>
<artifactId>log4jdbc-log4j2-jdbc4</artifactId>
<version>1.16</version>
</dependency>
- JUnit 버전 수정, Lombok 추가
<!-- Test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
<scope>provided</scope>
</dependency>
- Servlet 3.1(3.0)으로 수정
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
- Maven 관련 Java 버전 1.8로 수정
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<compilerArgument>-Xlint:all</compilerArgument>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
pom.xml 수정 완료 후 ‘컨트롤+s’ 누르고 프로젝트 우클릭 > Maven > Update Project 클릭
마지막으로 Oracle JDBC Driver를 프로젝트의 Build Path에 추가하고, Deployment Assembly에도 추가한다.
테이블 생성과 Dummy(더미) 데이터 생성
SQL Developer를 이용해서 book_ex 계정을 통해 테이블 생성. 게시글마다 고유의 번호가 필요한데 이부분은 시퀀스
를 이용해서 처리한다.
--시퀀스를 생성할 때는 다른 오브젝트와 구분하기 위해 'seq'와 같이 시작한다.--
CREATE SEQUENCE seq_board;
--테이블을 생성할때는 'tbl_'로 시작하거나 't_'로 시작한다. --
CREATE TABLE tbl_board (
bno number(10, 0),
title varchar2(200) not null,
content varchar2(2000) not null,
writer varchar2(50) not null,
regdate date default sysdate, --생성 시간--
updatedate date default sysdate --최종 수정 시간--
);
-- bno을 기본 키로 지정 --
ALTER TABLE tbl_board ADD CONSTRAINT pk_board PRIMARY KEY (bno);
더미데이터 추가
INSERT INTO tbl_board (bno, title, content, writer)
VALUES (seq_board.NEXTVAL, '테스트 제목', '테스트 내용', 'user00');
COMMIT;
오라클에서는 INSERT를 한 후 반드시 COMMIT
을 해줘야 데이터의 추가/변경 사항이 테이블에 적용된다.
COMMIT 후 SELECT문을 이용해 테이블을 조회한다.
SELECT * FROM tbl_board;
데이터베이스 관련 설정 및 테스트
- root-context.xml 네임스페이스
- root-context.xml 추가
<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
<property name="driverClassName"
value="net.sf.log4jdbc.sql.jdbcapi.DriverSpy"></property>
<property name="jdbcUrl"
value="jdbc:log4jdbc:oracle:thin:@localhost:1521:XE"></property>
<property name="username" value="book_ex"></property>
<property name="password" value="book_ex"></property>
</bean>
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource"
destroy-method="close">
<constructor-arg ref="hikariConfig"/>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
</bean>
<mybatis-spring:scan base-package="org.zerock.mapper" />
- log4jdbc.log4j2.properties 파일 추가
-
DataSourceTest 클래스, JDBCTests 클래스 테스트 패키지에 추가
-
DataSourceTest, JDBCTests 테스트로 오류가 없는지 확인
- 참고 : 코드로 배우는 스프링 웹 프로젝트
댓글남기기