온 코딩

[Spring] MVC / TodoList / Lombok.jar 본문

복습 ARCHIVE/모델별 프로젝트

[Spring] MVC / TodoList / Lombok.jar

SummerON 2021. 6. 30. 17:40

Spring MVC 프로젝트 주요 폴더

1. src/main/java 개발되는 java 코드

2. src/main/resources 서버가 실행될 때 필요한 파일들 

 

3. WEB-INF/spring 스프링 설정 파일

4. WEB-INF/views : JSP파일

 

5. pom.xml : maven 설정 


        프레젠테이션 레이어    <=  ||  => 비즈니스 레이어 <= ||  => 퍼시스턴트 영역

JSP

HTML

CSS                <= Controller         <= Service   <= DAO         <= MyBatis

JavaScript

jQuery 


          spring-mybatis                                     MyBatis영역                      

DAO   <= SqlSessionTemplate                          

                                         DataSource    =>   SqlSessionFactory 

                                                                                   Configuration.xml

                                                                                           Mapper.xml    =>  DataBase


xml 문서 연관관계

web.xml  => root-context.xml                        => mybatis-context.xml               =>  todoMapper.xml

                    (미리 등록해 놓아야 할 객체들)                    (맵핑 객체 및 Sql 매퍼 파일)                     (SQL 쿼리)

             => servlet-context.xml

                   (요청이 들어왔을 때 등록해 놓아야 할 객체들)

 

root-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
	<!-- 전체 설정파일  -->
	<!-- Root Context: defines shared resources visible to all other web components -->
	
	<!-- db.properties Registration For Read -->
	<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="location">
			<value>classpath:db.properties</value>
		</property>
	</bean>
	
	<!-- db.properties Read And Settings -->
	<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="${driver}"></property>
		<property name="url" value="${url}"></property>
		<property name="username" value="${user}"></property>
		<property name="password" value="${password}"></property>
	</bean>
	
	<!-- Transaction Registration -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	
	<!-- SqlSessionTemplate For MyBatis -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource"></property>
		<property name="configLocation" value="classpath:mybatis-config.xml"></property>
	</bean>
	
	<!-- SqlSession For MyBatis -->
	<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
		<constructor-arg index="0" name="sqlSessionFactory" ref="sqlSessionFactory"/>
	</bean>
	
</beans>

mybatis-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- Mapper 기본설정 -->
	<typeAliases>
		<typeAlias type="com.hhw.biz.dto.Todo" alias="Todo" />
	</typeAliases>
	<mappers>
		<mapper resource="Mapper/todoMapper.xml"/>
	</mappers>
</configuration>

<Mapper> 상대경로~~

1. SQL 쿼리를 선언한 Mapper에서 데이터를 자동 맵핑할 수 있도록 VO(DTO) 객체 설정 // alias

2. DataSource에 관한 설정 (DI방법에 따라 선택, 즉 생략 가능)

3. Mapper 파일의 위치 설정 

 

todoMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mapper.todoMapper">
	<!-- SQL 쿼리 -->
</mapper>

SQL 관련

namespace="com.hhw.biz.repository.TodoMapper" => namespace는 유일한 값 // Sqlsession에서 접근 가능한 맵퍼 인터페이스 풀네임 

 

servlet-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:beans="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
	
	<!-- 핸들러, 디스패쳐서블릿, 뷰리졸버  : 요청이 들어왔을 때 등록하는 객체들 -->
	
	<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
	
	<!-- Enables the Spring MVC @Controller programming model -->
	<annotation-driven />

	<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
	<resources mapping="/resources/**" location="/resources/" />

	<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
	<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<beans:property name="prefix" value="/WEB-INF/views/" />
		<beans:property name="suffix" value=".jsp" />
	</beans:bean>
	
	<context:component-scan base-package="com.hhw.biz" />
	
	
	
</beans:beans>

<resources mapping="/resources/**" location="/resources/" /> 이미지와 같은 resource 가져오는 코드

 


어노테이션 주입 순서 : @Repository -> @Controller

>> 어노테이션을 통해 컨트롤러에서 DAO 사용가능하게 자동으로 맵핑 해줌

* servlet-context.xml에서 어노테이션과 뷰 리졸버 등록 


web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

	<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/spring/root-context.xml</param-value>
	</context-param>
	
	<!-- Creates the Spring Container shared by all Servlets and Filters -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<!-- Processes application requests -->
	<servlet>
		<servlet-name>appServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
		
	<servlet-mapping>
		<servlet-name>appServlet</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

</web-app>

1. 사전등록관련

<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>

<!-- Creates the Spring Container shared by all Servlets and Filters -->

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

: 구동 시작과 함께 Context의 값을 받아서 처리 => root-context.xml 값을 가져옴

 

root-context.xml

db.properties

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">

=> 프로젝트 구동 시 미리 등록 됨!!

 

2. 요청 시 등록 관련

<!-- Processes application requests -->
<servlet>                                                                                                     < 3.          
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>       < 4.   디스패쳐서블릿 생성등록
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>           < 5. 생성등록 완성
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>                                                                                                    < 6. 생성등록 끝

<servlet-mapping>
<servlet-name>appServlet</servlet-name>                                                        < 2.     
<url-pattern>/</url-pattern>                                                                          < 1.     
</servlet-mapping>

