복습

Setter DI

- Setter 메소드가 만들어져 있어야함

ex) Contoller 에 Service 클래스를 주입할때 Service 클래스 안에 DI 가 있어야함

Constructor DI

- 생성자가 만들어져 있어야함

어노테이션 기반 DI

- 3가지 조건을 만족해야함

- 생성자나 Setter 메소드가 없어도 가능함

 

servlet-xml

ViewResolver

- View 파일들이 저장될 최상위 디렉토리 지정

- servlet-context.xml 에서 설정

 

 base-package

- 자바 파일들이 저장될 최상위 디렉토리 지정

- servlet-context.xml 에서 설정

 

root-context.xml

- 직접 bean 을 만들어서 Setter DI, Constructor DI 로 DB 연동 관련 내용 처리

- Controller, Service 와는 달리, DAO 에서 SqlSession 객체를 주입하기 위해서는 root-context.xml 에 bean 이 만들어져 있어야한다

 

+ 프로젝트 실행방법

- index 파일이 만들어져 있을때 프로젝트 Run As -> Run on Server 로 실행 가능

- index 파일 없을땐 다른 방법으로 실행해야한다


프로젝트 myBatis2 : 사원 등록 (이어서)

- 사원 등록폼 및 등록 기능은 모두 구현했고 이제 실제로 50번 부서에 사원을 등록해보자

- 이제 개발부는 참조하는 사원(자식) 이 있으므로 삭제되지 않는다


프로젝트 myBatis2 : 사원 상세 페이지

- 해당 부서의 직원 목록을 출력하는 부서 상세 페이지 empList.jsp 에서 사원의 이름을 클릭하면 사원 상세 페이지로 이동

 

<td><a href="empView.do?empno=${emp.empno}"
		class="btn btn-info">${emp.ename}</a></td>

- 사원명을 클릭하면 "empView.do" 로 요청한다, 요청하면서 사원 번호인 empno 를 GET 방식으로 전달함

 

Controller 클래스 EmpController.java 에서 "empView.do" 요청 부분만

	// 사원 상세페이지
	@RequestMapping("empView.do")
	public String empView(int empno, Model model) {
		Emp emp = es.select(empno); // 사원 상세 정보 구하기
		model.addAttribute("emp", emp);
		return "emp/empView";
	}

- 앞에서 넘어온 값인 사원번호를 @RequestParam (생략) 으로 바로 변수 empno 로 값을 받는다

- 자동으로 int 형으로 형변환되어 저장됨

- 1명에 대한 상세정보를 DB에서 구해와서 View 에 뿌려야 하므로 Model 객체를 매개변수에 선언해서 받음

<돌아온 후>

- 사원의 상세정보는 select() 가 리턴되면서 Emp DTO 객체에 저장되어 돌아온다, 그걸 Emp DTO 객체 emp 에 저장함

- 그 객체 emp 를 Model 객체에 저장하고 /WEB-INF/views/emp/empView.jsp 파일로 이동

- View 페이지로 이동할때 prefix, suffix 를 빼고 작성하고, 하위의 패키지는 적어줘야하므로 "emp/empView" 로 작성

 

Service 클래스 EmpServiceImpl.java 에서 select() 메소드 부분만

	public Emp select(int empno) {
		return ed.select(empno);
	}

- DB 연동을 해야하므로 Service 로 넘어왔다

 

DAO 클래스 EmpDaoImpl.java 에서 select() 메소드 부분만

	public Emp select(int empno) {
		return sst.selectOne("empns.select", empno);
	}

- root-context.xml 에서 SqlSession bean 객체를 생성했고, 그걸 DAO 클래스에 주입했으므로 selectOne() 사용 가능

- 전달된 사원번호 empno 를 selectOne() 을 호추랗며 그대로 전달함

- 사원 1명에 대한 상세정보를 구해야하므로 selectOne() 을 사용

 

Mapper 파일 Emp.xml 에서 id 가 "select" 인 태그 부분만

	<select id="select" parameterType="int" resultType="emp">
		select * from emp where empno=#{empno}
	</select>

- 전달받은 사원 번호로 해당 사원의 상세정보(모든 정보) 를 검색함

- 전달받은 값은 사원번호이므로 전달받은 자료형 parameterType 은 "int"

- 돌려주는 자료형 resultType 은 Emp DTO alias 인 "emp"

 

- 다시 DAO -> Service -> Controller 로 갔다가 View 로 오게 된다

 

View 페이지 empView.jsp

- emp/empView.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ include file="../header.jsp"%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
	$(function() {
		$('#list').load('empList.do?deptno=${emp.deptno}');
	});
</script>
</head>
<body>
	<div class="container">
		<h2 class="text-primary">직원 상세정보</h2>
		<table class="table table-bordered">
			<tr>
				<td>사번</td>
				<td>${emp.empno }</td>
			</tr>
			<tr>
				<td>이름</td>
				<td>${emp.ename}</td>
			</tr>
			<tr>
				<td>업무</td>
				<td>${emp.job }</td>
			</tr>
			<tr>
				<td>관리자</td>
				<td>${emp.mgr }</td>
			</tr>
			<tr>
				<td>입사일</td>
				<td>${emp.hiredate }</td>
			</tr>
			<tr>
				<td>급여</td>
				<td>${emp.sal }</td>
			</tr>
			<tr>
				<td>보너스</td>
				<td>${emp.comm }</td>
			</tr>
			<tr>
				<td>부서코드</td>
				<td>${emp.deptno }</td>
			</tr>
		</table>
		<a href="empUpdateForm.do?empno=${emp.empno}" class="btn btn-info">수정</a>
		<a class="btn btn-danger" href="empDelete.do?empno=${emp.empno}">삭제</a>
		<a href="empList.do?deptno=${emp.deptno}" class="btn btn-default">목록</a>
		<div id="list"></div>
	</div>
</body>
</html>

- Emp DTO 객체 emp 가 Model 객체에 저장되어 넘어왔으므로 ${emp.필드명} 으로 값을 가져와서 출력한다

ex) 사원번호를 출력할때 ${emp.empno}

