[Spring3.0] MVC: Spring3.0 + MyBatis 게시판
by 무작정 개발반응형
이번에는 Spring MVC Project를 생성해서 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 등 역할별로 패키지를 생성해서 클래스를 넣음
(2) - css, js는 src -> main -> webapp -> resources에 저장
(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링크 참고
SpringJdbcTemplate 프로젝트 안에 2가지가 있고, CustomDAO는 JDBC / CustomDAO2는 스프링의 JDBC 방식이다.
반응형
'Back-End > Spring Legacy' 카테고리의 다른 글
[Spring3.0] Spring Web View, 파일 업로드, 파일 다운로드 (0) | 2022.03.29 |
---|---|
[Spring3.0] AOP (관점 지향 프로그래밍) (4) | 2022.03.28 |
[Spring 3.0] LomBok 으로 getter/setter 생성 (0) | 2022.03.28 |
[Spring 3.0] 스프링 3.0 + MyBatis 연동 (0) | 2022.03.27 |
[Spring 3.0] 스프링JDBC (0) | 2022.03.26 |
블로그의 정보
무작정 개발
무작정 개발