[KOSTA] Spring 기반 Cloud 서비스 개발자 양성 과정 72일차 - Spring (CRUD, Mybatis, RequestParam, ModelAttribute, Restful, PathVariable, tiles)

JUNBEOM PARK·2022년 5월 17일
0
post-thumbnail

📖 배운 내용

  1. Mybatis
  2. CRUD
  3. @RequestParam
  4. @ModelAttibute
  5. @PathVariable(RESTful)
  6. tiles


1. Mybatis 연동

 <Context docBase="spring_web" 
          path="/spring_web" 
          reloadable="true" 
          source="org.eclipse.jst.jee.server:spring_web">
      	<Resource auth="Container" 
                  driverClassName="oracle.jdbc.driver.OracleDriver" 
                  maxActive="100" maxIdle="30" maxWait="10000" name="jdbc/oracle"
                  password="1234" type="javax.sql.DataSource" 
                  url="jdbc:oracle:thin:@localhost:1521:XE" username="kosta236"/>
 </Context>

위와 같은 형식으로 server.xml에 등록 해준다.



<!-- Mybatis Setting -->
	
	<bean id="sqlSessionTemplate"
		class="org.mybatis.spring.SqlSessionTemplate">
		<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"></constructor-arg>	
	</bean>
	
	<bean id="sqlSessionFactory"
		class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="myDataSource"/>
		<property name="configLocation" value="/WEB-INF/mybatis-config.xml"></property>
	</bean>
	
	<bean id="myDataSource"
		class="org.springframework.jndi.JndiObjectFactoryBean">
		<property name="jndiName" value="jdbc/oracle"/>
		<property name="resourceRef" value="true"/>
	</bean>

sqlSessionTemplate을 사용하기 위해 위와 같은 과정을 진행한다.




@Repository
public class BoardDao {
	
	@Autowired
	private SqlSessionTemplate sqlTemplate;
	
	public void insert(Board board) {
		sqlTemplate.getMapper(BoardMapper.class).insertBoard(board);
	}
}

최종적으로 DAO에서 sqlSessionTemplate을 사용하여 Mapping 한다.




2.CRUD

CRUD (Create, Read, Update, Delete)를 Spring을 이용하여 구현

<mapper namespace="kosta.mapper.BoardMapper">
	<cache />
		
	<insert id="insertBoard" parameterType="Board">
		insert into board(
			seq,title,writer,contents, regdate, hitcount
		)values(
			board_seq.nextval, #{title}, #{writer}, #{contents}, sysdate, 0 
		)
		
	</insert>
	
 	 <select id="listBoard" resultType="Board">
		select * from board
		order by seq desc
	</select>
	
	<select id="detailBoard" resultType="Board" parameterType="int">
		select * from board where seq=#{seq}
	</select> 
	
	<update id="updateBoard" parameterType="Board">
		update board set title=#{title}, contents=#{contents} where seq=#{seq}
	</update>
	
	<delete id="deleteBoard" parameterType="int">
		delete from board where seq=#{seq}
	</delete>   
</mapper>

Mapping할 CRUD의 쿼리문을 사용하기 위한 xml파일을 생성해 위와 같이 코딩
select를 제외한 모든 DML에는 parameterType을 선언



public interface BoardMapper {
	List<Board> listBoard();
	int insertBoard(Board board);
	Board detailBoard(int seq);
	int updateBoard(Board board);
	int deleteBoard(int seq);

}

CRUD에 해당되는 추상 메소드들을 Mapping



package kosta.model;

import java.io.Serializable;

import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;

import org.hibernate.validator.constraints.NotEmpty;

public class Board implements Serializable{

	private int seq;
	
	@NotEmpty(message = "반드시 입력하세요")
	@Size(min = 2, max = 5, message = "글자수 2~5까지")
	private String title;
	
	@Pattern(regexp = "[0-9a-zA-Z가-힣]*", message = "특수문자 금지")
	private String writer;
	
	private String contents;
	private String regdate;
	private int hitcount;
	
	public Board() {
		
	}

	public Board(int seq, String title, String writer, String contents, String regdate, int hitcount) {
		super();
		this.seq = seq;
		this.title = title;
		this.writer = writer;
		this.contents = contents;
		this.regdate = regdate;
		this.hitcount = hitcount;
	}

	public int getSeq() {
		return seq;
	}

