일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Oracle
- jsp 프로젝트
- 로그인과 장바구니 구현
- 코딩
- 스프링
- 다중 카테고리 구현
- jsp
- 인증코드로 비밀번호 변경 구현
- MySQL
- 세션
- 자바
- ajax
- jakarta.mail
- js
- Sts
- 이메일로 인증코드 전송 구현
- SESSION
- 오라클
- 고객센터 구현
- Spring MVC
- 프로그래머스
- 일단_해보는거야
- json
- MVC
- java
- 교보문고 따라하기
- jquery
- 대분류/중분류/소분류
- Level 1
- Spring
감 잃지말고 개발하기
[JSP][MVC][Session] 세션 및 로그인 도서 장바구니 구현하기 #2. DB 테이블 및 공통 클래스 설정 본문
세션 및 로그인 도서 장바구니 구현 두 번째 포스팅이다.
저번 포스팅에서는 교보문고 페이지를 살펴보면서 구현 방향을 정리해 보았다.
이번 포스팅에서는 본격적인 로직 구현에 앞서 이번 과정에 필요한 DB 테이블과 VO 클래스를 생성하고,
공통적으로 사용될 클래스를 정리해 보도록 하겠다.
목표
♠ 필요한 DB 테이블과 VO 클래스를 생성할 수 있다.
DB 테이블 생성 및 설정
ERD
세션 및 장바구니 구현을 위해 필요한 테이블의 관계도를 살펴보면 다음과 같다.
member, cart, book 테이블은 각각 회원, 장바구니, 도서의 정보를 저장한다.
cart 테이블의 칼럼 ca_m_id는 member 테이블의 m_id(PK)를, 칼럼 ca_b_id는 book 테이블의 b_id(PK)를 참조한다.
1. book 테이블
CREATE TABLE `book` (
`b_id` int NOT NULL AUTO_INCREMENT COMMENT '책 아이디',
`b_name` varchar(50) NOT NULL COMMENT '책 제목',
`b_writer` varchar(20) NOT NULL COMMENT '책 저자',
`b_translator` varchar(12) DEFAULT NULL COMMENT '책 옮긴이',
`b_publisher` varchar(15) NOT NULL COMMENT '책 출판사',
`b_catgy` varchar(12) NOT NULL COMMENT '책 분류',
`b_price` int NOT NULL COMMENT '책 가격',
`b_image` varchar(45) NOT NULL COMMENT '책 대표 이미지',
`b_page` bigint NOT NULL COMMENT '책 쪽수',
`b_publish_date` varchar(15) NOT NULL COMMENT '책 출판일',
`b_content` varchar(1000) DEFAULT NULL COMMENT '책 설명',
`b_readcount` int DEFAULT NULL COMMENT '조회수',
PRIMARY KEY (`b_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT=' '
2. cart 테이블
CREATE TABLE `cart` (
`ca_id` int NOT NULL AUTO_INCREMENT COMMENT '장바구니 아이디',
`ca_m_id` varchar(15) NOT NULL COMMENT '장바구니 회원 아이디',
`ca_b_id` int NOT NULL COMMENT '장바구니에 담은 도서 아이디',
`ca_b_qty` int NOT NULL COMMENT '장바구니에 담긴 도서 수량',
PRIMARY KEY (`ca_id`),
KEY `fk_c_b_id_idx` (`ca_b_id`),
KEY `fk_c_m_id_idx` (`ca_m_id`),
CONSTRAINT `fk_ca_b_id` FOREIGN KEY (`ca_b_id`) REFERENCES `book` (`b_id`),
CONSTRAINT `fk_ca_m_id` FOREIGN KEY (`ca_m_id`) REFERENCES `member` (`m_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='장바구니 테이블'
VO 클래스 생성
VO 클래스는 JSP 프로젝트에서 DB 테이블의 정보를 객체 타입으로 가져오기 위해 사용된다.
본 장바구니 구현 과정에서는 장바구니에 대한 VO 클래스만 있으면 된다.
장바구니 도서를 저장할 VO 클래스
해당 VO 클래스의 객체 하나는 사용자가 장바구니에 저장한 도서 한 권을 의미한다.
이 도서 한 권의 정보는 DB에서 book 테이블과 cart 테이블을 조인해 가져오기 때문에 해당 VO 클래스의 전역 변수에는 book 테이블 칼럼 및 cart 테이블 칼럼을 포함한다.
위의 DB book 테이블 이미지와 비교해 보면 이해가 빠를 것이다.
package vo;
/** 장바구니 도서 하나의 정보를 저장하는 클래스*/
public class Cart {
private int c_id; // 장바구니 아이디
private int c_b_id; // 책 아이디
private String c_b_name; // 책 제목
private String c_b_image; // 책 대표 이미지
private String c_b_catgy; // 책 분류
private int c_b_price; // 책 가격
private int c_b_qty; // 책 수량
private String c_m_id; // 회원 아이디
public Cart(int c_id, int c_b_id, String c_b_name, String c_b_image,
String c_b_catgy, int c_b_price, int c_b_qty, String c_m_id) {
super();
this.c_id = c_id;
this.c_b_id = c_b_id;
this.c_b_name = c_b_name;
this.c_b_image = c_b_image;
this.c_b_catgy = c_b_catgy;
this.c_b_price = c_b_price;
this.c_b_qty = c_b_qty;
this.c_m_id = c_m_id;
}
public Cart() {
// TODO Auto-generated constructor stub
}
// alt shift s + r (모든 전역변수에 대해 Getter, Setter 생성)
public int getC_id() {
return c_id;
}
public void setC_id(int c_id) {
this.c_id = c_id;
}
public int getC_b_id() {
return c_b_id;
}
public void setC_b_id(int c_b_id) {
this.c_b_id = c_b_id;
}
// 이하 생략
// 확인용을 위해 오버라이딩
@Override
public String toString() {
return "Cart [c_id=" + c_id + ", c_b_id=" + c_b_id + ", c_b_name=" + c_b_name
+ ", c_b_image=" + c_b_image + ", c_b_catgy=" + c_b_catgy + ", c_b_price="
+ c_b_price + ", c_b_qty=" + c_b_qty + ", c_m_id=" + c_m_id + "]";
}
}
공통으로 사용할 클래스 생성
세션을 확인하는 클래스
이번 구현에서는 요청된 URL을 처리할 때마다 세션을 사용하기 때문에 세션을 확인하는 메서드를 포함하는 클래스를 따로 생성해 주었다.
로그인 관련 세션 속성에는 isLogin과 userId가 있다.
장바구니 관련 세션 속성에는 cartList가 있다. 이 속성은 ArrayList<Cart> 타입으로 저장된다.
1. isLogined() 메서드
해당 메서드는 세션에서 로그인 관련 속성을 확인하여 그에 따른 결과값을 int형으로 반환한다.
로그인이 되어있으면 1을, 로그인이 되어 있지 않으면 0을, 세션이 NULL인 경우엔 -1을 리턴한다.
session = req.getSession(false);
위 코드로 인해 전역 변수 session에 가장 최근이 세션 객체가 저장되거나 NULL이 저장된다.
로그인 상태 유무를 확인하는 세션 속성 isLogin과 userId는 로그인을 처리하는 서버 딴에서 로그인에 성공했을 때 생성되는 속성들이다.
때문에 만약 속성 isLogin과 userID이 존재하지 않으면 로그인되지 않은 걸로 간주한다.
isLogin에는 boolean값이, userId에는 String형의 사용자 아이디가 저장된다.
2. isCartExist() 메서드
해당 메서드는 세션에서 장바구니 속성을 확인하여 그에 따른 결과값을 int형으로 반환한다.
로그인 속성과 장바구니 속성의 존재 유무는 아래 5가지의 경우로 생각해볼 수 있다(사용자가 도서 사이트에 접속하고 나서의 액션을 생각해보면 이해하기 쉽다).
- 도서 사이트 URL을 요청한 후 도서를 장바구니에 추가하고 로그인한 경우
- 세션에 로그인 속성과 장바구니 속성이 존재하는 경우
- 즉 isLogin, userId, cartList 모두 존재
- 도서 사이트 URL을 요청한 후 바로 로그인한 경우
- 세션에 로그인 속성은 존재하지만 장바구니 속성이 존재하지 않은 경우
- 즉 isLogin, userId 존재하지만 cartList 존재 X
- 도서 사이트 URL을 요청한 후 로그인하지 않은 상태에서 도서를 장바구니에 추가한 경우
- 세션에 로그인 속성은 존재하지 않지만 장바구니 속성이 존재하는 경우
- 즉 isLogin, userId 존재하지 않지만 cartList 존재
- 도서 사이트 URL을 요청한 후 로그인도, 장바구니 추가도 하지 않은 경우
- 세션은 존재하지만 아무런 속성이 저장되어 있지 않은 경우
- 즉 isLogin, userId, cartList 모두 존재 X
- 도서 사이트에서 로그아웃을 한 경우
- 세션 X
위의 5가지 경우를 switch-case문에 적용해 그에 따른 int형 결과값을 리턴할 것이다.
경우 1이면 1을, 2면 2를 ... 리턴할 것이다.
boolean isCartListExist
isCartListExist 변수는 장바구니 속성이 존재하는지 판단하기 위해 사용한다.
위의 5가지 경우에서 알 수 있듯이 장바구니 속성이 세션에 존재하지 않을 수 있다.
그렇기 때문에 session.getAttributeNames() 메서드를 사용해 장바구니 속성 존재 여부를 확인한 후 해당 속성이 존재하면 isCartListExist에 true가 저장되도록 만들어준다.
switch-case문
switch 괄호 안에는 int형 변수가 들어오는데, 이 int형 값에는 isLogined() 메서드의 리턴값이 온다.
나중에 장바구니 목록을 가져오는 Action 클래스를 살펴보면 이해가 될 것이다.
즉 1, 0, -1의 값만 오게되므로 그에 따라 case문을 만들어 처리해 준다.
각각의 중첩 조건은 위의 5가지 경우를 비교하면서 생각해 보면 이해가 될 것이다.
package util;
import java.util.Enumeration;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/** 세션을 확인하는 메서드 */
public class SessionUtil {
private static HttpSession session;
/** 로그인 유무를 확인하는 메서드 */
public static int isLogined(HttpServletRequest req, HttpServletResponse resp) {
/** 구분
* 로그인 : 1
* 비로그인 : 0
* 세션 x(로그아웃) : -1
*/
int result = -1;
session = req.getSession(false);
if(session != null) {
if(session.getAttribute("isLogin") != null
&& (boolean)session.getAttribute("isLogin")
&& session.getAttribute("userId") != null) {
// isLogin 속성값이 true(로그인 상태)
result = 1;
} else {
result = 0;
}
}
return result;
}
/** 장바구니 속성을 확인하는 메서드 */
public static int isCartExist(int loginResult) {
boolean isCartListExist = false;
// 세션이 존재하는 경우 장바구니 속성 가져오기
if(session != null) {
Enumeration<String> AttributeNamesE = session.getAttributeNames();
while (AttributeNamesE.hasMoreElements()) {
String attributeName = (String) AttributeNamesE.nextElement();
if(attributeName.equals("cartList")) {
// 장바구니 속성이 존재하는 경우
isCartListExist = attributeName.equals("cartList");
}
}
}
/** 경우의 수
* 경우 1 세션에 로그인 속성과 장바구니 속성이 존재하는 경우
* 경우 2 세션에 로그인 속성은 존재하지만 장바구니 속성이 존재하지 않은 경우
* 경우 3 세션에 로그인 속성은 존재하지 않지만 장바구니 속성이 존재하는 경우
* 경우 4 세션은 존재하지만 아무런 속성이 저장되어 있지 않은 경우
* 경우 5 로그아웃한 경우(세션 X)
* */
switch (loginResult) {
case 1:
// 로그인 상태
if (isCartListExist) {
// 경우 1
return 1;
} else {
// 경우 2
return 2;
}
case 0:
// 비로그인 상태
if (isCartListExist) {
// 경우 3
return 3;
} else {
// 경우 4
return 4;
}
default:
// 세션이 존재하지 않는 상태(로그아웃)
// 경우 5
break;
}
return 5;
}
}
이렇게 구현을 위한 기본적인 설정이 끝났다.
이번 구현의 핵심은 위 SessionUtil 클래스(특히 장바구니 속성을 확인하는 isCartExist() 메서드)에 있으므로 로직 구현에 앞서 반드시 이해하고 넘어가야 한다.
이번 구현의 첫 번째 포스팅(구현 흐름 잡기)을 참고하면 이해가 더 수월해질 것이다.
다음 포스팅부터 본격적으로 로직을 구현해 보도록 하겠다.
끝.
'JSP > MVC' 카테고리의 다른 글
[JSP][MVC][MySQL] Select 박스 옵션에 따른 페이징 처리 구현하기 #1. 기본 설정 (0) | 2023.05.27 |
---|---|
[JSP][MVC][Session] 세션 및 로그인 도서 장바구니 구현하기 #7. 장바구니 수량 변경하기 (2탄) (0) | 2023.05.24 |
[JSP][MVC][Session] 세션 및 로그인 도서 장바구니 구현하기 #6. 장바구니 수량 변경하기 (1탄) (0) | 2023.05.24 |
[JSP][MVC][Session] 세션 및 로그인 도서 장바구니 구현하기 #1. 구현 방향 설정 (0) | 2023.05.19 |
[JSP][MVC][Session] 세션을 이용한 도서 장바구니 구현하기 #4. 장바구니 주문 구현하기(마지막) (0) | 2023.05.17 |
[JSP][MVC][Session] 세션을 이용한 도서 장바구니 구현하기 #3. 장바구니 목록 구현하기 (0) | 2023.05.16 |