최근 국비학원에서 쿠키에 대한 내용을 들어갔다.
jdbc에 들어간 지 며칠 된 것 같지도 않은데 정말 빠르게 느껴진다.
강사님도 jdbc로 홈페이지를 만들때 파라미터의 이동이 익숙지 않다는 것을
고려하셔서 최근은 비슷한 주제로 무한반복해서 만들게 하신 결과
어느 정도 파라미터의 이동에 익숙해져 잊기 전에 정리해보려고 한다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="member.*" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<% request.setCharacterEncoding("UTF-8"); %>
<c:set var="cpath" value="${pageContext.request.contextPath }" />
<c:set var="dao" value="${MemberDAO.getInstance() }" />
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>day08_member</title>
</head>
<body>
<header>
<h1><a href="${cpath }">day08_member</a></h1>
<div>DB : ${dao.test() }</div>
<nav>
<ul>
<li><a href="${cpath }/list.jsp">전체목록</a></li>
<li><a href="${cpath }/add.jsp">추가(가입)</a></li>
</ul>
</nav>
</header>
<hr>
///////////////////////////////////header.jsp /////////////////////////////////
우선 header이다. 이 파일은 모든 jsp코드에서 공통적으로 사용될 수 있는 코드를 미리 입력해 놨다가
<%@ include file = "header.jsp" %> 이런 식으로 불러올 수 있다.
즉 위와 같이 써놓으면 jstl과 import, dao의 instance를 매번 불러올 필요가 없어진다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="header.jsp" %>
<c:set var="list" value="${dao.selectAll() }" />
<%-- <h3>dao : ${dao }</h3> --%>
<%-- <h3>list : ${list }</h3> --%>
<table>
<thead>
<tr>
<th>IDX</th>
<th>USERID</th>
<th>USERPW</th>
<th>UESRNAME</th>
<th>BIRTH</th>
<th>EMAIL</th>
<th>GENDER</th>
<th>AGE</th>
</tr>
</thead>
<tbody>
<c:forEach var="dto" items="${list }">
<tr>
<td>${dto.idx }</td>
<td><a href="${cpath }/view.jsp?idx=${dto.idx}">${dto.userid }</a></td>
<td>${dto.userpw }</td>
<td>${dto.username }</td>
<td>${dto.birth }</td>
<td>${dto.email }</td>
<td>${dto.gender }</td>
<td>${dto.age }</td>
</tr>
</c:forEach>
</tbody>
</table>
</body>
</html>
///////////////////////////////list.jsp ////////////////////////////////////////////////////
이번에는 list.jsp이다. 이건 DAO에 있는 selectAll이라는 함수를 사용하여 DB에 있는 모든
데이터를 불러오는 부분이다. 코드를 보면
c:set으로 변수명은 list, 값은 dao의 SelectAll함수에서 가져온 모든 값이다.
그것을 <c:forEach>로 객체이름은 dto, 값은 변수 list를 넣어 모든 값을 순서대로 불러온다.
그리고 cpath라는 부분이 있을 건데 이건 header에 있던 <c:set var="cpath" value="${pageContext.request.contextPath }" />
이 분인데 값과 경로를 같이 지정할 수 있는 기능이다.
즉 a태그로 위와 같이 걸어두면 idx의 값과 함께 페이지도 이동하게 된다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="header.jsp" %>
<c:set var="dto" value="${dao.selectOne(param.idx) }" />
<%-- select * from member1 where idx = ? --%>
<h3>회원 정보</h3>
<ul>
<li>userid : ${dto.userid }</li>
<li>userpw : ********</li>
<li>username : ${dto.username }</li>
<li>birth : ${dto.birth }</li>
<li>email : ${dto.email }</li>
<li>gender : ${dto.gender }</li>
<li>age : ${dto.age }</li>
</ul>
<p>
<a href="${cpath }/modify.jsp?idx=${dto.idx}">수정</a>
<a href="${cpath }/delete.jsp?idx=${dto.idx}">삭제</a>
</p>
</body>
</html>
/////////////////////////////////////////view.jsp /////////////////////////////////////////////
이동을 하게 되면
<c:set>의 객체는 dto, 값은 list.jsp에서 cpath로 보낸 idx값은 param.idx를 사용하게 받을 수 있다.
받은 idx를 SelectOne함수로 보내서 찾은 값들을 dto에 넣고 불러오는 것이다.
여기서 중요한 점은 여러 idx의 값을 불러왔다면 무조건 forEach를 사용해야 하고
이렇게 하나의 idx와 일치하는 값들만 불러올 때만 하나씩 불러올 수 있다.
a태그는 위와 같이 idx값을 보내낸다.
delete는 생략하고 modify.jsp를 보도록 하겠다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="header.jsp" %>
<h3>정보 수정</h3>
<c:set var="dto" value="${dao.selectOne(param.idx) }" />
<form method="POST" action="modify-action.jsp">
<table>
<tr>
<td>ID</td>
<td><input type="text" name="userid" placeholder="ID" value="${dto.userid }" readonly></td>
</tr>
<tr>
<td>Password</td>
<td><input type="password" name="userpw" placeholder="Password" required></td>
</tr>
<tr>
<td>Name</td>
<td><input type="text" name="username" placeholder="Name" value="${dto.username }" required></td>
</tr>
<tr>
<td>생년월일</td>
<td><input type="date" name="birth" value="${dto.birth }" required></td>
</tr>
<tr>
<td>이메일</td>
<td><input type="email" name="email" placeholder="foo@bar.com" value="${dto.email }" required></td>
</tr>
<tr>
<td>성별</td>
<td>
<select name="gender" required>
<option value="">=== 성별 ===</option>
<option value="남성" ${dto.gender == '남성' ? 'selected' : '' }>남성</option>
<option value="여성" ${dto.gender == '여성' ? 'selected' : '' }>여성</option>
</select>
</td>
</tr>
<tr>
<td>나이</td>
<td><input type="number" name="age" min="1" max="120"
placeholder="나이" value="${dto.age }" required></td>
</tr>
</table>
<input type="submit" value="정보수정">
</form>
</body>
</html>
////////////////////////////////////////modify.jsp ///////////////////////////////////////
위 코드는 form을 사용하여 원하는 파일로 값을 보내려고 한다.
형식에 맞춰서 데이터를 입력하고 submit타입의 버튼을 클릭하면
값이 action에서 지정했던 파일로 넘어간다.
여기서 받은 idx값을 form태그에 묶어서 같이 보내기 위해서 input태그의 hidden을 이용하여 value에 ${param.idx}
이런 식으로 하여 input태그에서 idx값을 받아서 같이 보낼 수도 있다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="header.jsp" %>
<jsp:useBean id="dto" class="member.MemberDTO"></jsp:useBean>
<jsp:setProperty property="*" name="dto"/>
<c:set var="row" value="${dao.modify(dto) }" />
<c:if test="${row != 0 }">
<h3>수정 성공</h3>
<a href="${cpath }/list.jsp">목록으로</a>
</c:if>
<c:if test="${row == 0 }">
<h3>수정 실패</h3>
<a href="${cpath }/modify.jsp?idx=${param.idx}">다시 수정</a>
</c:if>
</body>
</html>
/////////////////////////////////////modify-action.jsp//////////////////////////////////////
값이 오면 그 값을 <jsp:useBean>을 사용하여 DTO로 좌표설정을 하고
모든 값들을 DTO로 보내버린다.
그렇게 만든 dto를 dao의 modify함수에 넣어서 값을 받는다.
여기서 중요한 점은 DAO에서도 나오는 내용이지만 update류의 액션은
반환값이 0 or 1을 반환한다.
public class MemberDAO {
private Connection conn;
private PreparedStatement pstmt;
private ResultSet rs;
private Context init;
private DataSource ds;
private static MemberDAO instance = new MemberDAO();
// 생성자 대신 객체를 받는 함수 작성 (객체가 없는 상태에서 객체를 받아야 하니 static으로 처리)
public static MemberDAO getInstance() {
return instance;
}
private MemberDAO() { // 외부에서 생성자를 호출 못하게 private으로 변경
try {
init = new InitialContext();
ds = (DataSource) init.lookup("java:comp/env/jdbc/oracle");
} catch (NamingException e) {
System.err.println("DAO 생성자 예외 발생 : " + e);
e.printStackTrace();
}
}
public String test() {
String banner = "";
String sql = "select banner from v$version";
try {
conn = ds.getConnection();
// stmt = conn.createStatement();
pstmt = conn.prepareStatement(sql); // 미리 준비한 SQL을 넣어서 pstmt를 받는다
// rs = stmt.executeQuery(sql);
rs = pstmt.executeQuery();
while(rs.next()) {
banner = rs.getString("banner");
}
} catch (SQLException e) {
System.err.println(getClass().getSimpleName() + " : " + e);
// e.printStackTrace();
} finally {
try { if(rs != null) rs.close(); } catch(Exception e) {}
try { if(pstmt != null) pstmt.close(); } catch(Exception e) {}
try { if(conn != null) conn.close(); } catch(Exception e) {}
}
return banner;
}
// rs를 전달받아서, MemberDTO 하나를 반환하는 함수 (내부에서만 사용)
private MemberDTO mapping(ResultSet rs) throws SQLException {
MemberDTO dto = new MemberDTO();
dto.setAge(rs.getInt("age"));
dto.setBirth(rs.getString("birth"));
dto.setEmail(rs.getString("email"));
dto.setGender(rs.getString("gender"));
dto.setIdx(rs.getInt("idx"));
dto.setUserid(rs.getString("userid"));
dto.setUsername(rs.getString("username"));
dto.setUserpw(rs.getString("userpw"));
return dto;
}
// 연결 해제 (내부 사용)
private void close() {
try { if(rs != null) rs.close(); } catch(Exception e) {}
try { if(pstmt != null) pstmt.close(); } catch(Exception e) {}
try { if(conn != null) conn.close(); } catch(Exception e) {}
}
// 전체 목록
public List<MemberDTO> selectAll() {
ArrayList<MemberDTO> list = new ArrayList<MemberDTO>();
String sql = "select * from member1 order by idx";
try {
conn = ds.getConnection();
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
while(rs.next()) {
MemberDTO dto = mapping(rs);
list.add(dto);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
close();
}
return list;
}
// 추가
public int insert(MemberDTO input) {
int row = 0;
String sql = "insert into member1 "
+ "(userid, userpw, username, birth, email, gender, age) "
+ " values (?, ?, ?, ?, ?, ?, ?)";
try {
conn = ds.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, input.getUserid()); // 'test'
pstmt.setString(2, input.getUserpw());
pstmt.setString(3, input.getUsername());
pstmt.setString(4, input.getBirth());
pstmt.setString(5, input.getEmail());
pstmt.setString(6, input.getGender());
pstmt.setInt(7, input.getAge()); // 25
row = pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally { close(); }
return row;
}
// idx로 단일 회원 조회하기
public MemberDTO selectOne(int idx) {
MemberDTO dto = null; // new MemberDTO();
String sql = "select * from member1 where idx=?";
try {
conn = ds.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, idx);
rs = pstmt.executeQuery();
if(rs.next()) {
dto = mapping(rs);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
close();
}
return dto;
}
// 삭제 함수
public int delete(int idx) {
int row = 0;
String sql = "delete member1 where idx=?";
try {
conn = ds.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, idx); // ? 개수만큼 값을 넣었는지 확인하자 !!
row = pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
close();
}
return row;
}
// 수정 함수
public int modify(MemberDTO dto) {
int row = 0;
String sql = "update member1 "
+ " set userpw=?, username=?, birth=?, email=?, gender=?, age=? "
+ " where userid=?";
try {
conn = ds.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, dto.getUserpw());
pstmt.setString(2, dto.getUsername());
pstmt.setString(3, dto.getBirth());
pstmt.setString(4, dto.getEmail());
pstmt.setString(5, dto.getGender());
pstmt.setInt(6, dto.getAge());
pstmt.setString(7, dto.getUserid());
row = pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally { close(); }
return row;
}
}
//////////////////////////////////////MemberDAO.java ////////////////////////////////////
여기서 중요한 점은 sql문에?로 표시되어 있는 건 pstmt(preparedStatement)로 받은 값들을? 에 넣어주기 위함이다.
그리고 executeupdate는 반환값으로 정수 1이나 0을 반환한다. (변경된 행의 개수)
executeQuery는 db에서 받은 값을 반환하는 함수이다.
공통적으로 쓰이는 코드는 메서드로 만들어 놨다가 필요할 때 불러올 수 있게 만들어 놓으면 코드가 깔끔해진다.
sql문에서 where을 이용하여 특정 값을 찾을 때는 매개변수를 통해서 값을 넣어주고
그런 조건이 없으면 dto로 보내서 한 번에 값을 찾아오면 된다.
insert같이 데이터를 받는 경우는 jsp파일에서 dto로 보내고 그 값을 매개변수에서 DTO로 받아서 사용한다.
오늘은 간단히 꽤 어렵게 느껴졌던 파라미터의 이동에 대해서 정리해 보았다.
조금 내용이 조잡한 것은 100% 이해가 다 된 건 아닌 것이 아닐까 생각이 든다.
현재 만들고 있는 홈페이지에서 조금 더 공부를 하여 다음에는 더 알기 쉽게 정리해 보도록 하겠다.
'JSP' 카테고리의 다른 글
JSP 파일입출력 (싱글톤내용) (0) | 2023.06.07 |
---|---|
JSP JSTL - 파라미터의 흐름 (0) | 2023.05.23 |
JSP기초 - 자바코드 페이지 출력방법 (0) | 2023.05.17 |