무작정 개발.Vlog

[Spring3.0] MVC: Spring3.0 + MyBatis 게시판

by 무작정 개발
반응형

이번에는 Spring MVC Project를 생성해서 MyBatis를 활용한 게시판에 대해 정리할 것이다.

 

Spring3.0 + MyBatis 게시판
Spring3.0 + MyBatis 게시판

기존에 만들었던 게시판과 크게 다른 점은 없다. 이전처럼 게시글 등록, 게시글 조회, 게시글 리스트 조회, 게시글 삭제,

페이징 처리 기능이 있다.

url : http://localhost:8080/springwebmybatis/list.action

MVC : Spring3.0 + MyBatis 게시판 만들기

1. 프로젝트 생성

 

File -> New -> Spring Legacy Project ->프로젝트 이름 : SpringWebMybatis

Project Settings : com.jdbc.springweb

 

이전에 만들었던 SpringWeb 프로젝트 또한 Spring MVC로 생성했기 때문에 복사해서 이름만 변경해서 만들어도 된다. 

 

2. 프로젝트 전체 구조

 

(1) - dao, dto, util 등 역할별로 패키지를 생성해서 클래스를 넣음

(1) - dao,dto,util 등 역할별로 패키지를 생성해서 클래스를 넣음

 

(2) - css, js는 src -> main -> webapp -> resources에 저장

(2) - css, js는 src -> main -> webapp -> resources에 저장
(2) - css, js는 src -> main -> webapp -> resources에 저장

 

(3) - jsp 파일은 src -> main -> webapp -> WEB-INF -> views에 저장

(3) - jsp 파일은 src -> main -> webapp -> WEB-INF -> views에 저장
(3) - jsp 파일은 src -> main -> webapp -> WEB-INF -> views에 저장

 

 

3. Maven으로 필요한 lib(라이브러리) 설치

  • 이전과 같게 pom.xml에 작성해서 필요한 lib를 설치해 준다. (Maven을 사용하면 자동으로 lib 설치)
  • https://mvnrepository.com/
		<!-- commons-dbcp -->
		<dependency>
    		<groupId>commons-dbcp</groupId>
    		<artifactId>commons-dbcp</artifactId>
    		<version>1.4</version>
		</dependency>
		
		<!-- commons-pool -->
		<dependency>
    		<groupId>commons-pool</groupId>
    		<artifactId>commons-pool</artifactId>
    		<version>1.6</version>
		</dependency>
		
		<!-- ojdbc -->
		<dependency>
   		 	<groupId>com.oracle.database.jdbc</groupId>
    		<artifactId>ojdbc6</artifactId>
    		<version>11.2.0.4</version>
		</dependency>
		
		<!-- MyBatis -->
		<dependency>
    		<groupId>org.mybatis</groupId>
    		<artifactId>mybatis</artifactId>
    		<version>3.5.9</version>
		</dependency>
		
		<!-- MyBatis-Spring -->
		<dependency>
    		<groupId>org.mybatis</groupId>
    		<artifactId>mybatis-spring</artifactId>
    		<version>1.3.3</version>
		</dependency>

 

4. servlet-context.xml

  • 전체 소스코드는 맨 하단 GitHub링크 참조
<context:component-scan base-package="com.jdbc.springweb" />
	
	<beans:bean id="boardDAO2" class="com.jdbc.dao.BoardDAO2">
		<beans:property name="sessionTemplate" ref="sessionTemplate"/>
	</beans:bean>
	
	<beans:bean id="sessionTemplate"
		class="org.mybatis.spring.SqlSessionTemplate">
		<beans:constructor-arg ref="sessionFactory"/>
		
	</beans:bean>
	
	<beans:bean id="sessionFactory"
		class="org.mybatis.spring.SqlSessionFactoryBean">
		<beans:property name="dataSource" ref="dataSource"/>
		<beans:property name="configLocation"
		value="classpath:/mybatis-config.xml"/>
	</beans:bean>
	
	
	<beans:bean id="dataSource"
	class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
		<beans:property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
		<beans:property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
		<beans:property name="username" value="suzi"/>
		<beans:property name="password" value="a123"/>
	</beans:bean>
	
	<beans:bean id="myUtil" class="com.jdbc.util.MyUtil"/>

 

