Servlet JSP MVC Spring

[Servlet] 서블릿과 데이터베이스 연동 조회: PrepareStatement

vhxpffltm 2020. 2. 21. 00:45
반응형

이번에는 서블릿이 클라이언트로부터 요청을 받으면 그 요청에 대해 작업을 수행하는 것을 해보자.

 

보통, 회원 등록 요청 처리, 로그인 요청 처리 등의 처리를 의미한다.

 

아래 그림이 우리가 진행할 로직이다.

 

 

 

서블릿에서 데이터베이스와 연동하는 과정은 클라이언트로부터 요청을 받으면 서블릿은 SQL문을 사용해 데이터베이스에 접근하여 작업한다. 

 

이를 바탕으로 회원정보에 대한 CRUD작업을 하는것이 목표이다.

 

먼저 회원정보를 조회해보자. 

회원 정보 테이블을 생성한 후 회원 정보를 추가하여 웹 브라우저에서 서블릿으로 요청하면 데이터베이스와 연동해 회원 정보를 웹 브라우저로 출력하는 작업이다.

 

이번 실습의 구조는 아래와 같다.

 

 

sqldeveloper 데이터

 

먼저 Sqldevelper를 사용하여 데이터베이스를 정의한다. 이것을 사용하여 쉽게 SQL쿼리문을 사용하여 데이터를 삽입하고 조회할 수 있다.

 

데이터베이스를 추가하고 아래와 같은 코드를 작성해보자.

 

테이블을 생성하고 그 테이블에 데이터를 순차적으로 넣었다. SQL 쿼리문을 배웠다면 문제없이 이해할 수 있다. 

 

 

작성한 후, 각 쿼리문 마지막에 커서를 대고 '실행' 버튼인 초록색 화살표를 시행하면 쿼리문이 실행된다. 'commit'으로 추가한 회원정보를 영구적으로 반영되게 하고 'select' 문으로 회원정보를 조회하면 위와 같은 결과를 얻을 수 있다.

 

이후, 이클립스로 새로운 프로젝트를 만들어 오라클 데이터베이스와 연동하는데 필요한 드라이버인 'ojdbc6.jar'을 아래그림과 같은 경로에 복사한다.

 

이 파일은 오라클을 설치하였다면 C:\oraclexe\app\oracle\product\11.2.0\server\jdbc\lib 의 경로에 존재한다.

 

 

 

 

이클립스 작업

 

이제 이클립스에 패키지를 만들고 클래스를 작성해보자. 클래스는 아래와 같다.

MemberDAO.java

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package sec01.ex01;
 
 
 
public class MemberDAO {
    private static final String driver = "oracle.jdbc.driver.OracleDriver";
    private static final String url = "jdbc:oracle:thin:@localhost:1521:XE";
    private static final String user = "pl";
    private static final String pwd = "pllab304";
    //private Connection con;
    //private Statement stmt;
    //회원 정보 조회 SQL문을 실행하여 조회한 레코드들의 컬럼 값을 다시 MemberVO객체의 속성에 설정한 다음
    //ArrayList에 저장하고 호출한 곳으로 반환
    
    private Connection con;
    private PreparedStatement pstmt;
    //prepareStatement 인터페이스를 사용하여 SQL문을 미리 컴파일하여 재사용하므로 빠르게 DB작업 수행
    //DB와 연동할 때 또는 빠른 반복 처리가 필요할때 이 인터페이스를 사용
    