: 웹 브라우저로부터 요청사항이 들어오면 실행 됨 

 

servlet-context.xml

<annotation-driven> 

: @annotation 클래스 찾아서 등록 @Controller ".biz.controller" 홈컨트롤러

                                             @Repository   ".biz" 

                                             * 컨트롤러는 biz의 하위폴더기 때문에 @Repository가 먼저 등록됨!  

여기서 @Autowried 어노테이션으로 사전등록된 요소들과 자동 맵핑( ex) sqlSession )

@RequestMapping 

뷰리졸버

 

"/"요청 : DispatcherServlet이 Requsetmapping을 찾고 값이 없으면 homeController로 가서 찾아서 요청 처리 


웹브라우저 <-> 서버 요청/응답 처리

웹 브라우저에서는 WEB-INF아래 있는 jsp에 접근 불가능 

->프로젝트명을 이용해서 실행 -> 홈컨트롤러에 의해서 초기화면 생성~~!

:WEB-INF에 넣는 이유 : webapp에 jsp를 넣을 시 주소줄에 위치 노출이 되는 걸 방지하기 위해서 

주소 : http://localhost:9000/biz/

http://localhost:9000 => 톰캣 서버 주소 

/biz                       => 톰캣서버 내부의 프로젝트(컨테이너)

/                           => 실제 요청사항 문자열 (DispatcherServlet에게 전달)

 

DispatcherServlet의 작동원리

1. "/"과 동일한 값을 갖고 있는 메서드 검색 ( 없으면 404 err)

2. HomeController => @RequestMappin(value="/")

3. "main" 문자열을 DispatcherServlet에 전달

4. DispatcherServlet은 ViewResolver 객체를 찾고 ViewResolver 에게 "main"에 대한 구체적인 내용 문의

5. ViewResolver에서 prefix와 suffix를 이용해 주소 찾아서 DispatcherServlet에 응답

6. DispatcherServlet이 주소를 웹 브라우저에 응답 

7. 웹브라우저가 주소를 통해 다시 애플리케이션에 요청

8. DispatcherServlet이 받은 요청을 토대로 main.jsp 파일을 컴파일하여 html 형태로 웹 브라우저에 응답처리

9. 웹 브라우저는 응답받은 html 형태의 문서를 HTML 엔진을 통해 컴파일하여 사용자에게 출력


프레임워크

웹 프로젝트 : Spring / Struts

데이터베이스 : Mybatis, Ibatis / Hybernate

프론트 : JQuery / 타입리프 / node.js / react.js / vue.js

데이터 : collection (Map/List/Set)

+ 웹 어셈블리 언어


Mybatis 에서 SQL 쿼리 실행 

1. SqlSession 내에 선언 되어 있는 메서드를 이용하는 방법 

  SqlSession객체.insert("Mapper의 namespace.태그id" , VO객체); 

                     .delete("Mapper의 namespace.태그id" , VO객체);

                     .update("Mapper의 namespace.태그id" , VO객체);

                     .selectOne("Mapper의 namespace.태그id" , VO객체);

                     .selectList("Mapper의 namespace.태그id" , VO객체);

 

2. 개발자가 새로운 메서드를 선언하여 이용하는 방법 

1) interface 선언(TodoMapper.java)

2) ~~Mapper.xml

<mapper namespace="TodoMapper">

3) DAO 역할을 하는 Repository.java 

TodoMapper todomapper = SqlSession객체.getMapper(TodoMapper.class);

todomapper.insertUser(vo); // 이와 같이 인터페이스에 정의 된 메서드를 사용 

*interface가 가지고 있는 메서드명과 ~~Mapper.xml에 가지고있는 sql 실행 태그의 id명이 일치해야함


lombok.jar

설치방법 (cmd) java-jar lombok.jar

설치 후, dependency 등록하여 사용 

lombok 라이브러리의 대표적인 특징은 VO 클래스 선언시, getter/setter/toString 등의 메서드를 자동으로 만듦

개발자는 멤버변수만 선언하면 되기 때문에, VO(DTO) 사용 시 자주 사용됨 

 

기본 어노테이션 

@NonNull : 해당 값이 Null일 경우 NullPointerExceptrion을 발생 

@Cleanup : 자동 리소스 관리 :close() 메서드를 귀찮음 없게 안전하게 호ㅜㄹ

 

@Getter(lazy=true) : 동기화를 이용하여 최초 1회만 getter가 호출

 

@Getter/ @Setter : getter/setter를 코딩하지 않도록 자동 생성 지원 

@ToString : 모든 필드를 출력하는 toString() 메서드 생성 

 

@EqualsAndHashCode : hashcode와 equals 메소드를 생성 

 

@NoArgsContructor, @RequiredArgsContructor and @AllArgsConstructor : 인자 없는 생성자 생성, 필수 인자만 있는 생성자 생성, 모든 인자를 가진 생성자 생성 

 

@Data : @ToString, @EqulasAndHashCode, @Getter(모든필드) , @Setter(모든필드 - final로 선언되지 않은) , @RequiredArgsConstructor!

 

@SneakyThrows : Exception 발생시 체크 된 Throable로 감싸서 전달

 

@Log : 종류별 로그를 사용할 수 있도록 한다. (@Log, @CommonLog, @S1f4j 등)


 

Comments