- header.jsp 안에 공통적인 내용들이 들어있다 (core 라이브러리, Bootstrap 등)

 

버튼 기능 (empView.jsp 부분)

		<a href="empUpdateForm.do?empno=${emp.empno}" class="btn btn-info">수정</a>
		<a class="btn btn-danger" href="empDelete.do?empno=${emp.empno}">삭제</a>
		<a href="empList.do?deptno=${emp.deptno}" class="btn btn-default">목록</a>

- 사원 상세 페이지에도 '수정', '삭제', '목록' 버튼이 있다

- '목록' 을 누르면 해당 부서 상세 페이지로 간다, 해당 부서의 부서번호인 ${emp.deptno} 전달

- '수정' 을 누르면 사원 정보 수정 페이지로 간다

- '삭제' 를 누르면 사원 삭제 페이지로 간다

 


프로젝트 myBatis2 : 사원 정보 수정폼

- 사원 상세 페이지 empView.jsp 에서 '수정' 버튼을 누르면 사원 정보 수정폼으로 간다

		<a href="empUpdateForm.do?empno=${emp.empno}" class="btn btn-info">수정</a>

- '수정' 을 누르면 "empUpdateForm.do" 료 요청한다, 요청하면서 사원 번호인 empno 를 전달

 

Controller 클래스 EmpController.java 에서 "empUpdateFomr.do" 요청 부분만

	// 사원 수정폼
	@RequestMapping("empUpdateForm.do")
	public String empUpdateForm(int empno, Model model) {
		Emp emp = es.select(empno);
		List<Dept> deptList = ds.list();
		model.addAttribute("emp", emp);
		model.addAttribute("deptList", deptList);
		return "emp/empUpdateForm";
	}

- 앞에서 넘어온 사원번호 empno 를 @RequestParam("empno") (생략) 을 통해 바로 매개변수의 empno 에 저장한다

사원 수정폼에서 할 DB 연동 작업 2가지

1. 사원 수정폼에 뿌려줄 사원 상세 정보 구하기

- Emp Service 객체 es 로 Emp Service 클래스의 select() 메소드를 호출하고, 사원 번호 empno 를 전달

2. 사원 수정폼에서 부서를 수정할때, 부서 목록을 가져와야한다 

- Dept Service 객체 ds 로 Dept Service 클래스의 list() 메소드를 호출함, 돌아올땐 부서 목록을 List 형태로 돌려줌

 

1. 사원 수정폼에 뿌려줄 사원 상세 정보 구하기

- 이전에 사원 상세 정보를 구할때 했던 내용과 비슷하므로 설명 생략 https://laker99.tistory.com/147

2. 사원 수정폼에서 부서를 수정할때, 부서 목록을 가져와야한다 

- 이전에 사원 등록폼에서 했던 내용과 비슷하므로 설명 생략 https://laker99.tistory.com/147

 

<돌아올때>

- 해당 사원의 상세 정보를 저장한 DTO 객체 emp 와 부서 전체 목록인 deptList 를 Model 에 저장해서 "empUpdateForm.jsp" 로 이동

 

View 페이지인 empUpdateForm.jsp

- emp/empUpdateForm.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ include file="../header.jsp"%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<div class="container" align="center">
		<h2 class="text-primary">직원정보 수정</h2>
		<form action="empUpdate.do" method="post">
			<table class="table table-bordered">
				<tr>
					<td>사번</td>
					<td><input type="text" name="empno" readonly="readonly"
						value="${emp.empno}"></td>
				</tr>
				<tr>
					<td>이름</td>
					<td><input type="text" name="ename" required="required"
						value="${emp.ename }"></td>
				</tr>
				<tr>
					<td>업무</td>
					<td><input type="text" name="job" required="required"
						value="${emp.job }"></td>
				</tr>
				<tr>
					<td>급여</td>
					<td><input type="text" name="sal" required="required"
						value="${emp.sal}"></td>
				</tr>
				<tr>
					<td>보너스</td>
					<td><input type="text" name="comm" required="required"
						value="${emp.comm }"></td>
				</tr>
				<tr>
					<td>부서코드</td>
					<td><select name="deptno">
							<c:forEach var="dept" items="${deptList}">
								<c:if test="${emp.deptno==dept.deptno}">
									<option value="${dept.deptno}" selected="selected">
										${dept.dname}(${dept.deptno})</option>
								</c:if>
								<c:if test="${emp.deptno!=dept.deptno}">
									<option value="${dept.deptno}">${dept.dname}(${dept.deptno})</option>
								</c:if>
							</c:forEach>
					</select></td>
				</tr>
				<tr>
					<td colspan="2"><input type="submit" value="수정"></td>
				</tr>
			</table>
		</form>
	</div>
</body>
</html>

- emp.deptno (해당 사원의 부서) 와 dept.deptno (forEach에 의해 모든 부서의 부서번호가 차례대로 들어감) 가 같으면 selected 함으로서 해당 사원이 가입할때 등록했던 부서는 select-option 에서 선택되어 나타나도록 했다

+ jQuery 로 처리하면 간단하게 처리 가능

- 사원 번호을 readonly 속성으로 비활성화했다, readonly 이므로 값이 넘어간다!

- select-option 에 출력되는 내용은 부서명(부서번호) 형식이지만, 저장하는 값인 value 는 부서 번호가 된다

- 사원 수정폼에 수정할 정보를 입력하고 '수정' 을 누르면 action 인 "empUpdate.do" 로 요청한다


프로젝트 myBatis2 : 사원 정보 수정

Controller 클래스 EmpController.java 에서 "empUpdate.do" 요청 부분만

	// 사원 정보 수정
	@RequestMapping("empUpdate.do")
	public String empUpdate(Emp emp, Model model) {
		int result = es.update(emp);
		model.addAttribute("deptno", emp.getDeptno());
		model.addAttribute("result", result);
		return "emp/empUpdate";
	}

- 사원 수정폼에서 넘어온 값들을 @ModelAttribuate (생략) 을 사용해서 Setter 메소드들로 한번에 Emp DTO 객체인 emp 에 저장한다

- Emp Service 객체 es 를 사용해서 update() 메소드를 호출하고, 호출할때 수정할 정보를 저장한 객체 emp 를 전달