    public List<MemberVO> listMembers() {
        List<MemberVO> list = new ArrayList<MemberVO>();
        try {/*
            connDB(); //4가지 정보로 데이터베이스 연결
            String query = "select * from t_member ";
            System.out.println(query);
            ResultSet rs = stmt.executeQuery(query); //SQL문으로 회원 정보를 조회
            */
             connDB();
             String query = "select * from t_member ";
             System.out.println("PrepareStatement: " + query);
             pstmt = con.prepareStatement(query);//preparestatement 객체 생성
             ResultSet rs = pstmt.executeQuery();//executequery()로 미리 설정한 SQL문 실행
             //preparestatement는 statement를 상속하므로 사용한 메서드를 그대로 사용
             
            while (rs.next()) {
                String id = rs.getString("id");
                String pwd = rs.getString("pwd");
                String name = rs.getString("name");
                String email = rs.getString("email");
                Date joinDate = rs.getDate("joinDate");
                //조회한 레코드의 각 컬럼 값을 받아 옴
                MemberVO vo = new MemberVO();
                vo.setId(id);
                vo.setPwd(pwd);
                vo.setName(name);
                vo.setEmail(email);
                vo.setJoinDate(joinDate); //각 컬럼 값을 다시 MemberVO객체의 속성에 설정
                list.add(vo); //설정된 MemberVO객체를 다시 ArrayList에 저장
            }
            rs.close();
            pstmt.close();
            con.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list; //조회한 레코드의 개수만큼 MemberVo 객체를 저장한 ArrayList를 반환
    }
 
    private void connDB() {
        try {
            Class.forName(driver);
            System.out.println("Oracle 드라이버 로딩 성공");
            con = DriverManager.getConnection(url, user, pwd);
            System.out.println("Connection 생성 성공");
            //stmt = con.createStatement();
            System.out.println("Statement 생성 성공");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
 
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
 

 

memberServlet.java

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package sec01.ex01;
 
 
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
 
/**
 * Servlet implementation class MemberServlet
 */
@WebServlet("/Member")
public class MemberServlet extends HttpServlet {
    //브라우저의 요청을 받는 클래스
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
          PrintWriter out=response.getWriter();    
          MemberDAO dao=new MemberDAO(); //SQL문으로 조회할 MemberDAO 객체를 생성
          List<MemberVO> list=dao.listMembers(); //listMembers() 메서드로 회원 정보를 조회
          
          out.print("<html><body>");
          out.print("<table  border=1><tr align='center' bgcolor='lightgreen'>");
          out.print("<td>아이디</td><td>비밀번호</td><td>이름</td><td>이메일</td><td>가입일</td></tr>");
         
         for (int i=0; i<list.size();i++){
            MemberVO memberVO=(MemberVO) list.get(i);
            String id=memberVO.getId();
            String pwd = memberVO.getPwd();
            String name=memberVO.getName();
            String email=memberVO.getEmail();
            Date joinDate = memberVO.getJoinDate();
            out.print("<tr><td>"+id+"</td><td>"+
                                pwd+"</td><td>"+
                                name+"</td><td>"+
                                email+"</td><td>"+
                                joinDate+"</td></tr>");        
          }// 조회한 회원 정보를 for문과 <tr> 태그를 이용해 리스트로 출력
          out.print("</table></body></html>");
    }
 
}
 
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
 

 

memberVO.java

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package sec01.ex01;
 
 
public class MemberVO {
    //값을 전달하는데 사용되는 Value Object 클래스
    //테이블에서 조회한 레코드의 컬럼 값을 속성에 저장해야 하므로 컴럼 이름과 동일한 자료형과 이름으로 속성 선언
    //get,set 으로 각각의 값을 return하고 (get) this.~~(set)으로 값을 설정한다.
    private String id;
    private String pwd;
    private String name;
    private String email;
    private Date joinDate;
    
    public MemberVO() {
        System.out.println("MemberVO »ý¼ºÀڠȣÃâ");
    }
 
    public String getId() {
        return id;
    }
 
    public void setId(String id) {
        this.id = id;
    }
 
    public String getPwd() {
        return pwd;
    }
 
    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
 
    public String getEmail() {
        return email;
    }
 
    public void setEmail(String email) {
        this.email = email;
    }
 
    public Date getJoinDate() {
        return joinDate;
    }
 
    public void setJoinDate(Date joinDate) {
        this.joinDate = joinDate;
    }
}
 
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
 

 

이렇게 작성한 후, 서버를 키고 로컬 호스트로 접속하면 아래의 결과를 얻을수 있다.

 

 

MemberDAO클래스는 2가지 방법을 사용할 수 있다. 주석으로 처리된 부분은 Statement를 사용하고 주석이 아닌부분은 PrepareStatement를 사용하여 구현하였다. 이렇게 데이터 베이스와 연동할 경우 수행 속도가 빠르다는 점을 알아두자.

 

Refernce

자바 웹을 다루는 기술<길벗>

 

반응형