	public void setSeq(int seq) {
		this.seq = seq;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getWriter() {
		return writer;
	}

	public void setWriter(String writer) {
		this.writer = writer;
	}

	public String getContents() {
		return contents;
	}

	public void setContents(String contents) {
		this.contents = contents;
	}

	public String getRegdate() {
		return regdate;
	}

	public void setRegdate(String regdate) {
		this.regdate = regdate;
	}

	public int getHitcount() {
		return hitcount;
	}

	public void setHitcount(int hitcount) {
		this.hitcount = hitcount;
	}

	@Override
	public String toString() {
		return "Board [seq=" + seq + ", title=" + title + ", writer=" + writer + ", contents=" + contents + ", regdate="
				+ regdate + ", hitcount=" + hitcount + "]";
	}
	
}

Serializable한 DTO 객체 생성



@Repository
public class BoardDao {
	
	@Autowired
	private SqlSessionTemplate sqlTemplate;
	
	public void insert(Board board) {
		sqlTemplate.getMapper(BoardMapper.class).insertBoard(board);
	}
	
	public List<Board> list() {
		return sqlTemplate.getMapper(BoardMapper.class).listBoard();
	}
	
	public Board detail(int seq) {
		return sqlTemplate.getMapper(BoardMapper.class).detailBoard(seq);
	}
	
	public void update(Board board) {
		sqlTemplate.getMapper(BoardMapper.class).updateBoard(board);
	}
	
	public void delete(int seq) {
		sqlTemplate.getMapper(BoardMapper.class).deleteBoard(seq);
	}
}

@Repository를 사용하여 빈 등록을 해 Container에 객체 생성
@Autowired를 통해 의존성 주입
sql 객체를 생성한 sqlTemplate으로 Mapping




@Controller
public class BoardController {
	@Autowired
	private BoardDao dao;

	//@RequestMapping(value = "/board_insert", method = RequestMethod.GET)
	@GetMapping("/board_insert")
	public String board_form(@ModelAttribute("boardCommand") Board board) {
		System.out.println("form 페이지 이동");
		return "insert_form";
	}
	
	//@RequestMapping(value = "/board_insert", method = RequestMethod.POST)
	@PostMapping("/board_insert")
	public String board_insert(@ModelAttribute("boardCommand") @Valid Board board, BindingResult errors) {
		
		if(errors.hasErrors()) {
			System.out.println("에러발생");
			return "insert_form";
		}
		
		dao.insert(board);
		
		return "redirect:board_list";
	}
	
	@RequestMapping("/board_list")
	public String board_list(Model model) {
		List<Board> list = dao.list();
		
		model.addAttribute("list",list);
		
		return "list";
	}
	
	/*
	 * @RequestMapping("/board_detail") public String
	 * board_detail(@RequestParam("seq") int seq, Model model) {
	 * model.addAttribute("board",dao.detail(seq));
	 * 
	 * return "detail"; }
	 */
	
	@RequestMapping("/board_detail{seq}")
	public String board_detail(@PathVariable int seq, Model model) {
		model.addAttribute("board",dao.detail(seq));
		
		return "detail";
	}
	
	@GetMapping("/board_update")
	public String update_form(@RequestParam("seq") int seq, Model model) {
		model.addAttribute("board", dao.detail(seq));
		
		return "updateForm";
	}
	
	@PostMapping("/board_update")
	public String board_update(Board board) {
		dao.update(board);
		
		return "redirect:board_list";
	}
	
	@RequestMapping("/board_delete")
	public String delete_board(@RequestParam("seq") int seq) {
		dao.delete(seq);
		
		return("redirect:board_list");
	}
	
}

클래스에 @Controller를 선언하여 Controller임을 알려주고 @RequestMapping을 통하여 URL Mapping
String을 이용하여 바로 view로 return
각 메소드별 data를 받는 파라미터에 따라 Mapping




3. @RequestParam

파라미터값을 가져올 수 있는 어노테이션이다. 가져오는 파라미터값을 명확하게 하기 위해 사용한다.

  • 1:1로 파라미터를 받는 경우에 사용한다.
  • name, value : 파라미터 이름
  • required : 해당 파라미터가 필요한지의 여부
  • defaultValue : 해당 파라미터의 기본 값
@GetMapping("/board_update")
	public String update_form(@RequestParam("seq") int seq, Model model) {
		model.addAttribute("board", dao.detail(seq));
		
		return "updateForm";
	}

seq라는 파라미터값을 가져와 seq 라는 변수를 선언



4. @ModelAttribute

파라미터값을 가져올 수 있는 어노테이션