- 수정할 사원을 특정하는 사원 번호는 앞의 사원 수정폼에서 넘어왔으므로 emp 객체 안 emp.empno 에 저장되어있음

<돌아온 후>

- 수정 성공시 result 에는 1이 저장된다

- 수정이 끝난 후 부서 상세 페이지로 돌아가므로, 해당 사원이 소속된 부서의 부서번호가 필요하다, 그래서 emp.getDeptno() 를 "deptno" 네임으로 Model 객체에 저장

- View 페이지에서 수정 성공 / 실패 처리를 하기 위해 update() 에서 돌려받은 값 result 를 Model 객체에 저장

- /WEB-INF/views/emp/empUpdate.jsp 로 이동

 

Service 클래스 EmpServiceImpl.java 에서 update() 메소드 부분만

	public int update(Emp emp) {
		return ed.update(emp);
	}

 

DAO 클래스 EmpDaoImpl.java 에서 update() 메소드 부분만

	public int update(Emp emp) {
		return sst.update("empns.update", emp);
	}

- 수정할 정보를 담은 Emp DTO 객체 emp 를 받아서 그대로 전달

- 수정 성공시 자동으로 1을 리턴한다

 

Mapper 파일 Emp.xml 에서 id 가 "update" 태그 부분만

	<update id="update" parameterType="emp">
		update emp set ename=#{ename},job=#{job},sal=${sal},
			comm=#{comm},deptno=#{deptno} where empno=#{empno}
	</update>

- "emp" 는 MyBatis 환경설정 파일 Configuration.xml 에서 설정한 Emp DTO 의 alias 이다

- 객체 emp 가 넘어왔으므로 #{ename} 은 emp.getEname() 과 같은 의미

- 사원번호는 객체 emp 의 emp.empno 에 저장되어 있으므로 #{empno} 로 가져와서 where 절에 넣는다

 

View 페이지 empUpdate.jsp

- emp/empUpdate.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ include file="../header.jsp"%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<c:if test="${result > 0 }">
		<script type="text/javascript">
			alert("수정 성공");
			location.href = "empList.do?deptno=${deptno}";
		</script>
	</c:if>
	<c:if test="${result <= 0 }">
		<script type="text/javascript">
			alert("수정 실패");
			history.go(-1);
		</script>
	</c:if>
</body>
</html>

- Model 객체에 저장된 "result" 를 통해 성공 / 실패 처리를한다

- 수정이 성공한 후에 "empList.do" 로 요청하고, Model 객체에 저장된 "deptno" 를 전달하면서 해당 부서 상세 페이지로 이동한다

 


프로젝트 myBatis2 : 사원 정보 삭제

- 사원 상세 페이지 empView.jsp 에서 '삭제' 버튼을 누르면 사원 삭제를 할 수 있다

- 삭제 폼은 없고 바로 삭제 된다

		<a class="btn btn-danger" href="empDelete.do?empno=${emp.empno}">삭제</a>

- '삭제' 를 누르면 "empDelete.do" 료 요청한다, 요청하면서 사원 번호인 empno 를 전달

 

Controller 클래스 EmpController.java 에서 "empDelete.do" 요청 부분만

	// 사원 삭제
	@RequestMapping("empDelete.do")
	public String empDelete(int empno, Model model) {
		Emp emp = es.select(empno); // 사원 상세 정보 구하기
		int result = es.delete(empno);
		model.addAttribute("result", result);
		model.addAttribute("deptno", emp.getDeptno());
		return "emp/empDelete";
	}

- 앞에서 넘어온 사원번호 empno 를 @RequestParam("empno") (생략) 을 통해 바로 매개변수의 empno 에 저장한다
사원 삭제할때 DB 연동 작업 2가지

1. 사원 상세 정보 구하기

- 사원을 삭제 한 후 그 사원이 속해있었던 부서의 부서 상세 페이지로 이동할 것이다, 그러려면 부서 번호가 필요함

- 부서 상세 페이지로 가기 위해, 삭제될 사원의 상세 정보를 구해서 거기서 부서 번호를 가져올 것
- 사원의 상세 정보를 구하기 위해 select() 메소드를 호출하며, 사원번호를 전달

2. 사원 삭제 하기

- 사원 삭제를 위해 delete() 메소드를 호출하며, 사원번호를 전달

<돌아온 후>

- 삭제된 사원 상세정보를 받은 emp 에서 emp.getDeptno() 로 사원이 소속되어있던 부서번호를 가져와서 Model 객체에 저장하고 empDelete.jsp 로 이동

 

1. 사원 상세 정보 구하기

- 이전에 여러번 했으므로 설명 생략

2. 사원 삭제하기

Service 클래스 EmpServiceImpl.java 에서 delete() 메소드 부분만

	public int delete(int empno) {
		return ed.delete(empno);
	}

 

DAO 클래스 EmpDaoImpl.java 에서 delete() 메소드 부분만

	public int delete(int empno) {
		return sst.delete("empns.delete", empno);
	}

 

 

Mapper 파일 Emp.xml 에서 id 가 "delete" 인 태그 부분만

	<delete id="delete" parameterType="int">
		delete from emp where empno=#{empno}
	</delete>

 

View 페이지 empDelete.jsp

- emp/empDelete.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ include file="../header.jsp"%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<c:if test="${result > 0 }">
		<script type="text/javascript">
			alert("삭제 성공 ");
			location.href = "empList.do?deptno=${deptno}";
		</script>
	</c:if>
	<c:if test="${result <= 0 }">
		<script type="text/javascript">
			alert("삭제 실패");
			history.go(-1);
		</script>
	</c:if>
</body>
</html>

- 삭제 성공시 "empList.do" 로 요청하면서 삭제된 사원의 소속 부서인 deptno 를 넘겨주면서 해당 부서 상세 페이지로 이동

 

- 50번 부서에 등록되어있는 사원 LAY2 를 삭제해보자


STS 에 Data Source Management 추가

- STS 에는 이클립스와 다르게 Data Source Management 가 없으므로 DB 연결 불가능하다

- STS 에 plug-in 기능을 추가해야 Data Source Management 를 사용 가능

