-
210708_1(Spring3_MyBatis)Spring 2021. 7. 8. 17:56
어노테이션과 자동생성 스프링 MVC 프레임워크
@은 xml을 대체하는 효과를 가지고 온다.
외우면 좋은 @
자동생성 스프링 MVC 분석
1) web.xml
/WEB-INF/spring/root-context.xml <=== 스프링 기본환경 문서. 빈생성, DI, AOP 여기서 구현
/WEB-INF/spring/appServlet/servlet-context.xml <=== 스프링MVC 환경문서. HM, VR 여기서 구현
<?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 --> <!-- ContextLoaderListener가돌아갈때 위를 참조한다. --> <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><!-- 핼들러매핑과 뷰리졸버 servlet-context.xml--> </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>
2) 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 --> </beans>
3) servlet-context.xml
자동으로 빈이 되는조건 : 아래 두개의 태그를 만족해야한다
<annotation-driven /> 어노테이션이 붙은 요소(클래스,,,,)는 빈으로 자동 생성됨
<bean> 태그를 설정하지 않아도 된다.
<context:component-scan base-package="com.mysite.beans" />
해당패키지 아래있는 어노테이션이 붙은 클래스만 자동으로 빈이 생성된다
해당 위치에 있는 클래스가 어노테이션이 붙어 있느냐
<resources mapping="/resources/**" location="/resources/" />
정적 요소들이 저장된 위치 html, css, js, png, jpg,,,,
<default-servlet-handler/>
jsp같은 문서들을 호출하려면 추가해준다.
InternalResourceViewResolver
"/WEB-INF/views/" 아래에있는 웹문서를 파싱할수 있다. 원칙적으로는 /WEB-INF/아래에는 만들수 없었다
<?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 --> <!-- 정적 문서, 객체들이 위치하는 곳 , html,css,js,png,jpg,,,--> <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"> <!-- InternalResourceViewResolver : "/WEB-INF/views/" 아래에있는 웹문서를 파싱할수 있다. 원칙적으로는 안됐었다. --> <beans:property name="prefix" value="/WEB-INF/views/" /> <beans:property name="suffix" value=".jsp" /> </beans:bean> <!-- 해당패키지 아래있는 어노테이션이 붙은 클래스만 자동으로 빈이 생성된다 --> <context:component-scan base-package="com.mysite.beans" /> <default-servlet-handler/><!-- jsp같은 문서들을 인식한다. --> </beans:beans>
서버에돌리면 루트가 beans인점 확인
http://localhost:8888/beans/
Server.xml 에서의 path 설정때문
<Context docBase="spring_auto" path="/beans" reloadable="true" source="org.eclipse.jst.jee.server:spring_auto"/>
homeController.java
package com.mysite.beans;
패키지가 지정된 곳이고
@Controller <=== 컨트롤러 클래스 앞에 붙는 어노테이션
public class HomeController {클래스앞에 @이 붙어있으니 자동으로 빈으로 등록 된다.
@RequestMapping(value = "/", method = RequestMethod.GET)
찾는 경로가 Get방식으로 루트/ 이면 바로 밑에 있는 메서드가 동작한다.
public String home(Locale locale, Model model) { //<--- 실행된다
Model model <=== 뷰에서 사용할 데이터를 저장한다.
package com.mysite.beans; import java.text.DateFormat; import java.util.Date; import java.util.Locale; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; /** * Handles requests for the application home page. */ @Controller //컨트롤러 클래스 앞에 붙는 어노테이션 public class HomeController { // 클래스앞에 @가 붙어있으니 자동으로 빈으로 등록된다. private static final Logger logger = LoggerFactory.getLogger(HomeController.class); /** * Simply selects the home view to render by returning its name. */ @RequestMapping(value = "/", method = RequestMethod.GET) //찾는경로가 / 면 바로 밑에 있는 메서드가 동작한다. public String home(Locale locale, Model model) { //<--- 실행된다 Model model 뷰에서 사용할 데이터를 저장 //뷰 이름을 String으로 저장한다 logger.info("Welcome home! The client locale is {}.", locale); Date date = new Date(); DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale); String formattedDate = dateFormat.format(date); model.addAttribute("serverTime", formattedDate ); // 뷰에서 사용할 데이터를 모델에 저장한다. (키,밸류) return "home"; // 뷰이름을 리턴한다. /WEB-INF/view/home.jsp } }
@Controller : 컨트롤러 관련 클래스에 붙는다
@Repository : DAO관련 클래스에 붙는다
@Service : 각종 서비스 클래스에 붙는다
@Autowired : 자동으로 빈이 주입된다. 즉 세터가 필요없다
@Component : 일반적인 클래스에 붙인다.
사전작업
1단계
pom.xml
<!-- ojdbc를 위한 repositories세팅 --> <repositories> <repository> <id>ojdbc14</id> <name>oracle.com</name> <url>http://maven.geomajas.org/</url> </repository> </repositories> <dependencies> <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.7</version> </dependency> <!-- https://mvnrepository.com/artifact/com.oracle.jdbc/ojdbc14 --> <dependency> <groupId>com.oracle.jdbc</groupId> <artifactId>ojdbc14</artifactId> <version>10.2.0.1.0</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>3.1.1.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.6</version> </dependency>
oracle.sql
drop sequence seq_id; create sequence seq_id increment by 1 start with 1; create table spring_board( id number(10) not null, subject varchar2(50), name varchar2(50), created_date date, mail varchar2(50), memo varchar2(200), hits number(5), primary key (id) );
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 --> <!-- ContextLoaderListener가돌아갈때 위를 참조한다. --> <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><!-- 핼들러매핑과 뷰리졸버 servlet-context.xml--> </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>
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" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- Root Context: defines shared resources visible to all other web components --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="diverClassName"> <value>oracle.jdbc.driver.OracleDriver</value> </property> <property name="url"> <value>jdbc:oracle:thin:@localhost:1521:XE</value> </property> <property name="username"> <value>jspuser</value> </property> <property name="password"> <value>1234</value> </property> </bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <!-- 아래는 xml파일에 매퍼를 정의할때 --> <!-- <property name="configLocation" value="/WEB-INF/spring/mybatis/mybatis-config.xml"/> <property name="mapperLocation" value="classpath:mysite/com/app/Mapper*.xml"/> --> </bean> <!-- commot과 rollback의 스프링이 자동적용 --> <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg index="0" ref="sqlSessionFactory"></constructor-arg> </bean> <!-- 소스코드에 어노테이션 트랜잭션을 활용할때 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <tx:annotation-driven transaction-manager="transactionManager" /> <!-- Mapper! 이용한 매퍼 --> <bean id="boardMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"> <property name="mapperInterface" value="com.mysite.beans.BoardMapper" /> <property name="sqlSessionFactory" ref="sqlSessionFactory" /> </bean> <!-- BoardService --> <bean id="boardService" class="com.mysite.beans.BoardService" /> </beans>
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 --> <!-- 정적 문서, 객체들이 위치하는 곳 , html,css,js,png,jpg,,,--> <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"> <!-- InternalResourceViewResolver : "/WEB-INF/views/" 아래에있는 웹문서를 파싱할수 있다. 원칙적으로는 안됐었다. --> <beans:property name="prefix" value="/WEB-INF/views/" /> <beans:property name="suffix" value=".jsp" /> </beans:bean> <!-- 해당패키지 아래있는 어노테이션이 붙은 클래스만 자동으로 빈이 생성된다 --> <context:component-scan base-package="com.mysite.beans" /> <default-servlet-handler/><!-- jsp같은 문서들을 인식한다. --> </beans:beans>
2단계
BoardMapper.java
package com.mysite.beans; import org.apache.ibatis.annotations.Result; import org.apache.ibatis.annotations.Results; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Update; import org.apache.ibatis.annotations.Delete; import org.springframework.stereotype.Repository; @Repository public interface BoardMapper { //여기에 어노테이션 방식의 sql과 호출 메서드가 기술됩니다. }
BoardBean.java
package com.mysite.beans; import org.springframework.stereotype.Repository; @Repository public class BoardBean { int id, hits; String name, mail, subject, created_date, memo; public int getId() { return id; } public void setId(int id) { this.id = id; } public int getHits() { return hits; } public void setHits(int hits) { this.hits = hits; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getMail() { return mail; } public void setMail(String mail) { this.mail = mail; } public String getSubject() { return subject; } public void setSubject(String subject) { this.subject = subject; } public String getCreated_date() { return created_date; } public void setCreated_date(String created_date) { this.created_date = created_date; } public String getMemo() { return memo; } public void setMemo(String memo) { this.memo = memo; } }
PageNumberingManager.java
package com.mysite.beans; import org.slf4j.Logger; import org.slf4j.LoggerFactory; //페이징 처리 유틸 파일 public class PageNumberingManager { private static final PageNumberingManager pageNumberingManager = new PageNumberingManager(); private static final Logger logger = LoggerFactory.getLogger(PageNumberingManager.class); private PageNumberingManager() { } public static PageNumberingManager getInstance() { return pageNumberingManager; } public int getTotalPage(int total_cnt, int rowsPerPage) { logger.info("getTotalPage called!"); int total_pages = 0; if ((total_cnt % rowsPerPage) == 0) total_pages = total_cnt / rowsPerPage; else total_pages = (total_cnt / rowsPerPage) + 1; logger.info("getTotalPage return total_pages=" + total_pages); return total_pages; } // 게시판의 block처리 추가 필요 (이전/다음 블럭 버튼 처리) public int getPageBlock(int curPage, int pagePerBlock) { int block = 0; if ((curPage % pagePerBlock) == 0) { block = curPage / pagePerBlock; } else { block = curPage / pagePerBlock + 1; } return block; } // block에 속한 첫번째 페이지 계산 public int getFirstPageInBlock(int block, int pagePerBlock) { return ((block - 1) * pagePerBlock + 1); } // block에 속한 마지막 페이지 계싼 public int getLastPageInBlock(int block, int pagePerBlock) { return (block * pagePerBlock); } }
BoardService.java
package com.mysite.beans; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class BoardService { @Autowired private BoardMapper boardMapper; //여기에 서비스 메서드 정의가 기술되어야 합니다. }
BbsController.java
package com.mysite.beans; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; @Controller public class BbsController { @Autowired BoardService boardService; private static final Logger logger = LoggerFactory.getLogger(BbsController.class); { //여기에 @어노테이션 이용한 컨트롤 매핑이 기술이 들어 갑니다. } }
사전작업끝
연결작업
글입력하기
1. 매퍼 기술-BoardMapper
ibatis #속성# ==> mybais #{속성}
final String INSERT = "insert into spring_board (id, subject, name, created_date, mail, memo, hits) " + " values (seq_id.nextval, #{subject}, #{name}, to_char(sysdate, 'yyyy-mm-dd'), #{mail}, #{memo}, 0 ) "; @Insert(INSERT) void insertBoard(BoardBean boardBean);
2. 서비스파일 기술 - BoardService
//1단계 글입력하기 public void insertBoard(BoardBean boardBean) { boardMapper.insertBoard(boardBean); }//insertBoard
3. 컨트롤러 기술 - BbsController + 매핑이 같이들어간다
1-0) 폼처리와 1-1)입력처리를 같이했다
model.addAttribute("boardBean", new BoardBean());
//1-0 글쓰기폼 @RequestMapping(value="/show_write_form.do", method = RequestMethod.GET) public String show_write_form (Model model) { logger.info("글쓰기입력폼이 호출되었습니다."); model.addAttribute("boardBean", new BoardBean()); return "writeBoard"; } //show_write_form //1-1 글쓰기 처리 @RequestMapping(value = "/DoWriteBoard.do", method = RequestMethod.POST) public String DoWriteBoard(BoardBean boardBeanObjToWrite, Model model) { logger.info("DoWriteBoard called"); logger.info("memo=["+boardBeanObjToWrite.getMemo()+"]"); boardService.insertBoard(boardBeanObjToWrite); //model.addAttribute("totalCnt",new Integer(boardService.getTotalCnt())); //model.addAttribute("current_page", new BoardBean());//글을 작성후에는 처음 페이지로 돌아간다. //model.addAttribute("boardList", boardService.getList(1,2)); return "listSpecificPage"; } //DoWriteBoard
4. 뷰 - writeBoard.jsp
스프링 폼태그에서 modelAttribute="boardBean"
3+4번 ----> 입력한 폼데이터를 자동으로 빈에 저장하여 컨트롤러로 전달함
즉, 입력처리 부분에서 request.getParameter()가 필요없다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@page import="java.io.*, java.text.*" %> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@taglib uri="http://www.springframework.org/tags/form" prefix="sf"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>글입력하기</title> </head> <body> <c:url var="insertUrl" value="/DoWriteBoard.do"/> <sf:form modelAttribute="boardBean" method="POST" action="${insertUrl}"> 이름 : <sf:input path="name" size="50" maxlength="50"/> <sf:errors path="name" cssClass="error"/><br> 이메일 : <sf:input path="mail" size="50" maxlength="50"/> <sf:errors path="mail" cssClass="error"/><br> 제목 : <sf:input path="subject" size="50" maxlength="50"/> <sf:errors path="subject" cssClass="error"/><br> 내용 : <sf:textarea path="memo" size="200" cssStyle="width:350px; height:100px;" maxlength="200"/> <sf:errors path="memo" cssClass="error"/><br> <input type="submit" value="등록하기"> </sf:form> </body> </html>
'Spring' 카테고리의 다른 글
210712_1~210713_1(SpringBoot) (0) 2021.07.12 210709_1(Spring3_MyBatis 글목록부터) (0) 2021.07.09 210707_1(Springmvc+iBatis, xml을 이용하는방법) (0) 2021.07.07 210706_1(iBatis) (0) 2021.07.06 210705_2(iBatis) (0) 2021.07.05