지금까지는 서블릿의 기초적인 기능들을 확인했는데요. 실제 웹 서비스에서 서블릿은 클라이언트의 요청을 받아서 작업을 처리합니다. 이 작업을 비지니스 처리 작업이라고 부르는데요. 대표적인 비지니스 처리 작업으로는 DB와 연동해서 DB의 데이터를 로직으로 처리하는 작업이 있습니다.
지난시간에 만들었던 로그인도 당연히 DB와 연동해서 실제로 구현하게 되는 것이고, 쇼핑몰 등의 상품 목록 등도 DB와 연동하여 작업하는 등 서블릿의 DB 연동은 핵심적인 기능이라고 말할 수 있습니다.
그래서 이번 포스트부터 시작해서 두 세개 정도의 포스트 동안은 서블릿과 DB를 연동하는 작업을 해보고 비지니스 로직을 처리해보도록 하겠습니다.
Windows 11, IntelliJ, Java 17, Tomcat 10, Oracle DB 환경에서 실습합니다.
서블릿이 DB와 연동하는 과정을 그림으로 나타내면 다음과 같습니다.
클라이언트가 요청을 하면 톰캣 컨테이너(WAS)를 통해 서블릿에 요청이 전달되고, 서블릿은 DAO, VO를 통해 DB에 접근하여 비지니스 로직을 처리하게 됩니다.
연동 과정을 알아봤으니 실습으로 진행해보겠습니다. Oracle DB를 켜고 다음과 같이 테이블을 하나 생성해주세요. 저는 cmd에서 작업을 하지만 SQL Developer 등의 RDBMS GUI를 사용해도 좋습니다.
CREATE TABLE member (
id VARCHAR2(10) primary key,
password VARCHAR2(30),
name VARCHAR2(50),
email VARCHAR2(50),
joinDate DATE default sysdate //유저 등록 시간, 입력하지 않으면 현재 시각 추가
);
VARCHAR
와VARCHAR2
의 기능적인 차이는 없습니다. 따라서 둘 중 아무거나 사용해도 됩니다.왜 여기서 VARCHAR2를 사용했냐면 VARCHAR는 추후에 다른 타입으로 변경될 수 있기 때문에 안정성을 위해 VARCHAR2를 사용했습니다.
그리고 예제용 데이터 두 개를 INSERT 구문으로 삽입합니다.
INSERT INTO member VALUES(
'kim1',
'1234',
'김자바',
'kim1@e.com',
sysdate
);
INSERT INTO member VALUES(
'lee1',
'5678',
'이서버',
'lee@nekao.com',
sysdate
);
COMMIT;
SELECT 구문으로 데이터가 잘 삽입되었나 확인해봅니다.
자바 서블릿 코드와 오라클 DB 연동을 위해 ojdbc를 연결해주세요.
전에 만든 프로젝트에 이어서 작성되었습니다. 이어서 해도 좋고 새 프로젝트나 패키지를 만들어서 진행해도 좋습니다.
이제 이 테이블을 조회(Read)하는 서블릿 코드를 작성하겠습니다.
프로젝트에 dbexample
이라는 새 프로젝트를 만들고 MemberServlet
이라는 클래스를 하나 생성한 후 다음과 같이 코드를 작성합니다.
package com.example.helloservlet.dbexample;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
@WebServlet("/member")
public class MemberServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
MemberDAO memberDAO = new MemberDAO();
List<MemberDAO> memberDAOList = memberDAO.listMembers();
out.print("<html><body>");
out.print("<table border=\"1\"><tr align=\"center\">");
out.print("<td>id</td><td>password</td><td>name</td><td>email</td><td>joinDate</td></tr>");
for (int i = 0; i < memberDAOList.size(); i++) {
MemberVO memberVO = memberDAOList.get(i);
String id = memberVO.getId();
String password = memberVO.getPassword();
String name = memberVO.getName();
String email = memberVO.getEmail();
Date joinDate = memberVO.getJoinDate();
out.print("<tr><td>" + id + "</td><td>" + password + "</td><td>" +
name + "</td><td>" + email + "</td><td>" +
joinDate + "</td></tr>");
}
out.print("</table></body></html>");
}
}
다음은 DB에 접근하기 위한 MemberDAO
클래스를 작성합니다.
package com.example.helloservlet.dbexample;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class MemberDAO {
private Connection connection;
private String dbusername = "";
private String dbpassword = "";
public List<MemberDTO> listMembers() {
List<MemberDTO> members = new ArrayList<MemberDTO>();
try {
connectDB();
String sql = "SELECT * FROM member ";
System.out.println("query: " + sql);
PreparedStatement preparedStatement = connection.prepareStatement(sql);
ResultSet rs = preparedStatement.executeQuery();
while(rs.next()) {
System.out.println("rs running");
String id = rs.getString("id");
String password = rs.getString("password");
String name = rs.getString("name");
String email = rs.getString("email");
Date joinDate = rs.getDate("joinDate");
MemberDTO memberDTO = new MemberDTO();
memberDTO.setId(id);
memberDTO.setPassword(password);
memberDTO.setName(name);
memberDTO.setEmail(email);
memberDTO.setJoinDate(joinDate);
members.add(memberDTO);
}
rs.close();
preparedStatement.close();
connection.close();
}
catch (SQLException e) {
e.printStackTrace();
}
return members;
}
private void connectDB() {
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
connection = DriverManager.getConnection(
"jdbc:oracle:thin:@localhost:1521/xe",
dbusername,
dbpassword
);
System.out.println("Connected to database");
}
catch (Exception e) {
e.printStackTrace();
}
}
}
MemberDAO
에서는 DB에 접속을 하고 SELECT
문으로 테이블을 조회해서 각 레코드(row)의 컬럼 값을 받아 MemberDTO
의 값으로 설정 한 후 list에 담아서 반환합니다. 이렇게 함으로써 테이블의 레코드 정보들이 담긴 리스트를 받아올 수 있게 됩니다.
이제 회원 정보 담는 객체인 MemberDTO
를 생성해줍니다. MemberDTO
에는 회원 정보 (id, password, name, email, joinDate)에 대한 필드와 getter/setter만을 갖습니다.
Lombok 라이브러리를 사용하여 DTO를 간편하게 생성했습니다.
package com.example.helloservlet.dbexample;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.sql.Date;
@NoArgsConstructor
@Getter
@Setter
public class MemberDTO {
private String id;
private String name;
private String password;
private String email;
private Date joinDate;
}
이제 모든 코드의 작성을 마쳤으니 톰캣 서버를 실행한 후 http://localhost:8090/HelloServlet_war_exploded/
로 접속합니다. /member
로 요청을 보냈을 때 우리가 넣었던 예시 데이터가 테이블에 담겨서 출력이 되었다면 서블릿과 DB연동에 성공한 것 입니다.