✓ 흐름
① 드라이버 로드: 데이터베이스 연결을 위해 해당 데이터베이스 JDBC 드라이버 로드
② 연결 생성: 클래스를 이용하여 데이터베이스 연결 객체(Connection)생성(이때, 연결 정보를 지정)
③ Statement 생성: Connection 객체를 이용해, SQL문 실행을 위한 Statement 객체 생성
④ SQL문 실행: Statement 객체를 이용해 SQL문을 실행, 결과를 ResultSet 객체로 받아옴
⑤ 결과 처리: ResultSet 객체를 이용하여 SQL 실행 결과를 처리
⑥ 자원 반환: 모든 작업이 완료되면 사용한 자원(Connection, Statement, ResultSet 등)을 반드시 반환
(메모리 누수 방지, 다른 프로그램에서 해당 자원 접근 가능)
✓ 객체 생성
데이터베이스의 테이블과 1:1로 매핑되는 Java클래스들 정의: 생성자, gettet/setter, toString ...
✓ Servlet
- Service와 View 계층 사이에서 동작.
- HTTP 요청을 받아 분석하여 요청에 맞는 Service 메서드를 호출한다. Service 계층에서는 데이터베이스와의 연동 작업을 수행하고, 그 결과를 Servlet으로 반환한다.
- 즉, HTTP 요청에 대한 처리를 담당하고 데이터베이스와의 연동작업을 수행하는 등 비즈니스 로직을 처리한다. (View 계층에서는 데이터를 화면에 표시하는 등 UI 처리 담당)
package edu.kh.jsp.student.controller;
import java.io.IOException;
import java.util.List;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import edu.kh.jsp.student.model.service.StudentService;
import edu.kh.jsp.student.model.vo.Student;
//------------------------------------------
@WebServlet("/student/selectDepartment")
// 이 클래스를 Servlet으로 사용하기 위해 url패턴 매핑
public class SelectDepartmentServlet extends HttpServlet{
// HTTPServlet 클래스를 상속받아 SelectDepartmentServlet클래스 정의
// 상속받는 이유?
// Serlvet API를 사용하는 웹 애플리케이션에서 HTTP프로토콜을 사용하는 요청(request)과 응답(response)에
// 대한 처리를 담당하기 위해서이며, 상속 시 HTTP 요청을 처리하기 위해 사용할 수 있는 다양한 메서드를 제공받음.
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// HTTP Get요청을 처리하기 위해 doGet() 메서드를 오버라이딩
StudentService service = new StudentService();
// 비즈니스 로직을 수행하기 위해 해당 객체 생성 후 객체의 매서드 호출
try {
String inputDept = req.getParameter("inputDept");
// inputDept 변수에 HTTP에서 가져온 파라미터 값 대입
List<Student> stdList = service.selectDepartment(inputDept);
// 학생 전체 조회 서비스 호출 후 결과 반환받기
req.setAttribute("stdList", stdList);
// 조회 결과 request에 세팅
RequestDispatcher dispatcher = req.getRequestDispatcher("/WEB-INF/views/student/selectDepartment.jsp");
// "/WEB~" 페이지로 RequestDispatcher 객체 생성
dispatcher.forward(req, resp);
// 현재 요청 객체와 응답 객체를 "/WEB~" 페이지로 전달
} catch(Exception e) {
e.printStackTrace();
}
}
}
* RequestDispatcher
- Servlet에서 다른 Servlet, JSP, HTML 등의 자원으로 제어권을 넘기는 기능 제공.
- 현재의 요청과 응답 객체를 다른 자원으로 전달하여 해당 자원에서 요청을 처리하고 응답을 생성
- 사용 메서드
º foward(): 현재의 요청과 응답 객체를 다른 자원으로 전달. 다른 자원에서 처리된 결과를 클라이언트에 반환.
º include(): 현재의 요청과 응답 객체를 다른 자원으로 전달. 다른 자원에서 생성된 응답을 현재의 응답에 포함.
- 예를 들어, JSP파일에서 데이터베이스에서 조회한 결과를 출력하고자 한다면, 서블릿에서 데이터베이스 조회를 수행하고 JSP파일로 제어권을 전달할 수 있다. 이때, forward() 메서드를 사용하여 JSP파일로 요청과 응답 객체를 전달하면, JSP파일에서는 전달받은 데이터를 출력하여 클라이언트에게 응답한다.
② 연결 생성 ~ ⑥ 자원 반환
- DriverManager 혹은 Connection 인터페이스를 사용하여 데이터베이스와 연결
- Service: 비즈니스 로직(데이터 가공, 트랜잭션 제어) 처리를 하며, 실제 프로그램이 제공하는 기능을 모아놓은 클래스
- 하나의 Service 메서드에서 n개의 DAO 메서드(SQL실행)를 호출하여 이를 하나의 트랜잭션 단위로 처리해 한 번에 commit, rollback 을 수행할 수 있다.
package edu.kh.jsp.student.model.service;
import java.sql.Connection;
import java.util.List;
import static edu.kh.jsp.common.JDBCTemplate.*;
import edu.kh.jsp.student.model.dao.StudentDAO;
import edu.kh.jsp.student.model.vo.Student;
// ----------------------------------------------
public class StudentService {
// DAO 메서드 사용 위한 객체 생성
private StudentDAO dao = new StudentDAO();
// SELECT Department를 수행하기 위한 메서드
public List<Student> selectDepartment(String inputDept) throws Exception{
// 커넥션 생성
Connection conn = getConnection();
List<Student> stdList = dao.selectDepartment(conn, inputDept);
// DAO 메서드를 호출하여 수행 후 결과를 반환 받음.
// → Service에서 생성한 Connection 객체를 반드시 같이 전달
// 만약 DAO에서 DML구문을 실행한다면 여기서 트랜잭션 제어
// if(result > 0) commit(conn);
// else rollback(conn);
close(conn);
return stdList;
}
}
③ Statement 생성
- DAO(Data Access Object): 데이터가 저장된 DB에 접근하는 객체로 SQL문 실행 및 결과를 반환 받는 기능 수행
package edu.kh.jsp.student.model.dao;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import static edu.kh.jsp.common.JDBCTemplate.*;
import edu.kh.jsp.student.model.vo.Student;
// ------------------------------------------
public class StudentDAO {
// JDBC 객체를 참조하기 위한 참조변수 선언
private Statement stmt; // 빈 SQL
private PreparedStatement pstmt; // SQL문이 저장되어있음
private ResultSet rs; // 결과를 반환받음
private Properties prop;
// XML로 SQL을 다룰 것 → Properties 객체 사용
// Properties 객체
// key:value 쌍으로 이루어진 데이터를 관리하기 위한 클래스
// Property 파일에 저장되어 있는 설정 정보를 읽어와서 처리할 때 많이 사용
public StudentDAO() {
// StudentDAO 객체 생성 시 해당 쿼리 내용을 읽어와 Properties 객체에 저장
try {
String filePath
= StudentDAO.class.getResource("/edu/kh/jsp/sql/student-sql.xml").getPath();
prop = new Properties();
prop.loadFromXML(new FileInputStream(filePath));
}catch(Exception e) {
e.printStackTrace();
}
}
/** selectDepartment SQL실행 매서드
* @param conn
* @return
*/
public List<Student> selectDepartment(Connection conn, String inputDept) throws Exception{
// 결과 저장용 변수 선언
List<Student> stdList = new ArrayList<>();
try {
// student-sql.xml애 작성된 SQL 얻어오기(prop이 저장하고 있음)
// "entry key 값"
String sql = prop.getProperty("selectDepartment");
// prepareStatement 객체 생성
pstmt = conn.prepareStatement(sql);
// 위치 홀더(?)에 알맞은 값 세팅
pstmt.setString(1, inputDept);
/* 실행할 SQL문
<entry key="selectDepartment">
SELECT STUDENT_NO, STUDENT_NAME, STUDENT_ADDRESS, DEPARTMENT_NAME
FROM TB_STUDENT
JOIN TB_DEPARTMENT USING(DEPARTMENT_NO)
WHERE DEPARTMENT_NAME = ?
</entry>
*/
// SQL 실행 후 결과 반환 받음
rs = pstmt.executeQuery();
// 만약, DML을 수행하는 결과라면
//result = pstmt.excuteUpdate();
// next(): ResultSet 객체 메서드로 DB에서 조회한 결과 데이터를 가지고 있으며,
// 이 객체에서 다음으로 이동하며 데이터를 가져오기 위해 사용됨.
while(rs.next()) {
String studentNo = rs.getString("STUDENT_NO");
String studentName = rs.getString("STUDENT_NAME");
String studentAddress = rs.getString("STUDENT_ADDRESS");
String departmentName = rs.getString("DEPARTMENT_NAME");
// 결과로 받을 List에 추가
stdList.add(
new Student(studentNo, studentName, studentAddress, departmentName )
);
}
} finally {
// 사용한 JDBC 객체 자원 반환
close(rs);
close(pstmt);
}
return stdList;
}
}
'Sever' 카테고리의 다른 글
6. 이메일 중복 검사 및 인증번호 이메일 보내기 기능 구현하기 (0) | 2023.04.05 |
---|---|
5. 로그인 기능 구현하기 (1) | 2023.04.05 |
3. JDBC의 흐름 및 JDBC Tamplate (0) | 2023.04.04 |
2. JSP? + AJAX? (0) | 2023.03.28 |
1. Sevlet? (0) | 2023.03.27 |