5. BoardDTO클래스 생성 및 작성

  • 이전에 정리한 LomBok을 사용해도 된다.
package com.jdbc.dto;

public class BoardDTO {
	
	private int num;
	private String name;
	private String pwd;
	private String email;
	private String subject;
	private String content;
	private String ipAddr;
	private String created;
	private int hitCount;
    
    //getter/setter 생성

 

6. BoardDAO2클래스 생성 및 작성

package com.jdbc.dao;

import java.util.HashMap;
import java.util.List;


import org.mybatis.spring.SqlSessionTemplate;

import com.jdbc.dto.BoardDTO;


public class BoardDAO2 {
	
	private SqlSessionTemplate sessionTemplate;

	public void setSessionTemplate(SqlSessionTemplate sessionTemplate) {
		this.sessionTemplate = sessionTemplate;
		
	}


	// num의 최대값 구하기
	public int getMaxNum() {

		int maxNum = 0;
		
		maxNum = sessionTemplate.selectOne("com.boardMapper.maxNum");
		
		return maxNum;

	}

	// 입력(insert) - 넘어오는 데이터는 BoardDTO의 dto
	public void insertData(BoardDTO dto) {

		sessionTemplate.insert("com.boardMapper.insertData",dto);
		
	}

	// 전체 데이터 갯수 구하기
	public int getDataCount(String searchKey, String searchValue) {
		
		HashMap<String, Object> params = new HashMap<String, Object>();
		params.put("searchKey", searchKey);
		params.put("searchValue", searchValue);
		
		int totalCount = sessionTemplate.selectOne("com.boardMapper.getDataCount",params);
		
		return totalCount;
	}

	// 전체 데이터 출력(페이지마다 개수 제한)
	public List<BoardDTO> getLists(int start, int end,String searchKey, String searchValue) {
	//rownum을 매개변수로 할당해서 해당범위만 list로 출력
		
		HashMap<String, Object> params = new HashMap<String, Object>();
		params.put("start", start);
		params.put("end", end);
		params.put("searchKey", searchKey);
		params.put("searchValue", searchValue);
		
		List<BoardDTO> lists = 
				sessionTemplate.selectList("com.boardMapper.getLists",params);
		
		return lists;
		
	}
	

	// num으로 조회한 한개의 데이터
	public BoardDTO getReadData(int num) {

		BoardDTO dto = 
				sessionTemplate.selectOne("com.boardMapper.getReadData",num);
		
		return dto;
	}

	// 조회수 증가
	public void updateHitCount(int num) {

		sessionTemplate.update("com.boardMapper.updateHitCount",num);

	}
	
	
	//수정
	public void updateData(BoardDTO dto) {
		
		sessionTemplate.update("com.boardMapper.updateData",dto);
	}
	
	//삭제
	public void deleteData(int num) {
		
		sessionTemplate.delete("com.boardMapper.deleteData",num);
		
	}

}

 

7. boardMapper.xml 생성 및 작성

