728x90
페이징 처리를 할 때 화면 하단에 나타나는 페이지 번호들의 나열이 모여 하나의 섹션이 된다.
여기서 첫 번째 섹션은 첫 번째 페이지부터 열 번째 페이지 까지로 볼 수 있다. 두 번째 섹션은 열한 번째 부터 스무 번째 페이지까지를 뜻한다.
그래서 페이지 2를 클릭하면 브라우저는 서버에 section 값으로 1을, pageNum 값으로 2를 전송하게 된다. 그리고 글 목록에는 두 번째 페이지에 해당하는 글인 예를들어 11번부터 20번 까지의 글을 테이블에서 조회한 후 표시하게 된다.
페이징을 위한 쿼리는 위와 같은 형태를 취한다. 이 게시판은 계층형 게시판이기 때문에 계층형 구조를 조회하는 select문이 서브쿼리로 들어가게 된다.
jsp 페이지에서는 전체 하나의 세션에 나타낼 데이터 갯수를 100개로 설정했기 때문에(10*10) 100개를 넘는 경우, 100개인 경우, 100개를 넘지 않는 경우로 나누어 페이지 번호를 표시하도록 구현한다.
전체 글 수가 100개를 넘지 않으면 전체 글 수를 10으로 나눈 몫에 1을 더한 값이 페이지 번호로 표시된다. (13개면 2페이지가 나오는 방식)
100개일 경우 정확히 10 페이지가 표시되고, 100개를 넘을 경우에는 다음 section으로 이동할 수 있도록 페이지 번호 옆에 next를 표시
controller
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
|
@WebServlet("/board/*")
public class BoardController extends HttpServlet {
private static String ARTICLE_IMG_REPO = "C:\\pra_board\\article_img";//이미지 저장 위치
BoardService boardService;
ArticleVO articleVO;
@Override
public void init(ServletConfig config) throws ServletException {
//서블릿 초기화 시 BoardService 객체 생성
boardService = new BoardService();
articleVO = new ArticleVO();
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doHandle(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doHandle(request, response);
}
private void doHandle(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String nextPage ="";
request.setCharacterEncoding("utf-8");
response.setContentType("text/html; charset=utf-8");
HttpSession session;//답글에 대한 부모 글 번호를 저장하기 위해 세션을 사용
String action = request.getPathInfo();//요청명을 가져옴
try {
List<ArticleVO> articleList = new ArrayList<ArticleVO>();
if(action == null) {
//최초 요청 시 또는 /listArticle.do로 요청 시 section 값과 pageNum 값을 구함
String _section = request.getParameter("section");
String _pageNum = request.getParameter("pageNum");
//최초 요청 시 section 값과 pageNum 값이 없으면 각각 1로 초기화
int section = Integer.parseInt(((_section == null) ? "1" : _section));
int pageNum = Integer.parseInt(((_pageNum == null) ? "1" : _pageNum));
//section 값과 pageNum 값을 HashMap에 저장한 후 메서드로 넘김
Map<String, Integer> pagingMap = new HashMap<String, Integer>();
pagingMap.put("section", section);
pagingMap.put("pageNum", pageNum);
//section 값과 pageNum 값으로 해당 섹션과 페이지에 해당되는 글 목록을 조회
Map articlesMap = boardService.listArticles(pagingMap);
//브라우저에서 전송된 section과 pageNum 값을 articlesMap에 저장
articlesMap.put("section", section);
articlesMap.put("pageNum", pageNum);
//조회된 글 목록을 articlesMap으로 바인딩하여 listArticles.jsp로 넘김
request.setAttribute("articlesMap", articlesMap);
nextPage = "/board01/listArticles.jsp";
}
//액션 값이 아래와 같으면 전체 글을 조회
else if(action.equals("/listArticles.do")) {
//글 목록에서 명시적으로 페이지 번호를 눌러서 요청한 경우 section 값과 pageNum 값을 가져옴
String _section = request.getParameter("section");
String _pageNum = request.getParameter("pageNum");
int section = Integer.parseInt(((_section == null) ? "1" : _section));
int pageNum = Integer.parseInt(((_pageNum == null) ? "1" : _pageNum));
Map<String, Integer> pagingMap = new HashMap<String, Integer>();
pagingMap.put("section", section);
pagingMap.put("pageNum", pageNum);
Map articlesMap = boardService.listArticles(pagingMap);
articlesMap.put("section", section);
articlesMap.put("pageNum", pageNum);
request.setAttribute("articlesMap", articlesMap);
nextPage = "/board01/listArticles.jsp";
}
//액션 값이 아래와 같으면 글쓰기 페이지로 이동
else if(action.equals("/articleForm.do")) {
nextPage = "/board01/articleForm.jsp";
}
//액션 값이 아래와 같으면 새 글 추가 작업 실행
else if(action.equals("/addArticle.do")) {
int articleno = 0;
//파일 업로드 기능을 사용하기 위해서 upload()로 요청을 전달
Map<String, String> articleMap = upload(request,response);
//articleMap에 저장한 글 정보를 다시 가져옴
String title = articleMap.get("title");
String content = articleMap.get("content");
String imagefilename = articleMap.get("imagefilename");
System.out.println(title+","+content+","+imagefilename);
//글쓰기 창에서 입력된 정보를 VO 객체에 설정한 후 addArticle()로 전달
articleVO.setParentno(0);//새 글의 부모 글 번호를 0으로 설정
articleVO.setId("hong");//새 글 작성자 ID를 hong으로 설정
articleVO.setTitle(title);
articleVO.setContent(content);
articleVO.setImagefilename(imagefilename);
articleno = boardService.addArticle(articleVO);//테이블에 새 글을 추가한 후 새 글에 대한 글 번호 가져옴
//파일을 첨부한 경우에만 수행
if(imagefilename != null && imagefilename.length() != 0) {
//temp 폴더에 임시로 업로드 될 파일 객체를 생성
File srcFile = new File(ARTICLE_IMG_REPO+"\\"+"temp"+"\\"+imagefilename);
System.out.println("srcFile = "+srcFile);
//CURR_IMAGE_REPO_PATH의 경로 하위에 글 번호로 폴더를 생성
File destDir = new File(ARTICLE_IMG_REPO+"\\"+articleno);
System.out.println("destDir = "+destDir);
destDir.mkdirs();
//temp 폴더의 파일을 글 번호를 이름으로 하는 폴더로 이동
FileUtils.moveFileToDirectory(srcFile, destDir, true);
}
//새 글 등록 메시지를 나타낸 후 자바스크립트 location 객체의 href 속성을 이용해 글 목록을 요청
PrintWriter writer = response.getWriter();
writer.print("<script>" + " alert('새 글을 추가했습니다.');"
+ " location.href='"
+ request.getContextPath()
+ "/board/listArticles.do';"+"</script>");
return;
}
else if(action.equals("/viewArticle.do")) {
String articleno = request.getParameter("articleno");//글 상세창을 요청할 경우 articleno 값을 가져옴
//articleno에 대한 글 정보를 조회하고 article 속성으로 바인딩
articleVO = boardService.viewArticle(Integer.parseInt(articleno));
request.setAttribute("article", articleVO);
nextPage = "/board01/viewArticle.jsp";
}
else if(action.equals("/modArticle.do")) {
Map<String,String> articleMap = upload(request,response);
int articleno = Integer.parseInt(articleMap.get("articleno"));
articleVO.setArticleno(articleno);
System.out.println("articleno = "+articleno);
String title = articleMap.get("title");
String content = articleMap.get("content");
String imagefilename = articleMap.get("imagefilename");
articleVO.setParentno(0);
articleVO.setId("hong");
articleVO.setTitle(title);
articleVO.setContent(content);
articleVO.setImagefilename(imagefilename);
boardService.modArticle(articleVO);//전송된 글 정보를 이용해 글을 수정
if(imagefilename != null && imagefilename.length() != 0) {
String originalFileName = articleMap.get("originalFileName");
//수정된 이미지 파일을 폴더로 이동
File srcFile = new File(ARTICLE_IMG_REPO+"\\"+"temp"+"\\"+imagefilename);
File destDir = new File(ARTICLE_IMG_REPO+"\\"+articleno);
destDir.mkdirs();
FileUtils.moveFileToDirectory(srcFile, destDir, true);
//전송된 originalFileName을 이용해 기존의 파일을 삭제
File oldFile = new File(ARTICLE_IMG_REPO+"\\"+articleno+"\\"+originalFileName);
oldFile.delete();
}
//새 글 등록 메시지를 나타낸 후 자바스크립트 location 객체의 href 속성을 이용해 글 목록을 요청
PrintWriter writer = response.getWriter();
writer.print("<script>" + " alert('글을 수정했습니다.');"
+ " location.href='"
+ request.getContextPath()
+ "/board/viewArticle.do?articleno="+articleno+"';"+"</script>");
return;
}
else if(action.equals("/removeArticle.do")) {
int articleno = Integer.parseInt(request.getParameter("articleno"));
//articleno 값에 대한 글을 삭제한 후 삭제된 부모 글과 자식 글의 articleno 목록을 가져옴
List<Integer> articleNoList = boardService.removeArticle(articleno);
//삭제된 글들의 이미지 저장 폴더들을 삭제
for(int _articleno : articleNoList) {
File imgDir = new File(ARTICLE_IMG_REPO+"\\"+_articleno);
if(imgDir.exists()) {
FileUtils.deleteDirectory(imgDir);
}
}
PrintWriter writer = response.getWriter();
writer.print("<script>" + " alert('글을 삭제했습니다.');"
+ " location.href='"
+ request.getContextPath()
+ "/board/listArticles.do';"+"</script>");
return;
}
else if(action.equals("/replyForm.do")){
System.out.println("parentno = "+request.getParameter("parentno"));
//답글창 요청 시 미리 부모 글 번호를 parentno 속성으로 세션에 저장
int parentno = Integer.parseInt(request.getParameter("parentno"));
session = request.getSession();
session.setAttribute("parentno", parentno);
nextPage = "/board01/replyForm.jsp";
}
else if(action.equals("/addReply.do")){
//답글 전송 시 세션에 저장된 parentno를 가져옴
session = request.getSession();
int parentno = (Integer) session.getAttribute("parentno");
session.removeAttribute("parentno");
Map<String,String> articleMap = upload(request,response);
String title = articleMap.get("title");
String content = articleMap.get("content");
String imagefilename = articleMap.get("imagefilename");
articleVO.setParentno(parentno);//답글의 부모글 번호를 설정
articleVO.setId("lee");//답글의 작성자 ID를 lee로 설정
articleVO.setTitle(title);
articleVO.setContent(content);
articleVO.setImagefilename(imagefilename);
int articleno = boardService.addReply(articleVO);//답글을 테이블에 추가
//답글에 첨부한 이미지를 temp 폴더에서 답글 번호 폴더로 이동
if(imagefilename != null && imagefilename.length() != 0) {
File srcFile = new File(ARTICLE_IMG_REPO+"\\"+"temp"+"\\"+imagefilename);
File destDir = new File(ARTICLE_IMG_REPO+"\\"+articleno);
destDir.mkdirs();
FileUtils.moveFileToDirectory(srcFile, destDir, true);
}
PrintWriter writer = response.getWriter();
writer.print("<script>" + " alert('답글을 추가했습니다.');"
+ " location.href='"
+ request.getContextPath()
+ "/board/viewArticle.do?articleno="+articleno+"';"+"</script>");
return;
}
else {
nextPage = "/board01/listArticles.jsp";
}
RequestDispatcher dispatch = request.getRequestDispatcher(nextPage);
dispatch.forward(request, response);
} catch (Exception e) {
e.printStackTrace();
}
}
private Map<String, String> upload(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Map<String, String> articleMap = new HashMap<String, String>();
String encoding = "utf-8";
File currentDirPath = new File(ARTICLE_IMG_REPO);//글 이미지 저장 폴더에 대해 파일 객체를 생성
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setRepository(currentDirPath);
factory.setSizeThreshold(1024*1024);
ServletFileUpload upload = new ServletFileUpload(factory);
try {
List items = upload.parseRequest(request);//request 객체에서 매개변수를 List로 가져옴
for (int i = 0; i < items.size(); i++) {
FileItem fileItem = (FileItem) items.get(i);//파일 업로드창에서 업로드된 항목들을 하나씩 가져옴
//폼 필드면 전송된 매개변수 값을 출력
if (fileItem.isFormField()) {
System.out.println(fileItem.getFieldName()+"="+fileItem.getString(encoding));
//파일 업로드로 같이 전송된 새 글 관련 매개변수를 Map에 저장한 후 반환하고, 새 글과 관련된 title, content를 Map에 저장
articleMap.put(fileItem.getFieldName(), fileItem.getString(encoding));
}
else {
//업로드한 파일이 존재하는 경우 업로드한 파일의 파일 이름으로 저장소에 업로드
if(fileItem.getSize() > 0) {
int idx = fileItem.getName().lastIndexOf("\\");
if(idx == -1) {
idx = fileItem.getName().lastIndexOf("/");
}
//첨부한 파일을 먼저 temp 폴더에 업로드,
String fileName = fileItem.getName().substring(idx+1);
System.out.println("파일명 = "+fileName);
articleMap.put(fileItem.getFieldName(), fileName);//익스플로러에서 업로드 파일의 경로 제거 후 map에 파일명 저장
File uploadFile = new File(currentDirPath+"\\temp\\"+fileName);
fileItem.write(uploadFile);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return articleMap;
}
}
|
cs |
DAO
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
|
public class BoardDAO {
private static BoardDAO instance = new BoardDAO();
private Connection con = null;
private PreparedStatement pstmt = null;
private ResultSet rs = null;
public static BoardDAO getInstance() {
return instance;
}
public Connection getConnection() throws Exception {
Context ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup("java:/comp/env/jdbc/oracle");
return ds.getConnection();
}
// public List<ArticleVO> selectAllArticles() {
// List<ArticleVO> articleList = new ArrayList<ArticleVO>();
//
// try{
// con = getConnection();
// //오라클 계층형 SQL문 실행
// String sql = "select level, articleno, parentno, title, content, id, writedate from t_board "
// + "start with parentno=0 "
// + "connect by prior articleno=parentno "
// + "order siblings by articleno desc";
// pstmt = con.prepareStatement(sql);
// rs = pstmt.executeQuery();
//
// while (rs.next()) {
// int level = rs.getInt("level");//각 글의 계층을 저장
// int articleno = rs.getInt("articleno");
// int parentno = rs.getInt("parentno");
// String title = rs.getString("title");
// String content = rs.getString("content");
// String id = rs.getString("id");
// Date writedate = rs.getDate("writedate");
// //글 정보를 ArticleVO 객체의 속성에 설정
// ArticleVO article = new ArticleVO();
// article.setLevel(level);
// article.setArticleno(articleno);
// article.setParentno(parentno);
// article.setTitle(title);
// article.setContent(content);
// article.setId(id);
// article.setWritedate(writedate);
//
// articleList.add(article);
// }
// rs.close();
// pstmt.close();
// con.close();
// } catch (Exception e) {
// e.printStackTrace();
// }
// return articleList;
// }
public List selectAllArticles(Map<String,Integer> pagingMap) {
List<ArticleVO> articleList = new ArrayList<ArticleVO>();
//전송된 section과 pageNum 값을 가져옴
int section = pagingMap.get("section");
int pageNum = pagingMap.get("pageNum");
try{
con = getConnection();
//오라클 계층형 SQL문 실행
String sql = "select * from " +
"(select rownum as recNum, LVL, articleno, parentno, title, content, id, writedate from " +
"(select level as LVL, articleno, parentno, title, content, id, writedate " +
"from t_board " +
"start with parentno=0 " +
"connect by prior articleno=parentno " +
"order siblings by articleno desc)) " +
"where recNum between (?-1)*100+(?-1)*10+1 and (?-1)*100+?*10";
//section과 pageNum 값으로 레코드 번호의 범위를 조건으로 정한다.
//이들의 값이 각각 1로 전송되었으면 between 1 and 10이 된다.
pstmt = con.prepareStatement(sql);
pstmt.setInt(1,section);
pstmt.setInt(2,pageNum);
pstmt.setInt(3,section);
pstmt.setInt(4,pageNum);
rs = pstmt.executeQuery();
while (rs.next()) {
int level = rs.getInt("lvl");//각 글의 계층을 저장
int articleno = rs.getInt("articleno");
int parentno = rs.getInt("parentno");
String title = rs.getString("title");
String content = rs.getString("content");
String id = rs.getString("id");
Date writedate = rs.getDate("writedate");
//글 정보를 ArticleVO 객체의 속성에 설정
ArticleVO article = new ArticleVO();
article.setLevel(level);
article.setArticleno(articleno);
article.setParentno(parentno);
article.setTitle(title);
article.setContent(content);
article.setId(id);
article.setWritedate(writedate);
articleList.add(article);
}
rs.close();
pstmt.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
return articleList;
}
public int selectTotArticles() {
try{
con = getConnection();
String sql = "select count(articleno) from t_board";
pstmt = con.prepareStatement(sql);
rs = pstmt.executeQuery();
if (rs.next()) {
return (rs.getInt(1));
}
rs.close();
pstmt.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
//insertNewArticle 메서드의 쿼리를 실행하기 전에 새 글에 대한 글 번호를 먼저 가져옴
private int getNewArticleNO() {
int re = 0;
try{
con = getConnection();
String sql = "select max(articleno) from t_board";//기본 글 번호 중 가장 큰 번호 조회
System.out.println(sql);
pstmt = con.prepareStatement(sql);
rs = pstmt.executeQuery();
//가장 큰 번호에 1을 더한 번호를 반환
if (rs.next()) {
re = rs.getInt(1)+1;
return re;
}
rs.close();
pstmt.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
return re;
}
public int insertNewArticle(ArticleVO article) {
int articleno = getNewArticleNO();//새 글을 추가하기 전에 새 글에 대한 글 번호를 가져옴
try{
con = getConnection();
int parentno = article.getParentno();
String title = article.getTitle();
String content = article.getContent();
String id = article.getId();
String imagefilename = article.getImagefilename();
String sql = "insert into t_board (articleno, parentno, title, content, id, imagefilename) values(?,?,?,?,?,?)";
pstmt = con.prepareStatement(sql);
pstmt.setInt(1, articleno);
pstmt.setInt(2, parentno);
pstmt.setString(3, title);
pstmt.setString(4, content);
pstmt.setString(5, id);
pstmt.setString(6, imagefilename);
System.out.println("dao imagefilename = "+imagefilename);
pstmt.executeUpdate();
pstmt.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("dao articleno = "+articleno);
return articleno;
}
public ArticleVO selectArticle(int articleno) {
ArticleVO article = new ArticleVO();
try{
con = getConnection();
String sql = "select articleno, parentno, title, content, imagefilename, id, writedate from t_board where articleno=?";
pstmt = con.prepareStatement(sql);
pstmt.setInt(1,articleno);
rs = pstmt.executeQuery();
if (rs.next()) {
int _articleno = rs.getInt("articleno");
int parentno = rs.getInt("parentno");
String title = rs.getString("title");
String content = rs.getString("content");
String imagefilename = rs.getString("imagefilename");
String id = rs.getString("id");
Date writedate = rs.getDate("writedate");
article.setArticleno(_articleno);
article.setParentno(parentno);
article.setTitle(title);
article.setContent(content);
article.setImagefilename(imagefilename);
article.setId(id);
article.setWritedate(writedate);
}
rs.close();
pstmt.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
return article;
}
public void updateArticle(ArticleVO article) {
int articleno = article.getArticleno();
String title = article.getTitle();
String content = article.getContent();
String imagefilename = article.getImagefilename();
try{
con = getConnection();
String sql = "update t_board set title=?, content=?";
//수정된 이미지 파일이 있을 때만 imagefilename을 sql문에 추가
if (imagefilename != null && imagefilename.length() != 0) {
sql += ",imagefilename=?";
}
sql += "where articleno=?";
pstmt = con.prepareStatement(sql);
pstmt.setString(1, title);
pstmt.setString(2, content);
//이미지 파일을 수정하는 경우와 그렇지 않은 경우를 구분해서 실행
if (imagefilename != null && imagefilename.length() != 0) {
pstmt.setString(3, imagefilename);
pstmt.setInt(4, articleno);
}else{
pstmt.setInt(3, articleno);
}
pstmt.executeUpdate();
pstmt.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
//전달된 articleno에 대한 글을 삭제
public void deleteArticle(int articleno) {
try{
con = getConnection();
//오라클 계층형 sql문을 이용해 삭제 글과 관련된 자식 글까지 모두 삭제
String sql = "delete from t_board " +
"where articleno in (" +
"select articleno from t_board " +
"start with articleno = ? " +
"connect by prior articleno = parentno)";
pstmt = con.prepareStatement(sql);
pstmt.setInt(1, articleno);
pstmt.executeUpdate();
pstmt.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
//삭제할 글에 대한 글 번호를 가져옴
public List<Integer> selectRemovedArticles(int articleno) {
List<Integer> articleNoList = new ArrayList<Integer>();
try{
con = getConnection();
//삭제한 글들의 articleno를 조회
String sql = "select articleno from t_board " +
"start with articleno = ? " +
"connect by prior articleno = parentno";
pstmt = con.prepareStatement(sql);
pstmt.setInt(1, articleno);
rs = pstmt.executeQuery();
while (rs.next()) {
articleno = rs.getInt("articleno");
articleNoList.add(articleno);
}
rs.close();
pstmt.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
return articleNoList;
}
}
|
cs |
서비스
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
public class BoardService {
BoardDAO boardDAO;
public BoardService() {
//생성자 호출 시 BoardDAO()객체 생성
boardDAO = new BoardDAO();
}
// public List<ArticleVO> listArticles() {
// List<ArticleVO> articleList = boardDAO.selectAllArticles();
// return articleList;
// }
public Map listArticles(Map pagingMap) {
Map articlesMap = new HashMap();
List<ArticleVO> articleList = boardDAO.selectAllArticles(pagingMap);//전달된 pagingMap을 사용해 글 목록을 조회
int totArticles = boardDAO.selectTotArticles();//테이블에 있는 전체 글 수를 조회
articlesMap.put("articlesList", articleList);//조회된 글 목록을 ArrayList에 저장한 후 다시 articlesMap에 저장
articlesMap.put("totArticles", totArticles);//전체 글 수를 articlesMap에 저장
return articlesMap;
}
public int addArticle(ArticleVO article) {
return boardDAO.insertNewArticle(article);
}
public ArticleVO viewArticle(int articleno) {
ArticleVO article = null;
article = boardDAO.selectArticle(articleno);
return article;
}
public void modArticle(ArticleVO article) {
boardDAO.updateArticle(article);
}
public List<Integer> removeArticle(int articleno) {
List<Integer> articleNoList = boardDAO.selectRemovedArticles(articleno);
boardDAO.deleteArticle(articleno);
return articleNoList;
}
//새 글 추가 시 사용한 insertNewArticle()메서드를 사용해서 답글을 추가
public int addReply(ArticleVO article) {
return boardDAO.insertNewArticle(article);
}
}
|
cs |
listArticles.jsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%request.setCharacterEncoding("utf-8"); %>
<c:set var="contextPath" value="${pageContext.request.contextPath}"/>
<c:set var="articlesList" value="${articlesMap.articlesList}"/>
<c:set var="totArticles" value="${articlesMap.totArticles}"/>
<c:set var="section" value="${articlesMap.section}"/>
<c:set var="pageNum" value="${articlesMap.pageNum}"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
<style type="text/css">
.no-uline {text-decoration: none;}
/* 선택한 페이지 번호 빨간색으로 표시 */
.sel-page{text-decoration: none; color: red;}
.cls2{text-align:center; font-size:30px;}
</style>
</head>
<body>
<table border="1" align="center" width="80%">
<tr height="10" align="center">
<th>글번호</th>
<th>작성자</th>
<th>제목</th>
<th>작성일</th>
</tr>
<c:choose>
<c:when test="${empty articlesList}">
<tr height="10">
<td colspan="4" align="center">
<b>등록된 글이 없습니다.</b>
</td>
</tr>
</c:when>
<c:when test="${!empty articlesList}">
<c:forEach var="article" items="${articlesList}" varStatus="articleNum">
<tr align="center">
<!-- <forEach>의 varStatus의 count 속성을 이용해 글번호 1부터 자동으로 표시 -->
<td width="5%">${articleNum.count}</td>
<td width="10%">${article.id}</td>
<td align="left" width="35%">
<!-- 왼쪽으로 30px만큼 여백을 준 후 글 제목들을 표시 -->
<span style="padding-left: 30px"></span>
<c:choose>
<c:when test="${article.level>1}">
<c:forEach begin="1" end="${article.level}" step="1">
<span style="padding-left: 20px"></span>
</c:forEach>
<span>[답변]</span>
<a href="${contextPath}/board/viewArticle.do?articleno=${article.articleno}">
${article.title}
</a>
</c:when>
<c:otherwise>
<a href="${contextPath}/board/viewArticle.do?articleno=${article.articleno}">
${article.title}
</a>
</c:otherwise>
</c:choose>
</td>
<td width="10%">
<fmt:formatDate value="${article.writedate}"/>
</td>
</tr>
</c:forEach>
</c:when>
</c:choose>
</table>
<div class="cls2">
<c:if test="${totArticles != null}">
<c:choose>
<c:when test="${totArticles>100}"><!-- 100개 이상인 경우 -->
<c:forEach var="page" begin="1" end="10" step="1">
<!-- section 값 2부터는 앞 세션으로 이동할 수 있는 pre를 표시 -->
<c:if test="${section > 1 && page == 1}">
<a class="no-uline" href="${contextPath}board/listArticles.do?section=${section-1}&pageNum=${(section-1)*10+page}">
pre
</a>
</c:if>
<a class="no-uline" href="${contextPath}board/listArticles.do?section=${section}&pageNum=${page}">
${(section-1)*10+page}
</a>
<!-- 페이이지 번호 10 오른쪽에는 다음 섹션으로 이동할 수 있는 next를 표시 -->
<c:if test="${page == 10}">
<a class="no-uline" href="${contextPath}board/listArticles.do?section=${section+1}&pageNum=${section*10+1}">
next
</a>
</c:if>
</c:forEach>
</c:when>
<c:when test="${totArticles == 100}">
<c:forEach var="page" begin="1" end="10" step="1">
<a href="${contextPath}/board/listArticles.do?section=${section}&pageNum=${page}">
${page}
</a>
</c:forEach>
</c:when>
<c:when test="${totArticles <100}"><!-- 100개 이하인 경우 -->
<c:forEach var="page" begin="1" end="${totArticles/10 +1}" step="1">
<c:choose>
<!-- 페이지 번호와 컨트롤러에서 넘어온 pageNum이 같은 경우 페이지 번호를 빨간색으로 표시 -->
<c:when test="${page==pageNum}">
<a class="sel-page" href="${contextPath}/board/listArticles.do?section=${section}&pageNum=${page}">
${page}
</a>
</c:when>
<c:otherwise>
<!-- 페이지 번호를 클릭하면 section 값과 pageNum 값을 컨트롤러로 전송 -->
<a href="${contextPath}/board/listArticles.do?section=${section}&pageNum=${page}">
${page}
</a>
</c:otherwise>
</c:choose>
</c:forEach>
</c:when>
</c:choose>
</c:if>
</div>
<center>
<a href="${contextPath}/board/articleForm.do">글쓰기</a>
</center>
</body>
</html>
|
cs |
728x90
'자바 웹 > MVC' 카테고리의 다른 글
MVC - 서블릿(컨트롤러)/답변형 게시판 4(답글 작성) (0) | 2022.06.29 |
---|---|
MVC - 서블릿(컨트롤러)/답변형 게시판 3(수정, 삭제) (0) | 2022.06.26 |
MVC - 서블릿(컨트롤러)/답변형 게시판 2(글쓰기, 상세내용) (0) | 2022.06.26 |
MVC - 서블릿(컨트롤러)/답변형 게시판 1(계층구조) (0) | 2022.06.25 |