  • @RequestParam 과의 차이점으로는 도메인, 오브젝트를 통하여 파라미터를 받는다.

  • Validation을 사용하여 에러 처리가 가능하다.

    @PostMapping("/board_insert")
    		public String board_insert(@ModelAttribute("boardCommand") @Valid Board board, BindingResult errors) {
    		
    			if(errors.hasErrors()) {
    				System.out.println("에러발생");
    				return "insert_form";
    			}
    		
    			dao.insert(board);
    		
    			return "redirect:board_list";
    		}
    
  • boardCommand 라는 commandName을 가진 form 태그의 정보들을 한 번에 가져오기 위해 사용



5. @PathVariable(RESTful)

URL 경로에 변수를 넣어주는 어노테이션

  • @RequestMapping의 URL 정의 부분과 메소드 내의 파라미터 부분에 정의하여 사용

  • null 혹은 공백값이 들어가는 파라미터라면 적용이 되지 않는다.

  • 해당 어노테이션과 동일한 이름(템플릿 변수)를 가지는 파라미터에 적용

    @RequestMapping("/board_detail{seq}")
    		public String board_detail(@PathVariable int seq, Model model) {
    			model.addAttribute("board",dao.detail(seq));
    		
    			return "detail";
    		}
    
  • URL 주소 옆에 해당 변수 값을 {} 내에 추가

  • @PathVariable을 통해 int seq를 선언한다.



6. tiles

tiles는 View의 기존 구조를 쉽게 적용하기 위한 템플릿 프레임워크이다.

  • 페이지 수정이 쉬워 유지보수가 용이
  • 일관적인 페이지 관리 가능

1. pom.xml에 라이브러리 추가

		<dependency>
		    <groupId>org.apache.tiles</groupId>
		    <artifactId>tiles-jsp</artifactId>
		    <version>3.0.7</version>
		</dependency>
		
		<dependency>
		    <groupId>org.apache.tiles</groupId>
		    <artifactId>tiles-core</artifactId>
		    <version>3.0.7</version>
		</dependency>
		
		<dependency>
		    <groupId>org.apache.tiles</groupId>
		    <artifactId>tiles-servlet</artifactId>
		    <version>3.0.7</version>
		</dependency>
  • 총 세가지의 라이브러리를 추가
  • 버전은 3.0.7로 통일

2. Dispatcher Servlet.xml에 View Resolver, xml 추가

<!-- Tiles Setting -->
	
	<bean id="viewResolver2"
		class="org.springframework.web.servlet.view.UrlBasedViewResolver">
		<property name="viewClass"
			value="org.springframework.web.servlet.view.tiles3.TilesView"/>
		<property name="order" value="1"/>	
	</bean>
	
	<bean id="tilesConfigurer" 
		class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
		<property name="definitions">
			<list>
				<value>/WEB-INF/tiles2def.xml</value>
			</list>
		</property>
	</bean>
  • 중요한 부분은 order 속성을 최우선 1번 지정하여 tiles에 해당되는 로직을 우선적으로 로드 시킨 다는 의미이다.
  • 이에 따라 다른 order 속성도 차후 번호를 선언하여 주어야 한다.

3. tile-def.xml 설정

<tiles-definitions>

	<definition name="base_layout" template="/view/module/template.jsp">
		<put-attribute name="header" value="/view/module/header.jsp"/>	
		<put-attribute name="logo" value="/view/module/logo.jsp"/>	
		<put-attribute name="footer" value="/view/module/footer.jsp"/>	
	</definition>

	<definition name="insert_form" extends="base_layout">
		<put-attribute name="body" value="/view/insert_form.jsp"/>
	</definition>
	
	<definition name="list" extends="base_layout">
		<put-attribute name="body" value="/view/list.jsp"/>
	</definition>
	
			
</tiles-definitions>
  • 위 설정 파일은 tiles의 layout을 적용하는 화면을 설정
  • base_layout이라는 name을 가진 템플릿은 value로 설정한 경로의 내용에 맞는 header와 footer를 가지고 있다.
  • 나머지 name을 가진 태그들은 base_layout을 상속받아 기본적으로 header, footer의 속성을 가지고 있을 수 있게 선언
  • name은 URL을 통해서 가는 View와 이름이 같아야 한다.

4. 기본 레이아웃을 JSP에 추가

  • template.jsp 에서 tiles 태그를 사용해 xml에서 정해준 name을 선언

5. 결과

profile
DB 엔지니어👍

0개의 댓글