  • sql 쿼리가 들어있는 xml파일이다.
  • mybatis-config.xml에 이 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="com.boardMapper">

<select id="maxNum" resultType="int">
	select nvl(max(num),0) from board
</select>

<insert id="insertData" parameterType="com.jdbc.dto.BoardDTO">
	insert into board (num,name,pwd,email,subject,content,ipAddr,
	hitCount,created) values (#{num},#{name},#{pwd},#{email},#{subject},
	#{content},#{ipAddr},0,sysdate)
</insert>

<select id="getDataCount" parameterType="hashMap" resultType="int">
	select nvl(count(*),0) from board
	where ${searchKey} like '%' || #{searchValue} || '%'
</select>

<select id="getLists" parameterType="map" resultType="com.jdbc.dto.BoardDTO">
	select * from (
	select rownum rnum, data.* from (
	select num,name,subject,hitCount,
	to_char(created,'YYYY-MM-DD') created
	from board where ${searchKey} like '%' || #{searchValue} || '%'
	order by num desc) data)
<![CDATA[
	where rnum>=#{start} and rnum<=#{end}
]]>
</select>

<update id="updateHitCount" parameterType="int">
	update board set hitCount=hitCount+1 where num=#{num}
</update>

<select id="getReadData" parameterType="int" resultType="com.jdbc.dto.BoardDTO">
	select num,name,pwd,email,subject,content,IpAddr,
	hitCount,created from board where num=#{num}
</select>

<update id="updateData" parameterType="com.jdbc.dto.BoardDTO">
	update board set name=#{name},pwd=#{pwd},email=#{email},
	subject=#{subject},content=#{content} where num=#{num}
</update>

<delete id="deleteData" parameterType="int">
	delete board where num=#{num}
</delete>

</mapper>

 

8. mybatis-config.xml에 boardMapper.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>
	<mappers>
		<mapper resource="com/jdbc/mybatis/boardMapper.xml"/>
	</mappers>
</configuration>

 

9. BoardController 클래스 생성 및 작성

package com.jdbc.springweb;

import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

//import com.jdbc.dao.BoardDAO;
import com.jdbc.dao.BoardDAO2;
import com.jdbc.dto.BoardDTO;
import com.jdbc.util.MyUtil;

@Controller
public class BoardController {

	@Autowired
	@Qualifier("boardDAO2")//명시적으로 boardDAO가지고 와 할때 쓴다
	BoardDAO2 dao;//의존성 주입

	@Autowired
	MyUtil myUtil;//의존성 주입으로 가져오게 된다 

	@RequestMapping(value = "/",method = RequestMethod.GET)
	public String home() {

		return "index";
	}

	/*
	@RequestMapping(value = "/created.action",
			method = {RequestMethod.GET,RequestMethod.POST})
	public String created(HttpServletRequest request,
			HttpServletResponse response) throws Exception{

		return "bbs/created";

	}
	 */

	@RequestMapping(value = "/created.action")
	public ModelAndView created() {

		ModelAndView mav = new ModelAndView();
		mav.setViewName("bbs/created");

		return mav;
	}

	@RequestMapping(value = "/created_ok.action",
			method = {RequestMethod.GET,RequestMethod.POST})
	public String created_ok(BoardDTO dto,HttpServletRequest request,
			HttpServletResponse response) throws Exception{

		int maxNum = dao.getMaxNum();

		dto.setNum(maxNum + 1);
		dto.setIpAddr(request.getRemoteAddr());

		dao.insertData(dto);

		return "redirect:/list.action";

	}

	/*
	@RequestMapping(value = "/list.action",
			method = {RequestMethod.GET,RequestMethod.POST})
	public String list(HttpServletRequest request,
			HttpServletResponse response) throws Exception{
	 */	

	@RequestMapping(value = "/list.action",
			method = {RequestMethod.GET,RequestMethod.POST})
	public ModelAndView list(HttpServletRequest request,
			HttpServletResponse response) throws Exception{

		String cp = request.getContextPath();

		String pageNum = request.getParameter("pageNum");

		int currentPage = 1;

		if(pageNum!=null)
			currentPage = Integer.parseInt(pageNum);

		String searchKey = request.getParameter("searchKey");
		String searchValue = request.getParameter("searchValue");

		if(searchValue==null) {//searchValue가 null이얌 ??
			//||searchValue.equals("") 원래 이렇게 두번씩 쓴다 무슨 오류가 있을 수 도 있기 때문에

			searchKey = "subject";
			searchValue = "";

		}else {

			if(request.getMethod().equalsIgnoreCase("GET")) {
				searchValue = URLDecoder.decode(searchValue, "UTF-8");
			}
		}

		int dataCount = dao.getDataCount(searchKey, searchValue);

		int numPerPage = 5;
		int totalPage = myUtil.getPageCount(numPerPage, dataCount);

		if(currentPage>totalPage)
			currentPage = totalPage;

		int start = (currentPage-1)*numPerPage+1;
		int end = currentPage*numPerPage;

		List<BoardDTO> lists =
				dao.getLists(start, end, searchKey, searchValue);

		String param = "";
		if(searchValue!=null&&!searchValue.equals("")) {//서치벨류가 null이면
			param = "searchKey=" + searchKey;
			param+= "&searchValue=" + URLEncoder.encode(searchValue, "UTF-8");
		}

		String listUrl = cp + "/list.action";

		if(!param.equals("")) {
			listUrl += "?" + param;
		}

		String pageIndexList = 
				myUtil.pageIndexList(currentPage, totalPage, listUrl);

		//글보기 주소

		String articleUrl = cp + "/article.action?pageNum=" + currentPage;

		if(!param.equals("")) {
			articleUrl += "&" + param;
		}

		/*
		//포워딩 페이지에 데이터 넘기기
		request.setAttribute("lists", lists);
		request.setAttribute("articleUrl", articleUrl);
		request.setAttribute("pageIndexList", pageIndexList);
		request.setAttribute("dataCount", dataCount);		

		return "bbs/list";
		 */

		ModelAndView mav = new ModelAndView();

		mav.addObject("lists", lists);
		mav.addObject("articleUrl", articleUrl);
		mav.addObject("pageIndexList", pageIndexList);
		mav.addObject("dataCount", dataCount);

		mav.setViewName("bbs/list");

		return mav;


	}

	//아티클
	/*
	@RequestMapping(value = "/article.action",
			method = {RequestMethod.GET,RequestMethod.POST})
	public String article(HttpServletRequest request,
			HttpServletResponse response) throws Exception{
	 */

	@RequestMapping(value = "/article.action",
			method = {RequestMethod.GET,RequestMethod.POST})
	public ModelAndView article(HttpServletRequest request,
			HttpServletResponse response) throws Exception{

		String cp = request.getContextPath();
		String url;

		int num = Integer.parseInt(request.getParameter("num"));
		String pageNum = request.getParameter("pageNum");

		String searchKey = request.getParameter("searchKey");
		String searchValue = request.getParameter("searchValue");

		if(searchValue!=null) {
			searchValue = URLDecoder.decode(searchValue, "UTF-8");

		}

		dao.updateHitCount(num);

		//전체데이터 읽어오기
		BoardDTO dto = dao.getReadData(num);

		if(dto==null) {
			url = cp + "/list.action";
			response.sendRedirect(url);

		}

		int lineSu = dto.getContent().split("\n").length;

		dto.setContent(dto.getContent().replaceAll("\n", "<br/>"));

		String param = "pageNum=" + pageNum;
		if(searchValue!=null&&!searchValue.equals("")) {

			param += "&searchKey=" + searchKey;
			param += "&searchValue=" +
					URLEncoder.encode(searchValue, "UTF-8");

		}

		/*
		//4개의 데이터를 뿌려준다 
		request.setAttribute("dto", dto);
		request.setAttribute("params", param);
		request.setAttribute("lineSu", lineSu);
		request.setAttribute("pageNum", pageNum);

		return "bbs/article";
		 */

		ModelAndView mav = new ModelAndView();

		mav.addObject("dto", dto);
		mav.addObject("params", param);
		mav.addObject("lineSu", lineSu);
		mav.addObject("pageNum", pageNum);

		mav.setViewName("bbs/article");

		return mav;



	}//end 아티클

	//수정
	@RequestMapping(value = "/updated.action",
			method = {RequestMethod.GET,RequestMethod.POST})
	public String updated(HttpServletRequest request,
			HttpServletResponse response) throws Exception{
	 
		String cp = request.getContextPath();
		String url;

		int num = Integer.parseInt(request.getParameter("num"));
		String pageNum = request.getParameter("pageNum");

		String searchKey = request.getParameter("searchKey");
		String searchValue = request.getParameter("searchValue");

		if(searchValue!=null) {
			searchValue = 
					URLDecoder.decode(searchValue, "UTF-8");
		}

		BoardDTO dto = dao.getReadData(num);

		if(dto==null) {
			url = cp + "/list.action";
			response.sendRedirect(url);
		}

		String param = "pageNum=" + pageNum;

		if(searchValue!=null&&!searchValue.equals("")) {
			param+= "&searchKey=" + searchKey;
			param+= "&searchValue=" +
					URLEncoder.encode(searchValue, "UTF-8");

		}
		
		
		request.setAttribute("dto", dto);
		request.setAttribute("pageNum", pageNum);
		request.setAttribute("params", param);//이미 param에는 다른 변수값이 들어 있어서 변수명을 다른걸로 바꿔야한다 
		request.setAttribute("searchKey", searchKey);
		request.setAttribute("searchValue", searchValue);

		return "bbs/updated";
		
	}

	@RequestMapping(value = "/updated_ok.action",
			method = {RequestMethod.GET,RequestMethod.POST})
	public String updated_ok(BoardDTO dto,HttpServletRequest request,
			HttpServletResponse response) throws Exception{


		//String cp = request.getContextPath();
		//String url;

		String pageNum = request.getParameter("pageNum");
		String searchKey = request.getParameter("searchKey");
		String searchValue = request.getParameter("searchValue");

		dao.updateData(dto);

		String param = "pageNum=" + pageNum;

		if(searchValue!=null&&!searchValue.equals("")) {

			param += "&searchKey=" + searchKey;
			param += "&searchValue=" + 
					URLEncoder.encode(searchValue, "UTF-8");

		}

		return "redirect:/list.action?" + param;

	}

	@RequestMapping(value = "/deleted_ok.action",
			method = {RequestMethod.GET,RequestMethod.POST})
	public String deleted_ok(HttpServletRequest request,
			HttpServletResponse response) throws Exception{

		int num = Integer.parseInt(request.getParameter("num"));
		String pageNum = request.getParameter("pageNum");

		String searchKey = request.getParameter("searchKey");
		String searchValue = request.getParameter("searchValue");

		dao.deleteData(num);

		String param = "pageNum=" + pageNum;

		if(searchValue!=null&&!searchValue.equals("")) {

			param += "&searchKey=" + searchKey;
			param += "&searchValue=" + 
					URLEncoder.encode(searchValue, "UTF-8");

		}

		return "redirect:/list.action?pageNum=" + pageNum;
	}


}

 

10. JSP 파일 생성 및 작성

  • JSP파일은 이전에 사용한 JSP파일을 그대로 가져올 것이다.
  • 경로 수정
<link rel="stylesheet" type="text/css" href="/springwebmybatis/resources/css/style.css"/>

끝!

이번 게시판 관련 소스는 GitHub링크 참고 / 프로젝트 이름 : SpringWebMybatis


MyBatis를 하기 전에 JDBC, 스프링 JDBC를 연동하여 게시판을 만들었지만 기존에 학습했기에 생략하였다.

이 코드들은 하단 GitHub링크 참고

https://github.com/chaehyuenwoo/Spring3.0/tree/main/SpringJdbcTemplate/src/main/java/com/exe/springJdbcTemplate

 

GitHub - chaehyuenwoo/Spring3.0: Spring Framework 3.0버전_STS 3 IDE 사용

Spring Framework 3.0버전_STS 3 IDE 사용. Contribute to chaehyuenwoo/Spring3.0 development by creating an account on GitHub.

github.com

SpringJdbcTemplate 프로젝트 안에 2가지가 있고, CustomDAO는 JDBC / CustomDAO2는 스프링의 JDBC 방식이다.

반응형

블로그의 정보

무작정 개발

무작정 개발

활동하기