무작정 개발.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/
html
<!-- 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링크 참조
html
<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을 사용해도 된다.
java
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클래스 생성 및 작성

java
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을 등록해줘야 한다.
html
<?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 등록하기

html
<?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 클래스 생성 및 작성

java
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 방식이다.

블로그의 프로필 사진

블로그의 정보

무작정 개발

무작정 개발

활동하기