zipCheck.jsp에서비동기함수 $.post를 사용해서 ZipAction.java액션으로 갔다. Mybatis를 수행후 결과값이 List에 담겨있다. 그 값을 가지고 어디로 출력할 것인가? zipCheck.jsp에 다시 돌아온다. 비동기함수는 자신에게 돌아오는 함수이다.
그런데 ZipAction.java에서 dispatcher를 사용하면 다른 페이지로 이동한다.
따라서 JSON 방법을 사용해서 값을 가지고, 데이터를 기다리고 있는 jsp에 가야한다.
예전에는 json simple jar를 이용하여 JSON object, array를 만들었는데.. 이번엔 gson-2.8.5.jar를 maven repository에서 다운받아 사용한다.
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC"-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mappernamespace="org.addrMy.config.ObjectMapper"><sqlid="search"><where><iftest="word!=null and field=='name'"><!-- name like '%'||#{word}||'%' -->
name like '%${word}%'
</if><iftest="word!=null and field=='tel'">
tel like '%'||#{word}||'%'
</if></where></sql><!-- insert --><insertid="insertData"parameterType="org.addrMy.model.AddressVO">
insert into address(num, name, zipcode, addr, tel)
values(address_seq.nextval,#{name},#{zipcode},#{addr},#{tel})
</insert><!-- all select --><selectid="listData"resultType="org.addrMy.model.AddressVO">
select * from address
</select><!-- count --><selectid="countData"resultType="Integer">
select count(*) from address
</select><!-- view --><selectid="viewData"parameterType="Integer"resultType="org.addrMy.model.AddressVO">
select * from address where num=#{num}
</select><!-- update --><updateid="updateData"parameterType="org.addrMy.model.AddressVO">
update address set name=#{name}, zipcode=#{zipcode}, addr=#{addr}, tel=#{tel} where num=#{num}
</update><!-- delete --><deleteid="deleteData"parameterType="Integer">
delete from address where num=#{num}
</delete><!-- zipcode select --><selectid="zipData"parameterType="String"resultType="zipvo">
select * from zipcode where dong like '%'||#{dong}||'%'
</select><!-- search --><selectid="searchData"parameterType="java.util.Map"resultType="org.addrMy.model.AddressVO">
select * from address
<includerefid="search"></include></select><!-- countSearchData --><selectid="countSearchData"resultType="Integer"parameterType="java.util.Map">
select count(*) from address
<includerefid="search"></include></select></mapper>
<!-- 게시판 --><divclass="board"><br/><!-- 검색 시작--><divalign="right"id="searchDiv"><formname="search"id="search"><selectname="field"id="field"><optionvalue="userid">작성자</option><optionvalue="subject">제목</option></select><inputtype="text"name="word"id="word"><inputtype="button"value="찾기"id="btnSearch"class="btn btn-outline-secondary btn-sm"><ahref="#coll"id="writeBtn"class="btn btn-outline-dark btn-sm"data-toggle="collapse">글쓰기</a></form></div><!-- 검색 끝--><!-- 수강후기 게시판 --><divid="result"align="center"></div><!-- 글쓰기 폼 영역 --><divid="coll"class="collapse"><formaction="/Tutoring/board/boardinsert"method="post"id="wFrm"><br/><br/><!-- 수강후기 등록하고자 하는 강의 번호 --><inputtype="hidden"id="classnum"name="classnum"value="${dto.classnum}"><divclass="input-group mb-3"><divclass="input-group-prepend"><spanclass="input-group-text">강의명</span></div><inputtype="text"class="form-control"id="classname"name="classname"readonly="readonly"value="${dto.classname}"><divclass="input-group-prepend"><spanclass="input-group-text">작성자</span></div><inputtype="text"class="form-control"id="userid"name="userid"readonly="readonly"value="${sessionScope.userid}"></div><br/><divclass="input-group mb-3"><divclass="input-group-prepend"><spanclass="input-group-text">제목</span></div><inputtype="text"class="form-control"id="subject"name="subject"></div><br/><divclass="input-group mb-3"><divclass="input-group-prepend"><spanclass="input-group-text">내용</span></div><textarearows="5"cols="20"class="form-control"id="content"name="content"></textarea></div><divclass="button"><inputtype="reset"class="btn btn-gray"value="취소"><inputtype="button"class="btn btn-primary"id="send"value="후기등록"></div></form></div><!-- 글쓰기 폼 영역 끝--></div><!-- 게시판 끝-->
수강후기 게시판 영역은 div태그만 있고 내용이 없다. 테이블 태그는 보이지 않는다. 어떻게 구현할까?
페이지가 로드되자 마자 수강후기 리스트를 불러오도록 자바스크립트 함수를 기입한다.
<script>
$(document).ready(function(){
getData(1, "", "", ${dto.classnum}); //페이지 로드 시 수강후기 리스트 보기
이때 SQL문이 헷갈려서 고생을 했다.. (좀 막혔던 부분들을 생각해보면 다 전체목록 보기에 관한 기능 구현에 관해서다..)
지금까지 전체 목록을 볼때는 검색한 결과인지 아닌지만 가르면 됐는데, 지금의 수강후기 게시판은 "특정 강의에 대한" 수강후기라는 단서가 붙는다.
그래서 처음엔 바깥에 select를 한번 더 감싸고 where classnum=강의번호; 라고 조건절을 줬고 그 select문 안에서 rn을 미리 부여해놓고 5에서 10사이, 10에서 15사이 이런식으로 골라냈었다. 당연히 1페이지에는 2개, 2페이지에는 5개 이렇게 오류가 날 수 밖에 없었다. (사실 오류가 아니고 당연한 결과다.)
하지만 강의 페이지별로 수강후기 DB가 따로 있는게 아니고 전체 수강후기 DB에서 강의번호 별로 골라낸다.
따라서 바깥 select를 지우고, rownum where 절이 아닌 select * from wboard 뒤에 where classnum이라는 조건절을 추가해야한다. 즉 미리 classnum을 골라내고 rn을 계산해야하는 것이다.
<WBoard.java의 boardList 메소드>(검색일때)
//검색 전체보기public ArrayList<WBoardDTO> boardList(String field, String word, int startRow, int endRow, int classnum){
Connection con=null;
PreparedStatement ps=null;
ResultSet rs=null;
ArrayList<WBoardDTO>arr=new ArrayList<WBoardDTO>();
try {
con=getConnection();
StringBuilder sb=new StringBuilder();
sb.append(" select * from");
sb.append(" (select aa.*, rownum rn from");
sb.append(" (select * from WBoard where classnum="+classnum);
sb.append(" and upper ("+field+") like upper ('%"+word+"%')");
sb.append(" order by num desc) aa");
sb.append(" where rownum<=?) where rn>=?");
ps=con.prepareStatement(sb.toString());
ps.setInt(1, endRow);
ps.setInt(2, startRow);
rs=ps.executeQuery();
while(rs.next()) {
WBoardDTO dto=new WBoardDTO();
dto.setNum(rs.getInt("num"));
dto.setContent(rs.getString("content"));
dto.setReadcount(rs.getInt("readcount"));
dto.setReg_date(rs.getString("reg_date"));
dto.setSubject(rs.getString("subject"));
dto.setUserid(rs.getString("userid"));
dto.setClassnum(rs.getInt("classnum"));
arr.add(dto);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
closeConnection(con, ps, rs);
}
return arr;
}
<WBoard.java의 getCount 메소드>
//게시물수 출력publicintgetCount(String field, String word, int classnum){
Connection con=null;
Statement st=null;
ResultSet rs=null;
int count=0;
String sql="";
try {
con=getConnection();
st=con.createStatement();
if(word.equals("")) {
sql="select count(*) from WBoard where classnum="+classnum;
}else {
sql="select count(*) from WBoard where upper ("+field+") like upper ('%"+word+"%') and classnum="+classnum;
}
rs=st.executeQuery(sql);
if(rs.next()) {
count=rs.getInt(1);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
closeConnection(con, st, rs);
}
return count;
}
listResult.jsp
WBoardListAction.java에서 내보내진 값을 board란 이름에 담아서 뿌린다. 페이징 영역도 포함하고 있다.
그런데 courseDetail.jsp->WBoardListAction.java->listResult.jsp로 이동된 것이므로 $.get의 콜백함수에 의해 이 값들이 courseDetail.jap의 result div에 뿌려지게 된다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<body><h5style="text-align: left"><spanid="cntSpan">수강후기(${count}</span>)</h5><tableclass="table table-hover table-bordered table-sm"><thead><tr><thstyle="width: 8%">글번호</th><thstyle="width: 13%">작성자</th><th>제목</th><thstyle="width: 8%">작성일</th><thstyle="width: 7%">조회수</th></tr></thead><tbody><c:forEachitems="${board}"var="board"varStatus="st"><tr><td>${rowNo-st.index}</td><td>${board.userid}</td><td><ahref="/Tutoring/board/boardDetail?num=${board.num}">${board.subject}</a></td><td>${board.reg_date}</td><td>${board.readcount}</td></tr></c:forEach></tbody></table><divalign="center"><c:iftest="${pu.startPage>pu.pageBlock}"><!-- 이전 --><ahref="javascript:getData(${pu.startPage-pu.pageBlock},'${pu.field}','${pu.word}', ${pu.classnum})">[이전]</a></c:if><c:forEachbegin="${pu.startPage}"end="${pu.endPage}"var="i"><!-- 페이지 출력 --><c:iftest="${i==pu.currentPage}"><!-- 현재 페이지 --><c:outvalue="${i}"/></c:if><c:iftest="${i!=pu.currentPage}"><!-- 현재 페이지 아닌 경우 링크 부여--><ahref="javascript:getData(${i},'${pu.field}','${pu.word}', ${pu.classnum})">${i}</a></c:if></c:forEach><c:iftest="${pu.endPage<pu.totPage}"><!-- 다음--><ahref="javascript:getData(${pu.endPage+1},'${pu.field}','${pu.word}', ${pu.classnum})">[다음]</a></c:if></div></body></html>
다음은 수강후기 글쓰기에 대한 내용이다.
지금까지는 로그인 없이 볼 수 있는 내용들이었지만 수강후기를 쓰려고 하면 로그인을 해야한다.
글쓰기 버튼을 누르면 숨어있던 글쓰기 폼이 나타난다. 부트스트랩의 collapse 클래스를 이용했다.
courseDetail.jsp 내에 글쓰기 폼이 있으므로 후기등록 버튼을 눌렀을때 실행되는 자바스크립트 함수도 이곳에 적어준다.
courseDetail.jsp 내의 글쓰기 폼 영역
//후기등록 버튼 클릭
$("#send").click(function(){ //후기등록 버튼 클릭if(${sessionScope.userid==null}){
alert("로그인 필요");
location.href="/Tutoring/member/login";
}else{
var classnum=$("#classnum").val();
var userid=$("#userid").val();
var content=$("#content").val();
var subject=$("#subject").val();
var postString="classnum="+classnum+"&userid="+userid+"&content="+content+"&subject="+subject;
$.ajax({
type: "post",
url : "/Tutoring/board/boardinsert",
data: postString,
success:function(d){
alert("후기가 등록되었습니다!");
$("#result").html(d);
document.getElementById("wFrm").reset();
},
beforeSend: showRequest, //빈칸 확인error: function(e){
alert("error:"+e);
}
})//ajax
}
})//send
}); //document ready