- 설치 이후 이제 필요한 SQL문을 STS 내에서 실행할 수 있다

 

STS 에 Data Source Management 추가하는 방법

- 이러면 STS 에 plug-in 을 설치한다, 원격 저장소에서 로컬 저장소로 다운받음

- 그 후 STS 를 Restart 시키면 plug-in 이 추가되어있다

- 이후 이제 필요한 SQL문을 STS 내에서 실행할 수 있다


게시판 직접 만들어보기

설계도

spring 실습 설계도

프로젝트 명
spring

계정생성
sqlplus system/oracle
create user spring identified by spring123;

권한 부여 (connect, resource 롤)
grant connect, resource to spring;

테이블명
myboard

create table myboard(
no number primary key,
writer varchar2(20),
passwd varchar2(20),
subject varchar2(50),
content varchar2(100),
readcount number, register date );

시퀀스명
myboard_seq

create sequence myboard_seq;

구조
- base-package 는 myspirng 으로 한다
- prefix 하위에 board 가 있다

환경 설정 파일 작성(세팅) 순서
1) pom.xml
2) web.xml
3) servlet-context.xml
4) configuration.xml
5) board.xml
6) root-context.xml
- 4), 5), 6) 은 DB 연동 관련 내용


오라클 계정 생성 및 권한 부여

- 기존 계정들은 복잡하므로 새 오라클 계정을 생성해서 프로젝트를 하자

 

Spring MVC 프로젝트 생성

- 도메인명 역순으로 지정해야한다

- com.myhome.spring 을 top-level 패키지로 지정

 

프토젝트 테스트

- 프로젝트 오른 마우스 -> Run As -> Run on Server

- 잘 실행되었음을 확인 가능

 

커넥션 생성, 테이블 생성하기

- webapp 폴더 하위에 sql 폴더 추가하고, 안에 SQL 파일 myboard.sql 생성

- 다음으로 커넥션을 연결해야함

- 커넥션이 생성되었다!

- Connection profile 도 설정한다

- 다음은 테이블 생성 위해 myboard.sql 작성

-- 게시판
select * from tab;
select * from seq;
select * from myboard;

-- 테이블명 : myboard
create table myboard(
	  no number primary key,
	  writer varchar2(20),
      passwd varchar2(20),
	  subject varchar2(50),
	  content varchar2(100),
	  readcount number,
	  register date );

-- 시퀀스명 : myboard_seq
create sequence myboard_seq;

- 테이블과 시퀀스 생성하기

- 테이블 및 시퀀스 생성 확인

 

환경설정 파일 세팅

+ 환경 설정 파일 작성(세팅) 순서
1) pom.xml
2) web.xml
3) servlet-context.xml
4) configuration.xml
5) board.xml
6) root-context.xml

 

pom.xml 파일 세팅

- Maven 의 환경설정 파일이다

- 잘 실행되는 내용을 가져와서 복붙하면 된다, 프로젝트 myBatis2 의 pom.xml 을 그대로 가져와서 복붙

- pom.xml 은 프로젝트 바로 하위에 있으므로 프로젝트를 선택하고 붙여넣기 (overwrite)

- 오라클, MyBatis, JSTL 라이브러리들이 모두 들어가있다

- 프로젝트 실행하기

- 환경설정 파일 만들면서 중간중간 실행해서 확인해야함

 

web.xml 파일 세팅

- url-pattern 을 / 에서 *.do 로 수정

	<servlet-mapping>
		<servlet-name>appServlet</servlet-name>
		<url-pattern>*.do</url-pattern>
	</servlet-mapping>

- 한글값 인코딩 처리 코드는 web.xml 생성시에 들어가있지 않는다, 직접 넣어줘야한다

- 프로젝트 myBatis2 에서 web.xml 에서 filter 와 filter-mapping 부분 가져오기

	<!-- 한글 입력 -->
	<filter>
		<filter-name>CharacterEncodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
		<init-param>
			<param-name>forceEncoding</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>CharacterEncodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

- 이 부분 넣어주기

 

요청 -> Dispatcher Servlet -> Controller 테스트

- HomeController.java 부분

- url-pattern 을 *.do 로 바꾸었으므로 샘플로 만들어진 HomeController.java 클래스에서 @RequestMapping 에 value 를 "/" 에서 "/test.do" 로 수정

- 요청 -> Dispatcher Servlet -> Controller 까지의 흐름을 확인하기 위해서이다

- 요청은 index.jsp 에 넣어줄 것

 

index 파일 생성

- 자동으로 실행되도록 하기 위해서 반드시 WEB-INF 폴더 하위에 index.jsp 를 생성해야함

- index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<script>
	location.href = "test.do";
</script>
</body>
</html>

- "test.do" 로 요청해준다

- index.jsp 실행

- 이 화면이 나오면 테스트 완료

- 요청 -> Dispatcher Servlet -> Controller -> View (home.jsp) 로 갔기때문에 이 화면에 나타난다

 

servlet-context.xml 파일 세팅

- base-package 가 top-level 패키지로 되어있다, 이 패키지는 java 폴더 하위에 생성되어잇음

- 즉 base-pacakge 는 자바파일들이 저장될 최상위 패키지

- 우리는 이 top-level 패키지 사용하지 않을 것

 

- myspring 패키지를 java 폴더 하위에 생성하고 myspring 을 base-package 로 설정하기

	<context:component-scan base-package="myspring" />

 

- 최상위 디렉토리 myspring 을 생성했으므로 그 myspring 아래에 controller, service, dao, model 폴더 생성

 

- 다음으로 샘플로 만들어진 HomeContorller.java 를 myspring/controller 로 옮기기

- 그 후 com.myhome.spring 패키지는 삭제 (com 만 삭제하면 다 삭제된다)

- HomeContorller.java 의 패키지도 수정해주기

package myspring.controller;

 

- 환경파일 하나를 설정했으므로 다시 프로젝트 실행해서 실행확인

- servlet-context.xml 환경설정 파일 설정 완료

- 나머지 환경설정은 DB 연동 관련 내용이다, 나중에 할 것

 

Java 파일들 생성하기

