52-1. DB설계
1. 정규화
함수종속성 x -> y : x는 결정자 y는 종속자(x는 Primary Key)
완전/부분 함수적 종속성(pk가 복합키일 경우)
- 부분 함수적 종속성 : y가 x의 전체가 아닌 일부분에도 함수적으로 종속됨
- 완전 함수적 종속성 : y가 x의 전체에 대해서만 함수적으로 종속
1정규화 : 모든 컬럼의 데이터가 원자값으로 이루어져야 한다.
2정규화 : 1정규화를 만족하고, 부분함수적 종속을 제거해서 완전함수적 종속 상태로 만드는 것
3정규화 : 2정규화를 만족하고, 이행적 함수종속을 제거하는 것
=> 정규화 시, INSERT, UPDATE, DELETE 비용이 줄어들 수 있지만,
SELECT 비용이 증가할 수 있다. ( JOIN이 많아짐 )
2. 테이블과 테이블간의 관계
1:1관계 - 식별관계 : 참조하는 컬럼을 다시 pk로 사용하는 경우
1:N관계 - 비 식별관계 : 참조하는 컬럼을 식별자(pk)로 사용하지 않는 경우
* 대부분의 경우 1:N관계로 만들어진다.
N:M관계 - 1:N, M: 1 관계로 풀어서 설계해야 함. 중간 테이블 필요.
* 찜하기, 좋아요, 구독하기, 장바구니 등
3. 테이블 설계
ERD cloud 사용
52-2. JSP
로그아웃
1. 로그아웃하면 보낼 경로(절대경로) 설정
menubar.jsp
<a href="/jsp/logout.me">로그아웃</a>
2. Controller 생성 (Mapping값 logout.me)
LogoutController.java(Servlet)
POST방식도 doGet메소드에 작성
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 로그아웃 요청에 대한 처리 => session을 만료시킨다(== 무효화한다)
// 무효화메소드 == invalidate() => session에서 제공하는 메소드
HttpSession session = request.getSession();
session.invalidate(); // 다날림
// 응답데이터 => sendRedirect방식
// index가 보여지게끔 => localhost:8001/jsp
// response.sendRedirect("/jsp");
// request.getContextPath()
// System.out.println(request.getContextPath());
response.sendRedirect(request.getContextPath());
}
request.getContextPath() ==> tomcat Server의 Path
3. Path값 변수 처리 후, 절대경로 바꿔주기
menubar.jsp
String contextPath = request.getContextPath();
<!-- <a href="/jsp/logout.me">로그아웃</a> -->
<a href="<%= contextPath %>/logout.me">로그아웃</a>
<!-- <form action="/jsp/login.me" method="post"> -->
<form action="<%= contextPath %>/login.me" method="post">
------------------------------------------------------------------------------
52-3. 회원가입
include는 내 하위 폴더에 있는 모든 jsp나 html에 있는 변수들을 쓸 수 있음. => Path경로/매핑값
1. 회원가입 페이지 만들기
memberEnrollForm.jsp
VS Code에서 jsp가 저장된 폴더를 불러와 화면 만들고 저장하면 Eclipse와 연동됨
<%@ include file="../common/menubar.jsp" %>
<!-- ../ : 상위폴더로 이동(view폴더로 이동) -->
<!-- include는 내 하위 폴더에 있는 모든 jsp나 html에 있는 변수들을 쓸 수 있음. => Path경로/매핑값 -->
<form id="enroll-form" action="<%= contextPath %>/insert.me" method="post">
http://localhost:8001/jsp/views/member/memberEnrollForm.jsp
http://ip주소:port번호(톰캣)/Server Path(식별값) /(WebContent) 폴더경로
2. 회원가입 버튼을 누르면 만들어둔 회원가입 페이지로 이동
menubar.jsp
<button type="button" onclick="enrollPage();">회원가입</button>
<script>
function enrollPage(){
// 페이지 이동
// localhost:8001/jsp/views/member.memberEnrollForm.jsp
// location.href = "<%= contextPath %>/views/member/memberEnrollForm.jsp";
// 웹 어플리케이션의 디렉토리 구조가 url에 노출됨 => 보안에 취약
// 단순한 정적인 페이지 요청이라고 하더라도 Servlet을 거쳐서 화면을 띄어줄 것!
// => url에 서블릿 매핑값만 노출되게끔
// localhost:8001/jsp/매핑값
location.href = '<%= contextPath %>/enrollForm.me';
}
</script>
3. menubar에서 부른 페이지 생성
member > controller > MemberEnrollFormController.java(Servlet)
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 회원가입 양식 띄어주기
// 서블릿에서 화면 응답을 해주는 방법이 두 가지
// 1. RequestDispatcher객체를 이용하는 방법(forwarding)
// 2. sendRedirect(url재요청 방식)
RequestDispatcher view = request.getRequestDispatcher("views/member/memberEnrollForm.jsp");
view.forward(request, response);
}
동적인 이벤트 발생 시 문제 => JavaScript에서 문제 발생 => F12 console창 열어서 확인
404 Error => 메시지를 읽어볼 것 => 매핑값 오타 / 경로 오타 / 파일명 오타
4. 사용자가 회원가입 진행 시 입력한 값을 다루어줄 Controller 생성
MemberinsertController.java(Servlet)
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// POST
// 1) 인코딩 설정
request.setCharacterEncoding("UTF-8");
// 회원가입이란?
// 2) request객체로부터 요청 시 전달값 뽑기
String userId = request.getParameter("userId"); // "필수입력"
String userPwd = request.getParameter("userPwd"); // "필수입력"
String userName = request.getParameter("userName"); // "필수입력"
String phone = request.getParameter("phone");
String email = request.getParameter("email");
String address = request.getParameter("address"); // 빈문자열이 들어갈 수 있음
String[] interestArr = request.getParameterValues("interest"); // null / ["소개팅", "아프기"]
// 소개팅, 아프기
// String.join("구분자", 배열명)
String interest = "";
if(interestArr != null) {
interest = String.join(",", interestArr);
}
// 데이터 가공 String 배열에 담던가, String형 list에 담던가, Member객체에 담던가
// 3) Member 객체에 담기(setter메소드이용)
Member m = new Member();
m.setUserId(userId);
m.setUserPwd(userPwd);
m.setUserName(userName);
m.setPhone(phone);
m.setEmail(email);
m.setAddress(address);
m.setInterest(interest);
// 4) 요청처리(Service단 메소드 호출)
int result = new MemberService().insertMember(m);
}
5. Controller가 호출한 Service 메소드 만들어주기
MemberService.java
public int inserMember(Member m) {
Connection conn = JDBCTemplate.getConnection();
int result = new MemberDao().insertMember(conn, m);
// 성공했다면 1 / 실패했으면 0
if(result > 0) {
JDBCTemplate.commit(conn);
} else {
JDBCTemplate.rollback(conn);
}
JDBCTemplate.close(conn);
return result;
}
6. Service가 호출한 DAO 메소드 만들어주기
MemberDao.java
public int insertMemeber(Connection conn, Member m) {
// INSERT문 => 처리된 행의 개수
int result = 0;
PreparedStatement pstmt = null;
String sql = prop.getProperty("insertMember");
try {
// pstmt 객체 생성(SQL문 미리 전달)
pstmt = conn.prepareStatement(sql);
// 위치홀더 채우기
pstmt.setString(1, m.getUserId());
pstmt.setString(2, m.getUserPwd());
pstmt.setString(3, m.getUserName());
pstmt.setString(4, m.getPhone());
pstmt.setString(5, m.getEmail());
pstmt.setString(6, m.getAddress());
pstmt.setString(7, m.getInterest());
// SQL문 실행 및 결과받기
// insert / update / delete => pstmt.executeUpdate();
result = pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCTemplate.close(pstmt);
}
// 결과 반환
return result;
}
7. Controller에서 Service에서 가져온 결과값으로 응답화면 지정
MemberinsertController.java
// 데이터 가공 String 배열에 담던가, String형 list에 담던가, Member객체에 담던가
// 3) Member 객체에 담기(setter메소드이용)
Member m = new Member();
m.setUserId(userId);
m.setUserPwd(userPwd);
m.setUserName(userName);
m.setPhone(phone);
m.setEmail(email);
m.setAddress(address);
m.setInterest(interest);
// 4) 요청처리(Service단 메소드 호출)
int result = new MemberService().insertMember(m);
// 5) 처리결과를 가지고 사용자가 보게 될 응답화면 지정
if(result > 0) { // 성공 => /jsp를 요청(index.jsp) => url재요청방식(sendRedirect)
HttpSession session = request.getSession(); // 원래 기획회의때 이런것까지 정해줘야함.. session으로 보낼건지 request로 보낼건지..
session.setAttribute("alertMsg", "회원가입에 성공했습니다.");
response.sendRedirect(request.getContextPath());
} else { // 실패 => 에러페이지로 포워딩
request.setAttribute("errorMsg", "회원가입에 실패했습니다.");
RequestDispatcher view = request.getRequestDispatcher("views/common/errorPage.jsp");
view.forward(request, response);
}
'WAS > WAS수업' 카테고리의 다른 글
#50. JSP/Servlet 회원(로그인) (0) | 2023.09.11 |
---|---|
#49. JSP/Servlet 종합(JDBC연계) (1) | 2023.09.08 |
#48. Servlet (POST방식) / JSP / error시 띄어줄 페이지만들기 (0) | 2023.09.07 |
#47. Servlet (Get방식) (1) | 2023.09.06 |