<loginProcAjax.jsp>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import = "com.icia.web.model.User" %>
<%@ page import = "com.icia.web.dao.UserDao" %>
<%
String userId = request.getParameter("userId");
String userPwd = request.getParameter("userPwd");
//정상 파라미터를 받았을 때
UserDao userDao = new UserDao();
User user = userDao.userSelect(userId);
if(user != null)
{
if(user.getStatus().equals("Y"))
{
if(user.getUserPwd().equals(userPwd))
{
response.getWriter().write("{\"flag\": 0}");
}
else
{
//비밀번호 불일치
response.getWriter().write("{\"flag\": -1}");
}
}
else
{
//정지된 사용자
response.getWriter().write("{\"flag\": -2}");
}
}
else
{
response.getWriter().write("{\"flag\": -100}");
}
%>
다른 패키지의 클래스를 사용하기 위해 import 시켜준다.
<%@ %>이것은 임포트 하기 위한 JSP 문법임
- User파일 : private 인스턴스 변수 선언
- UserDao파일 : 각 서비스 별로 메소드 구현
- index.jsp 서버는 있지만 실제 페이지는 브라우저에 있다. 그래서 브라우저에서 로그인을 누를 때 서버를 호출하게 되는 것이다. 그리고 index.jsp 화면에서 클라이언트로부터 입력 받은 아이디와 비밀번호가 파라미터 값으로 서버쪽으로 넘어가게 된다.
- 이렇게 아이디와 비밀번호를 받으면, UserDao/User객체에서 결과값을 알려준다. 이것으로 알 수 있는 것은 loinProcAjax.jsp가 index.jsp와 User, UserDao를 연결해 주는 역할을 한다는 점이다.
- request 객체는 자바에서 제공을 하고 있다.
- getParameter() 이 메소드의 기능은 자동으로 괄호 안의 값을 읽는다.
-- 사용자 조회 서비스를 콜하게 되는 것이다.
-- 유저 셀렉트 메소드
자바에서는 static이 아닌 이상 객체 생성을 해야 사용할 수 있다.
9번 - UserDao 클래스를 사용하기 위해서 객체 생성을 한다.
10번 - User도 마찬가지이다. 컨트롤을 눌러서 가보면? userSelect() 메소드의 리턴타입이 user 객체라서 new로 별도의 객체 생성을 해주기 보다는 이것이 그대로 객체 생성을 해주게 되는 것!
이걸 위에서 한 줄로 줄인 거임
UserDao의 결과를 User에 받아준다.
Status는 회원정보가 차단인지 아닌지 구별하는 부분이다.
"Y"는 정상적인 사용자 / "N"은 블랙리스트 및 비정상 사용자
패스워드의 값도 같다면 사용자에게 응답으로 flag: 0을 줌(로그인 성공)
0 : 로그인 성공
-1 : 비밀번호 불일치
-2 : 사용이 정지된 사용자
-3 : 아이디와 일치하는 사용자가 없음
-100 : 파라미터 값이 잘 못 전달 됨
플래그 값은 index.jsp => ajax에서 설정함
여기서 다른 파일부터 분석을 해보자 . . .
<User.java>
어려워보이지만 별 거 없는 파일이다.
DB에서 가져오는 회원 정보를 JSP 서버에서 다룰 수 있도록 도와주는 역할을 한다.
package com.icia.web.model;
import java.io.Serializable;
public class User implements Serializable
{
private static final long serialVersionUID = 1L;
//유저 값을 변경하는 것은 은닉화 해야한다.
private String userId;
private String userPwd;
private String userName;
private String userEmail;
private String status; //상태(사용: Y, 정지: N)
private String regDate;
public User()
{
userId = "";
userPwd = "";
userName = "";
userEmail = "";
status = "";
regDate = "";
//초기화
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserPwd() {
return userPwd;
}
public void setUserPwd(String userPwd) {
this.userPwd = userPwd;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserEmail() {
return userEmail;
}
public void setUserEmail(String userEmail) {
this.userEmail = userEmail;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getRegDate() {
return regDate;
}
public void setRegDate(String regDate) {
this.regDate = regDate;
}
}
단, User.java를 만들기 전에 기본적으로 테이블 추가(TBL_USER)를 해야한다.
Serializable 인터페이스를 상속 받은 User 클래스 (import 필요)
여기서 Serializable는 직렬화 라고 한다.
시리얼라이저블을 사용하는 이유?
결국 아래 줄을 사용하기 위함이다.
private static final long serialVersionUID = 1L;
개발자가 신경 안 써도 되는 부분이라고 한다...(이러면 더 궁금함)... 자바 내부적으로 JVM을 사용하기 위해서 적어주는 부분이다.
상속 받은 후 에러가 뜨면 마우스를 올려본다.
변수를 자동 추가 할 수 있음!
자바 내에서 알아서 싱크를 맞추겠다는 말임. 컴파일하면 알아서 JVM가 이곳에 싱크를 넣어준다.
객체 직렬화
서버간의 데이터 이동을 의미한다. User.java가 데이터를 담아서 보내는 역할을 하기 때문에 이 안에서 사용을 하는 것이다. 데이터를 보낼 때 바이트 코드로 바꿔서 다른 서버로 넘긴다. 그럼 받을 때 변수를 보고 '아~ 얘구나~' 이런 식으로 구분하기 위함이라고 한다... 설명을 들어도 모르겠음^^
--Serializable 용어 설명--
[Java] 직렬화(Serialization)란 무엇일까?
Serializable에 대해서 알아보기 직렬화라는 용어에 대해서 들어만 보고 공부해본 적은 없는데 이번 기회에 정리를 하게 되었습니다,, 이번 글에서는 직렬화 에 대해서 알아보겠습니다. public interfac
devlog-wjdrbs96.tistory.com
- DB에 담긴 정보가 노출되지 않게 하려면 private 접근지정자를 설정해야하고, 그 아래에 getter/setter Generater
- 인스턴스 변수는 DB 컬럼명과 타입이 같아야한다.
- DB에서 VARCHAR2 문자형 타입으로 만들었으니 모두 String 타입으로 받아온다.
- regDate(가입일)의 경우 SYSDATE이지만 페이지에서 보여 줄 때 Java에서는 String타입으로 보여줘야 한다. 즉, DB에서 toChar()로 넘겨 받아야한다는 뜻이다. 여기서 알 수 있는 건 Oracle에서 문자 타입들은 Java에서 무조건 String 타입으로 넘겨 받아야 한다.
- 이렇게 변수를 만들어주면 각각의 회원 정보들이 DB와 동일하게 담길 수 있다.
- 객체지향으로 넘겨 받아야하기 때문에 이제부터 인스턴스 변수들을 모두 private으로 넘겨 받아야한다. 그래서 해당 인스턴스 변수들에 접근할 때는 해당 메소드(get/set)를 통해서만 담을 수 있다.
<UserDao.java>
DAO => 데이터베이스 접근의 약자이다.
- 실질적으로 데이터베이스에 접근을 해서 회원 정보를 불러오거나 DB에 정보를 넣을 때 사용
- 모든 sql문은 dao 패키지에 값을 담아서 이동하는 수단으로 사용한다.
package com.icia.web.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.icia.web.db.DBManager;
import com.icia.web.model.User;
public class UserDao
{
private static Logger logger = LogManager.getLogger(UserDao.class);
public UserDao()
{
}
//사용자 id 체크
public int userIdSelectCount(String userId)
{
int count = 0; //존재 여부 확인하기 위한 변수
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
StringBuilder sql = new StringBuilder();
sql.append("SELECT COUNT(USER_ID) AS CNT "); //반드시 띄어쓰기
sql.append(" FROM TBL_USER ");
sql.append(" WHERE USER_ID = ? ");
try
{
conn = DBManager.getConnection();
pstmt = conn.prepareStatement(sql.toString());
pstmt.setString(1, userId); //0부터 아님
rs = pstmt.executeQuery();
if(rs.next()) //next() 첫번째 레코드값을 읽어 온다.
{
count = rs.getInt("CNT");
}
}
catch(Exception e)
{
logger.error("[UserDao] userIdSelectCount Exception", e);
//log4j를 이용한 출력
}
finally
{
DBManager.close(rs, pstmt, conn);
}
return count;
}
//사용자 조회
public User userSelect(String userId)
//객체 하나만 넘어가는 거임
//모델 클릭
{
User user = null;
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
StringBuilder sql = new StringBuilder();
sql.append("SELECT ");
sql.append(" USER_ID, ");
sql.append(" NVL(USER_PWD, '') AS USER_PWD, ");
sql.append(" NVL(USER_NAME, '') AS USER_NAME, ");
sql.append(" NVL(USER_EMAIL, '') AS USER_EMAIL, ");
sql.append(" NVL(STATUS, '') AS STATUS, ");
sql.append(" NVL(TO_CHAR(REG_DATE, 'YYYY.MM.DD HH24:MI:SS'), '') AS REG_DATE ");
sql.append(" FROM ");
sql.append(" TBL_USER ");
sql.append(" WHERE USER_ID = ? ");
try
{
conn = DBManager.getConnection();
pstmt = conn.prepareStatement(sql.toString());
pstmt.setString(1, userId); //0부터 아님
rs = pstmt.executeQuery();
if(rs.next()) //next() 첫번째 레코드값을 읽어 온다.
{
user = new User();
user.setUserId(rs.getString("USER_ID")); //세터메소드를 이용해서 하나씩 넣어줌
user.setUserPwd(rs.getString("USER_PWD"));
user.setUserName(rs.getString("USER_NAME"));
user.setUserEmail(rs.getString("USER_EMAIL"));
user.setStatus(rs.getString("STATUS"));
user.setRegDate(rs.getString("REG_DATE"));
}
}
catch(Exception e)
{
logger.error("[UserDao] userIdSelectCount Exception", e);
}
finally
{
DBManager.close(rs, pstmt, conn);
}
return user;
}
//회원정보 삽입
public int userInsert(User user)
{
//리턴타입을 pstmt 날리고 나서 카운트로 받을 거임
int count = 0;
Connection conn = null;
PreparedStatement pstmt = null;
StringBuilder sql = new StringBuilder();
sql.append("INSERT INTO TBL_USER ");
sql.append(" (USER_ID, USER_PWD, USER_NAME,USER_EMAIL, STATUS, REG_DATE ) ");
sql.append("VALUES (?, ?, ?, ?, ?, SYSDATE) ");
try
{
int idx = 0;
conn = DBManager.getConnection();
pstmt = conn.prepareStatement(sql.toString());
//pstmt.setString(4, "Y"); //이렇게 넣어 줄 수도 있음
pstmt.setString(++idx, user.getUserId());
//1부터 시작을 해야 돼서 전치 증가 연산자
pstmt.setString(++idx, user.getUserPwd());
pstmt.setString(++idx, user.getUserName());
pstmt.setString(++idx, user.getUserEmail());
pstmt.setString(++idx, user.getStatus());
count = pstmt.executeUpdate();
}
catch(Exception e)
{
logger.error("[UserDao] userInsert SQLException", e);
}
finally
{
DBManager.close(pstmt, conn);
}
return count;
}
}
- log4j를 사용하기 위해서 객체 생성을 해주는 모습이다.
- System.out.print의 단점을 보완한 로그 출력용이다.
- 위에서 import 시켜야 log4j 사용할 수 있다.
System.out.println이 아니라 log4j를 사용하는 이유
- log를 남기는 것 자체가 서버의 자원을 낭비하는 일이다. 동시 접속자 몇 천 만명이 들어 왔는데 그 로그가 모두 저장된다고 생각을 해보자 실제 서버가 뻗는 경우도 있다. 때문에 필요한 로그만 남길 수 있게 설정하는 것이 log4j이다.
- 여기서는 크게 차이를 못 느끼지만 실제로 사용할 때는 큰 차이가 있다.
- 개발서버에는 당연히 어떤 값이 넘어가는지 보여야 된다. 그러나 운영서버에 올라갔을 때는? 계속 되는 로그의 발자취가 서버에 과부하를 주게 되는 것이므로 아침마다 로그 지우는 게 일이기도 하다. 그래서 log4j의 경우 서버에서 print처럼 매 번 출력 되는 게 아니라 test할 때는 나오지만 운영서버에 올라갈 때는 로그의 레벨을 내가 결정할 수 있다. "여기는 출력해 여기는 하지만 여기는 어떻게 해~!" 이런 식으로 다 적용 가능하다.
logger.error("[UserDao] userIdSelectCount Exception", e);
여기서는 이렇게 사용이 된다.
-- 관련 정보는 아래 주소 참고 --
로그 라이브러리 (Log4j)
<!DOCTYPE html> log4j System.out.print 우리는 System.out.print로 우리는 로그를 출력하곤 합니다. 그래서, 로그를 많이 출력하게 되면 로그용 함수를 만들어서 보기 쉽게 만들어 주거나, 파일로 출력해서 나
jusunglee.tistory.com
Log4j의 정의, 개념, 설정, 사용법 정리
* Log4j 1에 대해서 가볍게 정리한 문서입니다. * Log4j 2는 일부 내용이 변경되었을 수 있습니다. * 요약 * Log4j 정의 Log4j 특징 Log4j 구조 Log4j 레벨 Log4j Pattern Option Log4j 주요 클래스 Log4j 설정..
cofs.tistory.com
userIdSelectCount() - 사용자의 id를 체크한다.
userSelect() - 사용자의 정보를 조회한다.
userInsert() - 회원의 정보를 가지고 와서 삽입한다 (가입)
각각의 메소드를 만들어준다.
아래의 conn, pstmt, rs 변수는 무조건 들어가야하니 외우자!
jdbc 드라이버를 이용해 테이블에 있는 정보들을 가지고 오려면
기본적으로 생성해야 하는 문장임
메소드들 안에서 DB연결 시 꼭 필요한 방을 생성해야 함
객체 생성은 안 하고 사용하기 위해서 방만 잡아 둔 것임
각 객체의 시작 주소값이 들어가는 변수명이다!
Connection conn = null;
Connection conn
DB 접근(연결)을 위한 객체
- connection 객체를 먼저 연결해서 사용한다.
PreparedStatement pstmt = null;
PreparedStatement pstmt
- WAS에서 DB로 요청시 쿼리에 담아 보낼 용도이다. 이곳에 SQL 문장을 담아서 보내준다.
- rs에서 받은 리턴값(쿼리)을 pstmt.executeQuery()을 통해 실행
- 매 실행시 컴파일을 해야하는 Statement와 다르 게 그것을 상속 받은 pstmt는 '?' 통해서 쿼리문에 인자를 사용할 수 있다. 매 번 컴파일 진행하지 않고 ? 부분을 변경해서 해당 객체를 재사용할 수 있는 뜻이다.
ResultSet rs = null;
ResultSet rs -->(Insert/Update 메소드에는 필요 없음!!)
어떠한 정보를 담을 수 있는 객체로 서버로부터 데이터를 얻을 때 반드시 사용한다. pstmt에서 DB로 정보를 담아 보냈을 때(SELECT) 해당 정보의 리턴값을 받는 데이터 타입으로 테이블 형태 그대로 갖고 있다.
이러한 객체들은 외부 라이브러리에서 제공을 해주는 거라서 아래처럼 import를 시켜주어야한다.
ctrl+shift+o 눌러서 외부라이브러리 자동 불러오기
. . . 그런데 여기서 잠깐!!
각 메소드를 살펴보면 특이한 점들이 보인다.
리턴타입이 하나만 다르다는 걸 볼 수 있다.
이 이유는 SELECT(userSelect)만 리턴 타입이 객체타입이기 때문이다.
그 외의 INSERT - DELETE - UPDATE시에는 int타입으로 받아준다.
쿼리를 StringBuffer를 이용하는 경우도 있지만 여기서는 StringBuilder를 이용했다.
자바에서 제공하는 타입 중 하나로 긴 문장들을 이어 붙이는 용도로 사용한다. 아래처럼!
특히 sql.append() 대신에 String을 이용하면 안 되는 이유는?
- 여기서 String을 쓰면 안 되는 이유는 String을 사용할 때마다 새로운 집을 할당 받게 된다. 여러 명령어를 처리하게 되면 과부하가 생기기 때문에 append를 사용하는 것이다. append는 문장을 붙이는 용도
- 앞뒤로 띄어쓰기를 해야 하는 것은 물론이고, 여러개의 칼럼을 가지고 올 때는 뒤에 쉼표를 넣어 줘야한다.
- 실제 데이터 베이스에 입력할 명령어를 적어주는 부분이다.
- 각 테이블의 값들을 불러오기(SELECT) 위해서 쓰는 부분임
-AS를 사용하는 이유는 아래에서 세터메소드를 가지고 올 때 AS로 지정한 이름을 넣어주기 위함이다.
- 이 쿼리문이 잘 못 됐을 경우에는 index.jsp 하단 부분의 ajax문에서 에러로 뜨게 된다.
- 43, 93 line : pstmt.executeQuery() 메소드로 resultSet의 값을 받고 나서 rs.next()를 통해서 값을 하나하나 읽을 때에는 getString 안에서 AS 이름이랑 일치해야한다.
try-catch로 꼭 감싸야 하는 이유
안에서 사용하려는 메소드들 중에서 트라이 캐치가 걸려 있다면 사용해줘야한다.
pstmt = conn.prepareStatement(sql.toString());
마우스를 올려 놓으면 메소드 예외처리가 걸려있는 걸 볼 수 있다. (throws SQLException)
메소드 예외처리란?
메소드 예외처리를 해야 하는데 사용할 메소드 안에는 예외처리가 아무것도 돼 있지 않을 때 받아서 쓰는 사용자 쪽에서 메소드 예외 처리를 구현해야 함. 만약 userSelect() 메소드를 호출하는 loginProcAjax.jsp에서 예외처리를 했다면 여기서 굳이 try-catch를 사용하지 않아도 된다. 던지고 받는 쪽에서 트라이 캐치를 한 경우에는 한쪽에서 처리를 하지 않아도 되는 공식이 있음. 그런데 메소드 쪽에서 하는 게 번거롭지 않다.
conn.prepareStatement() : 인수 값을 sql.toString()으로 넣어줘야 StringBuilder sql = new ... 에 저장된 값을 문자열로 가지고 올 수 있다. 이 메소드의 특징은 인수 값을 받아서 처리할 수 있다는 것이다. 쿼리문의 '?' 문장 안에다가 하나씩 대입할 수 있다. 그걸 대입하기 위해서는 아래의 pstmt.setString을 이용한다. 숫자의 경우는 setInt()가 따로 있음
pstmt.setString(1, userId);
(물음표 순서, 매개변수로 받아온 유저아이디값)
파라미터 값으로 유저 비밀번호도 받은 경우
sql.append로 USER_PWD도 같이 체크를 해주고,
아래에서 2, userPwd으로 매개 변수로 받은 값을 대입만 해주면 된다.
지금은 90,91번 순서가 바뀌어도 첫번째에서 순서가 적혀 있으니 상관 없다. 하지만 쿼리문에서 AND절이 많아지면 쉽지 않음. 게시판 만들 때에도 문제가 생기니까 순서를 지키는 게 좋다.
이 문장을 통해서 executeQuery() 메소드가 실질적으로 DB에게 쿼리를 날리고 그 결과를 rs으로 받는다. 쿼리에서 SELECT를 날리게 되면 결과가 나오게 되는데 그 값을 ResultSet이 갖고 온다고 보면 됨
- rs.getString() - rs에서 getString으로 받아 온다.
- 타입에 따라서 getXXX으로 설정 가능
conn = DBManager.getConnection() - DB의 접근(연결)을 위한 부분
< DBManager.java >
DB Connection(접근/연결) 파일이다. 이렇게 DBManager파일을 따로 만드는 이유는 코드의 재사용성 때문이다. 따로 파일로 만들어서 호출하는 방식으로 사용하지 않으면 모든 .java 파일에 집어 넣어야 하고, DB정보에서 localhost가 아니라 ipAdress로 바꾸어야 할 때 모든 파일들을 수정해야 하니까 번거로움이 있다.
package com.icia.web.db;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public final class DBManager
{
//jdbc 드라이버명
private static final String diverClassName = "oracle.jdbc.OracleDriver";
//jdbc url
private static final String jdbcUrl = "jdbc:oracle:thin:@localhost:1521:xe";
//계정
private static final String userName = "c##iciauser";
private static final String password = "1234";
//생성자
//없으면 자동으로 컴파일
private DBManager() {}
//데이터베이스 연결 객체 얻기
//Connection 구현
public static Connection getConnection()
{
Connection conn = null;
try
{
Class.forName(diverClassName);
conn = DriverManager.getConnection(jdbcUrl, userName, password);
}
catch(ClassNotFoundException e)
{
//콘솔로그에 찍기
System.out.println("[DBManager]getConnection ClassNotFoundException");
}
catch(SQLException e)
{
System.out.println("[DBManager]getConnection SQLException");
}
return conn;
}
//close() 메소드,
//ResultSet 닫기(select시에만 닫긔)
public static void close(ResultSet rs)
{
//오버로딩
close(rs, null, null);
}
//PreparedStatement 객체 닫기(status일 때 닫기)
public static void close(PreparedStatement pstmt)
{
close(null, pstmt, null);
}
//Connection 객체 닫기
public static void close(Connection conn)
{
close(null, null, conn);
}
//ResultSet, PreparedStatment 객체 닫기
public static void close(ResultSet rs, PreparedStatement pstmt)
{
close(rs, pstmt, null);
}
//PreparedStatment, Connection 객체 닫기
public static void close(PreparedStatement pstmt, Connection conn)
{
close(null, pstmt, conn);
}
//데이터베이스 객체 닫기
public static void close(ResultSet rs, PreparedStatement pstmt, Connection conn)
{
if(rs != null)
{
try
{
rs.close();
}
catch(SQLException e)
{
System.out.println("[DBManager]close ResultSet SQLException");
}
}
if(pstmt != null)
{
try
{
pstmt.close();
}
catch(SQLException e)
{
System.out.println("[DBManager]close PreparedStatement SQLException");
}
}
if(conn != null)
{
try
{
conn.close();
}
catch(SQLException e)
{
System.out.println("[DBManager]close Connection SQLException");
}
}
}
// commint 모드 변경
//자동인 경우 수동, 수동의 경우 자동으로 바꿈
public static void setAutoCommit(Connection conn, boolean flag) {
if (conn != null) {
try {
if (conn.getAutoCommit() != flag) {
conn.setAutoCommit(flag);
}
} catch (SQLException e) {
System.out.println("[DBManager]setAutoCommit SQLException");
}
}
}
//rollback
public static void rollback(Connection conn) {
if(conn!=null) {
try {
conn.rollback();
}
catch(SQLException e) {
System.out.println("[DBManager]rollback SQLException");
}
}
}
}
- final 클래스로 만들었으니 변수들도 상수형으로 만듦
- 상수형이라고 해서 꼭 이름을 대문자로 할 필요 없음
- 처음부터 클래스 생성할 때 final 찍고 만들어도 됨
diverClassName
- 드라이버 로딩할 때 쓸 값
jdbcUrl
- DB Connection할 때 쓸 값
- DB접속정보 바꾸라고 할 때 localhost 이 부분만 바꾸면 됨
- 포트번호는 팀마다 다름 : xw/ORCL(SID)
- 회사의 ipAdress는 똑같지만 컴퓨터 자리마다 포트번호가 다르다는 걸 생각 . . .
public static Connection getConnection() {}
객체 생성을 하지 않고 바로 쓸 수 있는 메소드
Connection conn = null; 방 생성
Class.forName(driverClassName);
Oracle 드라이버(ojdbc8)를 이용해서 메모리에 올리는 역할을 한다.
(driverClassName 여기에 있는 JDBC 드라이버를 메모리에 올림)
톰캣을 깔았을 때 lib폴더 밑에 설치한 이유가 이것 때문이다.
conn = DriverManager.getConnection(jdbcUrl, userName, password);
JDK에서 만든 객체와 클래스
위에서 메모리에 올려 놨다면 여기서 커넥션을 맺는다.
return conn;
커넥션 맺은 객체(시작주소값)를 넘겨 준다.
DB 연결 후에 객체 3가지를 닫아주어야 한다.
- ResultSet, PrepareStatement, Connection 객체 닫기
- 순서대로 닫아주어야 하며 null 값이 오는 경우도 있으니 모든 상황에 대비한다.
<UserDao.java>
다시 돌아와서 . . .
85번 - getConnection()으로 얻어 온 리턴 값 conn
user = new User() - 객체 생성
user.setUserXX() - user 객체에 있는 setUserXX들이 Private 메소드니까 값을 받고 넘겨 주는 것이 get/set이어야 함
Exception 대신에 SQLException 되지만 Exception은 예외처리 중에서도 가장 최상위를 의미한다. SQLException을 했다면 아래에서 또 Exception을 해야하니까 처음부터 해주는 게 좋다. "모든 처리는 여기서 해주마!" 약간 이런 뜻임
'개발일지 > JSP' 카테고리의 다른 글
[JSP] 쿠키(Cookie) (0) | 2021.11.29 |
---|---|
[JSP] DB연결 확인 (JDBC) (0) | 2021.11.27 |
[JSP] 로그인 화면 분석하기①(index.jsp) (0) | 2021.11.26 |
[JSP] 내부 객체 (기초) (0) | 2021.11.26 |
[JSP] 기초 정리 1 (0) | 2021.11.25 |