- Controller, Service, DAO, DTO 파일들을 myspring 하위의 해당 폴더 안에 파일 생성

- 생성 된 Java 파일들에 어노테이션 추가 (@Controller, @Service, @Repository 등)

- 그리고 주입할 객체 위에 @Autowired 까지 추가

+ 어노테이션은 import 를 해야한다

* 위에서 프로퍼티명을 bd 대신 dao 로 수정했다

- 일단 @Autowired 는 현재 주석해두고 @Controller, @Service, @Repository 만 붙이기

- 여기까지 설정한 후 index 파일 실행해서 확인

 

- 이제 Controller 와 Service클래스에서의 @Autowired 어노테이션 주석을 하나씩 풀고 실행을 다시 해보면 실행이 잘 된다

- DAO 클래스는 아직 @Autowired 주입이 되지 않는다, root-context.xml 세팅을 먼저 해야 주입 가능

 

- BoardDao.java

- SqlSession 또는 SqlSession 구현 클래스로 객체를 주입해야한다

- 현재는 @Autowired 로 객체 주입이 불가능하다, @Autowired 를 쓰면 실행시 오류 발생

-  @Autowired 를 주석으로 막자

- root-context.xml 에서 SqlSessionTemplate bean 객체를 생성해야하고, Constructor DI 를 해서 bean 객체를 생성해야 여기서 @Autowired 사용해서 주입 가능

 

DTO 클래스 작성

- Board.java (DTO) 부분

- 테이블안의 컬럼과 같은 이름으로 프로퍼티들을 만들고 getter / setter 메소드를 생성한다

- 테이블의 컬럼명과 DTO 프로퍼티명이 일치가 되어야 매핑이 자동으로 된다

- number 타입은 int로, Date 타입은 Date(java.util)로, varchar2 타입은 String 으로 변환

- DTO 클래스 안에는 어노테이션을 붙이지 않음

 

View 파일 위치 설정

- servlet-context.xml 에서 /WEB-INF/views/ 가 prefix 로 설정되어있다, 이건 View 파일들이 저장될 최상위 디렉토리이다

	<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<beans:property name="prefix" value="/WEB-INF/views/" />
		<beans:property name="suffix" value=".jsp" />
	</beans:bean>

- 이 /WEB-INF/views/ 하위에 Viwe 파일들을 저장할 폴더 board 를 생성하자

 

폼 가져오기

- 게시판 글 작성 폼 boardform.jsp 를 클라우드에서 폴더 board 로 가져오자

- 가져오는 파일은 이것 하나뿐임, 나머지는 직접 생성해야함

 

+ 현재 상태에서 프로젝트 시작해서 실행 확인해보기, 실행 잘 된다

+ boardform.jsp 는 View 페이지이므로 결과가 여기서 출력되는 것이다,

- boardform.jsp 를 그냥 실행하면 실행되지 않음, 오류발생

 

- boardform.jsp 를 실행해보자

 

- index 파일을 수정해서 boardform.do 로 요청시키자

- Controller 클래스 BoardController.java 에 boardform.do 요청을 받는 코드를 작성해주자

+ HomeController.java 는 삭제하기

 

- BoardController.java 에서 "boardform.do" 요청 받는 부분만

	// 글 작성 폼
	@RequestMapping("boardform.do")
	public String boardform() {
		return "board/boardform";
	}

- 접근제어자는 public, 리턴자료형은 주로 String 으로 메소드 작성

- DB 연동은 아직 처리하지 않으므로 Controller 에서 View 로 가기

- prefix 하위 폴더인 board 를 경로 앞에 붙여야한다

 

- 이제 index 파일 실행시 글 작성 폼이 나타남

- boardform.jsp 를 보자

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>글작성</title>
</head>
<body>

<form method=post action="boardwrite.do">
<table border=1 width=400 align=center>
	<caption>글작성</caption>
	<tr><th>작성자명</th>
		<td><input type=text name="writer" required="required"></td>
	</tr>
	<tr><th>비밀번호</th>
		<td><input type=password name="passwd" required="required"></td>
	</tr>
	<tr><th>제목</th>
		<td><input type=text name="subject" required="required"></td>
	</tr>
	<tr><th>내용</th>
		<td><textarea cols=40 rows=5 name="content" required="required"></textarea></td>
	</tr>
	<tr><td colspan=2 align=center>
			<input type=submit value="글작성">
			<input type=reset value="취소">
		</td>
	</tr>
</table>
</form>

</body>
</html>

- 이 폼에서 넘어가는 내용은 writer, passwd, subject, content 이다

- 입력하고 "글작성" 클릭시 "boardwrite.do" 로 넘어간다, Controller -> Service -> DAO (Mapper 파일) 으로 가야한다

- 그러기 위해서 DB 연동을 먼저 처리해야함

 

configuration.xml 파일 생성 및 세팅

- 프로젝트 myBatis2 의 configuration.xml 파일 복사해서 현재 프로젝트인 spring 의 resources 폴더에 붙여넣기, 이후 수정

- configuration.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>

	<typeAliases>
		<typeAlias alias="board" type="myspring.model.Board" />
	</typeAliases>	
	
	<!-- 
	<mappers>
		<mapper resource="sql/Dept.xml" />
		<mapper resource="sql/Emp.xml" />
	</mappers>  -->	
	
</configuration>

- 가져온 파일을 현재 프로젝트에 맞게 수정, DTO의 alias 값을 설정해준다

- base-package 부터 시작해서 DTO 까지의 경로를 써준다, myspring.model.Board

- DTO 클래스에 대한 alias 내용 한가지만 들어간다

 

Board.xml (Mapper 파일) 생성 및 세팅

- 먼저 resources 폴더 하위에 sql 폴더를 생성

- myBatis2 의 Mapper 파일인 Dept.xml 이나 Emp.xml 을 현재 프로젝트의 resources/sql로 가져와서 이름을 Board.xml 으로 수정

- Board.xml

- 루트엘리먼트인 mapper 빼고 모두 지우기, namespace 는 "boardns" 로 지정

- 여기까지 하고 프로젝트 실행해서 실행 확인, 잘 된다

 

root-context.xml

- DB 연동 관련 내용이 들어간다

- DB 설정하는 3개의 파일(configuration.xml, board.xml(Mapper), root-context.xml) 중에서 가장 마지막에 root-context.xml 내용을 세팅해야한다

- 프로젝트 myBatis2의 root-context.xml 을 복사해서 같은 위치인 /WEB-INF/spring 폴더에 붙여넣기 (overwrite)

- root-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">
	
	<!-- <context:property-placeholder location="classpath:jdbc.properties" /> -->
	
	<!-- dataSource -->
	<!-- <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
		destroy-method="close">
		<property name="driverClass" value="${jdbc.driverClassName}" />
		<property name="jdbcUrl" value="${jdbc.url}" />
		<property name="user" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
		<property name="maxPoolSize" value="${jdbc.maxPoolSize}" />
	</bean> -->
	
	<!-- Data Source -->
	<bean id="dataSource"
		class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
		<property name="driverClass" value="oracle.jdbc.driver.OracleDriver" />
		<property name="url" value="jdbc:oracle:thin:@localhost:1521:xe" />
		<property name="username" value="spring" />
		<property name="password" value="spring123" />
	</bean>
	
	<!-- 스프링 jdbc 즉 스프링으로 oracle 디비 연결 -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="configLocation" value="classpath:configuration.xml" />
		<property name="mapperLocations" value="classpath:sql/*.xml" />
	</bean>
	
	<bean id="session" class="org.mybatis.spring.SqlSessionTemplate">
		<constructor-arg index="0" ref="sqlSessionFactory" />
	</bean>	
	
</beans>

- 첫번째 bean 에서 username, password 를 테이블을 만든 계정의 username, password 인 "spring", "spring123" 로 수정

- 두번째 bean 에서 Configuration 파일 위치를 설정하는 configLocation 을 설정해야하는데 위치가 맞으므로 그대로 두기

- 두번째 bean 에서 Mapper 파일 위치를 설정하는 mapperLocations 를 설정해야하는데 위치가 맞으므로 그대로 두기

- 세번째 bean 에서 SqlSessionTemplate bean 객체를 생성하고 있다, 위의 sqlSessionFactory 를 Construct DI 로 주입

 

- 그리고 DAO 인 BoardDao.java 로 가서 @Autowired 주석 풀기, 이제는 주석 풀어도 실행 된다

- index 파일 실행시 잘 실행된다

 

- 환경설정이 모두 끝났다, 모든 환경설정 파일 기본세팅을 완료했음

 

- 이제 흐름에 따라 파일들의 내용을 추가하자

- boardform.jsp 파일을 다시 열어보자

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>글작성</title>
</head>
<body>

<form method=post action="boardwrite.do">
<table border=1 width=400 align=center>
	<caption>글작성</caption>
	<tr><th>작성자명</th>
		<td><input type=text name="writer" required="required"></td>
	</tr>
	<tr><th>비밀번호</th>
		<td><input type=password name="passwd" required="required"></td>
	</tr>
	<tr><th>제목</th>
		<td><input type=text name="subject" required="required"></td>
	</tr>
	<tr><th>내용</th>
		<td><textarea cols=40 rows=5 name="content" required="required"></textarea></td>
	</tr>
	<tr><td colspan=2 align=center>
			<input type=submit value="글작성">
			<input type=reset value="취소">
		</td>
	</tr>
</table>
</form>

</body>
</html>

- DB 연동을 처리한 후 넘어왔다

- 이 폼에서 넘어가는 내용은 writer, passwd, subject, content 이다

- 입력하고 "글작성" 클릭시 "boardwrite.do" 로 넘어간다, Controller -> Service -> DAO (Mapper 파일) 으로 가야한다

 

- Controller 클래스 BoardController.java 에서 "boardwrite.do" 요청 부분을 처리하자

- 아래 내용을 작성

	// 글 작성
	@RequestMapping("boardwrite.do")
	public String boardwrite(Board board, Model model) {
		int result = bs.insert(board);
		model.addAttribute("result", result);
		return "board/insertresult";
	}

- 폼에서 넘어온 값을 DTO 객체로 한번에 받기 위해 @ModelAttribute 사용

- 메소드 명은 요청 이름값과 같게 맞췄다

- 글을 작성(insert) 한 후 성공 / 실패를 View 에서 처리하기위해 어떠한 값들을 가져갈 것이므로 Model 객체 선언해서 받기

 

- Service 객체 bs 를 사용해서 Service 클래스의 insert() 메소드를 호출, 이때 삽입할 데이터인 객체 board 를 가져감, 리턴자료형은 int 이다

 

- Service 클래스 BoardService.java 에서 insert() 메소드를 생성해야한다

	public int insert(Board board) {
		return dao.insert(board);
	}

- Controller 에서 이 메소드를 호출해야하므로 public, 리턴자료형은 int, 메소드 명은 insert(), 매개변수 자료형은 Board

- DAO 의 insert() 를 호출

 

- 이 코드를 복사 후 DAO 클래스 BoardDao.java 로 가서 복붙 하고 수정

- BoardDao.java 에서 insert() 메소드 생성

	public int insert(Board board) {
		return session.insert("insert", board);
	}

- 이 insert() 가 실제 SQL문을 수행하고 성공시 1 을 반환함

 

- Mapper 파일인 Board.xml 에 id 가 "insert" 인 insert (글 작성) 문을 생성해야함

	<!-- 글 작성 -->
	<insert id="insert" parameterType="board">
		insert into myboard values(myboard_seq.nextval,#{writer},
		#{passwd},#{subject},#{content},0,sysdate)
	</insert>

- 전달되는 값이 DTO Board 객체 board 이므로 DTO Board 의 alias 인 "board" 를 parameterType 에 설정

- no 컬럼은 sequence 인 myboard_seq 로 세팅

- 앞에서 객체 board 가 넘어왔으므로 #{writer}, #{passwd}, #{subject}, #{content} 로 세팅

- 조회수 readcount 컬럼은 0, 등록일 register 컬럼은 sysdate 로 세팅

 

- DAO -> Service -> Controller 로 다시 돌아왔다

- Controller "boardwrite.do" 요청 부분 다시 보기

	// 글 작성
	@RequestMapping("boardwrite.do")
	public String boardwrite(Board board, Model model) {
		
		int result = bs.insert(board);
		if(result == 1) System.out.println("글 작성 성공");
		
		model.addAttribute("result", result);
		return "board/insertresult";
	}

- result 값을 한번 찍어보기

- 그리고 /WEB-INF/views/board/insetresult.jsp 로 이동한다, 이 insertresult.jsp 파일을 board 폴더 하위에 생성해야함

- 이 파일에서 성공 / 실패 처리, 즉 출력을 할 것이다

 

- insertresult.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<c:if test="${result == 1}">
	<script>
		alert("글 작성 성공");
		location.href = "boardlist.do";
	</script>
</c:if>

<c:if test="${result != 1}">
	<script>
		alert("글 작성 실패");
		history.go(-1);
	</script>
</c:if>

- JSTL core 라이브러리 사용하기 위해 core 라이브러리 불러오는 코드 한 줄 추가

- 글 작성 성공하면 목록 페이지로 갈 것이므로 "boardlist.do" 요청하기

- 글 작성 실패시 이전 페이지인 글 작성 폼으로 돌아감

 

- index 파일을 실행시켜서 글 작성폼에서 글을 작성해보자

+ 글 수정 / 삭제 시 비밀번호가 맞아야 삭제되도록 하기 위해 비밀번호를 입력받는 것임

- "boardlist.do" 요청 처리를 하지 않았으므로 오류가 뜬다

 

- Controller 클래스 BoardController.java 에서 "boardlist.do" 요청을 처리하는 코드를 작성하자 (미완성, 수정 전)

	// 글 목록
	@RequestMapping("boardlist.do")
	public String boardlist(HttpServletRequest request, Model model) {
		
		int page = 1;	// 현재 페이지 번호
		int limit = 10;	// 한 화면에 출력할 데이터 갯수
		
		if(request.getParameter("page") != null) {
			page = Integer.parseInt(request.getParameter("page"));
		}
		
		int startRow = (page - 1) * limit + 1;
		int endRow = page * limit;
		
		int listcount = bs.getCount();	// 총 데이터 갯수
		System.out.println("listcount : " + listcount);
		
		return "board/boardlist";
	}

 

- 기본변수, 파생변수를 설정해서 DB에서 목록을 구해오고, 페이징 처리를 하고, 그걸 View 에 뿌려야함

- request 객체를 매개변수로 부터 받는다, 이렇게 매개변수에 선언하면 자동으로 request 객체를 받아옴

- 결과를 View 페이지에 뿌려야하므로 Model 객체도 매개변수에 선언해서 받아온다

1. 기본변수 page : 현재 페이지를 저장할 변수

2. 기본변수 limit : 한 화면에 출력할 데이터 개수를 저장하는 변수

3. 파생변수 starRow, endRow : page, limit 을 이용해서 구해준다, page, limit 로 생성 가능하므로 굳이 생성하지 않아도 된다

4. 기본변수 listcount : 총 데이터 갯수를 저장, DB 와 연동해서 count(*) 로 가져올 것 

<총 데이터 개수 가져오기>

- Service 클래스의 getCount() 를 호출해서 리턴받는다 * 아래에서 Service 에서 getCount() 를 생성함

- 나머지 부분은 아래에서 다시 완성

 

- Service 클래스 BoardService.java 에서 getCount() 메소드를 생성해야함

	public int getCount() {
		return dao.getCount();
	}

 

- DAO 클래스 BoardDao.java 에서 getCount() 메소드 생성하기

	public int getCount() {
		return session.selectOne("count");
	}

- 그룹함수는 결과가 1개이므로 selectOne() 메소드 사용, id 가 "count" 인 SQL문 불러오기

 

- Mapper 파일 Board.xml 에서 id 가 "count" 인 SQL문 생성

	<!-- 총 데이터 갯수 -->
	<select id="count" resultType="int">
		select count(*) from myboard
	</select>

- 돌려주는 값이 총 데이터 갯수이므로 resultType 은 "int"

 

- 총 데이터 갯수를 가져왔는지 확인하기 위해 현재 상태에서 index 파일에서 "boardlist.do" 로 요청해보자

- index 파일 실행 하고 콘솔창 보기

- listcount 값이 찍혀 나왔다, 글을 하나 작성했었으므로 listcount : 1 이 맞다

 

- 이제 목록을 가져오는 작업을 Controller 부터 처리하자

- Controller 클래스 BoardController.java 에서 "boardlist.do" 요청을 처리하는 코드를 작성하자 (이어서, 완성, 추가되었다)

	// 글 목록
	@RequestMapping("boardlist.do")
	public String boardlist(HttpServletRequest request, Model model) {
		
		int page = 1;	// 현재 페이지 번호
		int limit = 10;	// 한 화면에 출력할 데이터 갯수
		
		if(request.getParameter("page") != null) {
			page = Integer.parseInt(request.getParameter("page"));
		}
		
		int startRow = (page - 1) * limit + 1;
		int endRow = page * limit;
		
		int listcount = bs.getCount();	// 총 데이터 갯수
		System.out.println("listcount : " + listcount);
		
		List<Board> boardlist = bs.getBoardList(page); // 게시판 목록
		System.out.println("boardlist : " + boardlist);
		
		// 총 페이지
		int pageCount = listcount / limit + ((listcount % limit == 0) ? 0 : 1);
		
		int startPage = ((page - 1) / 10) * limit + 1; // 1, 11, 21...
		int endPage = startPage + 10 - 1;	// 10, 20, 30...
		
		if(endPage > pageCount) endPage = pageCount;
		
		model.addAttribute("page", page);
		model.addAttribute("listcount", listcount);
		model.addAttribute("boardlist", boardlist); // 리스트
		model.addAttribute("pageCount", pageCount);
		model.addAttribute("startPage", startPage);
		model.addAttribute("endPage", endPage);
		
		return "board/boardlist";
	}

<목록 가져오기>

- MyBatis 로 처리하면 DAO -> Mapper 파일로 갈때 단 하나의 값만 전달가능하다

- limit 은 고정되어있고, startRow, endRow 는 나중에 페이지 번호 page 로 계산 가능하므로 페이지번호 page 만 넘기기

+ 또는 map 객체에 키밸류 형태로 저장하는 방법도 있다

- getBoardList() 에서 글들이 저장된 리스트를 반환하도록 할 것 * 아래에서 설명

<돌아온 후>

- getBoardList() 에서 돌아온 후 콘솔창 출력해보면 boadlist 에 내가 썼던 글의 주소가 출력된다

5. 파생변수 pageCount : 총 페이지 수를 구함, listcount 와 limit 사용

6. 파생변수 startPage & endPage : 각(현재) 블럭의 시작 페이지, 끝 페이지, page 와 limit 사용

- 이후 기본변수, 파생변수, 가져온 목록(List) 들을 Model 객체에 저장하고 board/boardlist.jsp 로 이동

 

- Service 클래스 BoardService.java 에서 목록을 가져오는 메소드 getBoardList() 를 생성하자

	public List<Board> getBoardList(int page) {
		return dao.getBoardList(page);
	}

 

- DAO 클래스 BoardDao.java 에서 getBoardList() 를 작성하자

	public List<Board> getBoardList(int page) {
		return session.selectList("list", page);
	}

- 여러개의 글(DTO 객체) 을 가져올 것이므로 selectList() 메소드 사용

- 페이지 번호 page 를 전달함, 받는 값은 DTO 객체들이 저장된 리스트이다

 

- Mapper 파일 Baord.xml 에서 id 가 "list" 인 SQL문 작성

	<!-- 글 목록 -->
	<!-- &gt; : > , &lt; : < -->
	<select id="list" parameterType="int" resultType="board">
		<![CDATA[
		select * from (select rownum rnum, board.* from (
		select * from myboard order by no desc) board )
		where rnum >= ((#{page}-1) * 10 + 1) and rnum <= (#{page} * 10)
		]]>
	</select>

- 페이지 번호가 넘어오므로 parameterType 은 "int" , 돌려주는 값은 DTO 가 저장된 리스트 이므로 resultType 은 "board"(DTO alias) 

- limit 은 10으로 고정되어있으므로 10 으로 쓰고, startRow, endRow 는 페이지 번호 page 로 계산 가능해서 사용하기

+ <. > 인식을 못하므로 &gt; , $lt; 사용, 또는 <![CDATA[ ]]> 로 전체 SQL문으로 감싸주면 부등호 기호 <, > 를 인식함

 

- View 페이지를 보기 전에 페이징 처리를 확인하기 위해 myboard.sql 에서 데이터를 강제로 많이 삽입하자

insert into myboard values(myboard_seq.nextval,'Lay','1234','Practice1',
	'Content',0,systdate)

 

- View 페이지 board/boardlist.jsp 를 생성해서 Contorller 에서 Model 객체에 저장된 값들을 활용해서 목록을 출력하자

- boardlist.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시판 목록</title>
</head>
<body>
	<a href="boardform.do">글작성</a> <br>
	글갯수 : ${listcount }
	
	<table border=1 align=center width=700>
		<caption>게시판 목록</caption>
		<tr>
			<th>번호</th>
			<th>제목</th>
			<th>작성자</th>
			<th>날짜</th>
			<th>조회수</th>
		</tr>
		
		<!-- 화면 출력 번호 -->
		<c:set var="num" value="${listcount - (page - 1) * 10}"/>

		<c:forEach var="b" items="${boardlist}">
		<tr>
			<td>${num}
				<c:set var="num" value="${num-1}"/>
			</td>
			<td>
				<a href="boardcontent.do?no=${b.no}&page=${page}">${b.subject}</a>
			</td>
			<td>${b.writer}</td>
			<td>
				<fmt:formatDate value="${b.register}" 
				pattern="yyyy-MM-dd HH:mm:ss"/>
			</td>
			<td>${b.readcount}</td>
		</tr>
		</c:forEach>
		
	</table>
<br>
<!-- 페이지 처리 -->
<center>
<c:if test="${listcount > 0}">

<!-- 1페이지로 이동 -->
<a href="boardlist.do?page=1" style="text-decoration:none"> << </a>
<!-- 이전 블럭으로 이동 -->
<c:if test="${startpage > 10}">
	<a href="boardlist.do?page=${startPage - 10}">[이전]</a>
</c:if>
<!-- 각 블럭에 10개 페이지 출력 -->
<c:forEach var="i" begin="${startPage}" end="${endPage}">
	<c:if test="${i == page}"> <!-- 현재 페이지 -->
		[${i}]
	</c:if>
	<c:if test="${i != page}"> <!-- 현재 페이지가 아닌 경우-->
		<a href="boardlist.do?page=${i}">[${i}]</a>
	</c:if>
</c:forEach>
<!-- 다음 블럭으로 이동 -->
<c:if test="${endPage < pageCount}">
	<a href="boardlist.do?page=${startPage + 10}">[다음]</a>
</c:if>
<!-- 마지막 페이지로 이동 -->
<a href="boardlist.do?page=${pageCount}" style="text-decoration:none"> >> </a>

</c:if>
</center>

</body>
</html>

- JSTL core 라이브러리, 국제화 라이브러리를 불러오기

7. 파생변수 num : 화면 출력 번호, 코어 라이브러리 set 태그 사용해서 생성했음, listcount, page 를 사용해서 생성

- forEach 태그 items 안에 목록 리스트인 ${boardlist} 를 써서 하나씩 글을 가져오기

- forEach 루프가 돌아갈때마다 num 을 1씩 감소시키기, 이때 코어 라이브러리 set 태그 사용해서 재정의 하는 방식

			<td>${num}
				<c:set var="num" value="${num-1}"
			</td>

- 등록일은 국제화 라이브러리 formatDate 태그로 패턴지정해서 적용

- 제목을 클릭하면 상세페이지로 가기 위해 "boardcontent.do" 로 요청하고 글번호 no, 페이지 번호 page 전달

- table 태그 아래에는 페이지 처리를 하고 있음, 자주 했으므로 설명 생략

 

+ Recent posts