[Servlet] DataSource CRUD

Bam·2024년 5월 3일
0

Spring

목록 보기
21/48
post-thumbnail

지난 포스트에서 DataSource를 이용해서 DB에 미리 연결을 해놓고, 필요할 때만 연결 정보를 가져와서 빠르게 로직을 처리하는 방법에 대해 알아보았습니다. 이번에는 한 발 더 나아가서 DataSource를 이용해 CRUD를 처리하는 방법에 대해 알아보겠습니다.

CRUD에 대한 설명은 이 포스트를 참조해주세요. CRUD + 기본 개념과 각 코드에 대한 기본틀이 동일합니다.

각종 환경 설정이나 DataSource의 기본 사항에 대해서는 이 포스트를 참조해주세요. 오늘의 포스트는 지난 포스트에서 계속 이어지는 내용입니다.


Servlet 작성

다음으로는 요청을 처리할 서블릿인 MemberServlet.java를 작성합니다.

package com.example.helloservlet.dbexample3;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Date;
import java.util.List;

// "/member3"로 서블릿 매핑
@WebServlet("/member3")
public class MemberServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        doHandle(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        doHandle(req, resp);
    }

	//실제 작업을 처리하는 doHandle() 메소드
    public void doHandle(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");

        MemberDAO memberDAO = new MemberDAO();
        PrintWriter out = resp.getWriter();
        //command의 값을 받아옴
        String command = req.getParameter("command");
		
        if (command != null && command.equals("addMember")) {
        	//폼에서 전달된 값들을 받아와 MemberDTO에 저장 후 addMember()로 전달하여 추가 기능 동작
            String id = req.getParameter("id");
            String password = req.getParameter("password");
            String name = req.getParameter("name");
            String email = req.getParameter("email");

            MemberDTO memberDTO = new MemberDTO();
            memberDTO.setId(id);
            memberDTO.setPassword(password);
            memberDTO.setName(name);
            memberDTO.setEmail(email);
            memberDAO.addMember(memberDTO);
        }

        List<MemberDTO> members = memberDAO.listMembers();
        
        // "/member3"에선 현재 DB의 멤버들을 SELECT를 통해 가져와 table로 출력
        out.println("<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><td>delete</td>" +
                "<td>update</td></tr>");

        for (int i = 0; i < members.size(); i++) {
            MemberDTO memberDTO = (MemberDTO) members.get(i);
            String id = memberDTO.getId();
            String password = memberDTO.getPassword();
            String name = memberDTO.getName();
            String email = memberDTO.getEmail();
            Date joinDate = memberDTO.getJoinDate();

            out.print("<tr><td>" + id + "</td><td>" + password + "</td><td>" +
                    name + "</td><td>" + email + "</td><td>" + joinDate + "</td><td>" +
                    "<a href='/member3?command=deleteMember&id=" + id + "'>" +
                    "회원 삭제</a></td><td>" +
                    "<a href='/updateForm.html'>수정</a>" +
                    "</td></tr>");
        }

        out.println("</table></body></html>");
        //joinForm.html로 이동하도록 버튼 생성
        out.print("<a href='/joinForm.html'>회원 가입</a>");
    }
}

GET 또는 POST 요청에 대해 모두 대응할 수 있도록 실제 작업을 처리하는 doHandle()에서 실제 작업 코드를 작성하고 각 doXxxxx()메소드에서 doHandle()을 호출합니다.

doHandle()에서는 command 값을 받아와서 조건에 맞는 조건문을 실행합니다. 지금은 멤버 추가 기능만 있어서 addMember만을 검사하지만 추후에 삭제, 갱신 기능을 추가하면 else~if로 새로운 분기를 더하고 검사하게 됩니다.

if문 내부에서는 폼에서 전달된 값들(id, password, name, email)을 가져와서 MemberDTO 객체에 저장하는 과정을 거친 후 addMember()로 전달하게 됩니다.


Create

Create는 회원 가입을 담당합니다. INSERT 구문을 통해 DB에 회원 정보를 추가하게 됩니다.

회원 정보를 사용자로부터 받기 위해 joinForm.html을 작성합니다.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Join</title>
    <script type="text/javascript">
        function sendJoinForm() {
            let joinForm = document.joinForm;
            let id = joinForm.id.value;
            let password = joinForm.password.value;
            let name = joinForm.name.value;
            let email = joinForm.email.value;

            if (id.length === 0 || id === "") {
                alert("아이디는 필수입니다.");
            } else if (password.length === 0 || password === "") {
                alert("비밀번호는 필수입니다.");
            } else if (name.length === 0 || name === "") {
                alert("이름은 필수입니다.");
            } else if (email.length === 0 || email === "") {
                alert("이메일은 필수입니다.");
            } else {
                joinForm.method = "post";
                joinForm.action = "member3";
                joinForm.submit();
            }
        }
    </script>
</head>
<body>
<form name="joinForm">
    <table>
        <th>회원 가입</th>
        <tr>
            <td>아이디</td>
            <td><input type="text" name="id"></td>
        </tr>
        <tr>
            <td>비밀번호</td>
            <td><input type="password" name="password"></td>
        </tr>
        <tr>
            <td>이름</td>
            <td><input type="text" name="name"></td>
        </tr>
        <tr>
            <td>이메일</td>
            <td><input type="text" name="email"></td>
        </tr>
    </table>
    <input type="button" value="가입하기" onclick="sendJoinForm()">
    <input type="reset" value="다시입력">
    <input type="hidden" name="command" value="addMember"/>
</form>
</body>
</html>

sendJoinForm() 자바스크립트 함수는 각 폼에 입력된 정보가 유효한지 유효성 검사를 수행하고 요청을 보냅니다.

그러면 실제로 추가 작업을 수행하는 MemberDAO 객체를 작성해보겠습니다.

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import java.sql.*;
import java.sql.Date;
import java.util.*;

public class MemberDAO {
    private Connection connection;
    private PreparedStatement preparedStatement;
    private DataSource dataSource;

	(...)

    public void addMember(MemberDTO memberDTO) {
        try {
        	//DataSource로부터 연결 정보 취득
            connection = dataSource.getConnection();
            
            //DTO 객체로부터 각 필드 정보 취득
            String id = memberDTO.getId();
            String password = memberDTO.getPassword();
            String name = memberDTO.getName();
            String email = memberDTO.getEmail();
            
            //매개변수화된 INSERT SQL 쿼리
            String sql = "INSERT INTO member (id, password, name, email)" +
                    "VALUES (?, ?, ?, ?)";
            System.out.println("query: " + sql);
            
            //매개변수화된 INSERT에 각 정보 삽입 후 쿼리 실행
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1, id);
            preparedStatement.setString(2, password);
            preparedStatement.setString(3, name);
            preparedStatement.setString(4, email);
            preparedStatement.executeUpdate();
            preparedStatement.close();
        }
        catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

생략된 부분은 이전 포스트를 참조해주세요.

실제로 INSERT를 수행하는 addMember()입니다. 폼으로 부터 전송된 정보가 저장된 DTO 객체로부터 정보를 얻어 매개변수화된 INSERT 구문에 대입하고 쿼리를 실행함으로써 새로운 멤버 정보를 추가하게 됩니다.


Read

ReadSELECT 쿼리를 이용해서 DB 정보를 읽어오는 것인데요. /member3에 접속하면 자동으로 실행됩니다.

public List<MemberDTO> listMembers() {
        List<MemberDTO> members = new ArrayList<MemberDTO>();

        try {
            connection = dataSource.getConnection();

            String sql = "SELECT * FROM member";
            System.out.println("query: " + sql);

            preparedStatement = connection.prepareStatement(sql);
            ResultSet resultSet = preparedStatement.executeQuery();

            while (resultSet.next()) {
                String id = resultSet.getString("id");
                String password = resultSet.getString("password");
                String name = resultSet.getString("name");
                String email = resultSet.getString("email");
                Date joinDate = resultSet.getDate("joinDate");

                MemberDTO memberDTO = new MemberDTO();
                memberDTO.setId(id);
                memberDTO.setPassword(password);
                memberDTO.setName(name);
                memberDTO.setEmail(email);
                memberDTO.setJoinDate(joinDate);
                members.add(memberDTO);
            }

            resultSet.close();
            preparedStatement.close();
            connection.close();
        }
        catch (SQLException e) {
            throw new RuntimeException(e);
        }

        return members;
    }

이에 대한 내용은 지난 포스트에서 다뤘으므로 해당 포스트를 참조해주세요.

간단히 요약하자면 SELECT로 정보를 가져오고 이를 List에 담아 반환합니다.


Update

사용자 정보를 갱신하는 Update입니다. 완벽한 기능은 추후에 JSP를 다룰때 제대로 구현해보기로 하고, 이번에는 간단히 구현해보겠습니다. 먼저 수정을 위한 폼인 updateForm.html을 작성합니다.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Update</title>
    <script type="text/javascript">
        function sendUpdateForm() {
            let updateForm = document.updateForm;
            let id = updateForm.id.value;
            let password = updateForm.password.value;
            let name = updateForm.name.value;
            let email = updateForm.email.value;

            if (id.length === 0 || id === "") {
                alert("아이디는 필수입니다.");
            } else if (password.length === 0 || password === "") {
                alert("비밀번호는 필수입니다.");
            } else if (name.length === 0 || name === "") {
                alert("이름은 필수입니다.");
            } else if (email.length === 0 || email === "") {
                alert("이메일은 필수입니다.");
            } else {
                updateForm.method = "post";
                updateForm.action = "member3";
                updateForm.submit();
            }
        }
    </script>
</head>
<body>
<form name="updateForm">
    <table>
        <th>회원 정보 수정</th>
        <tr>
            <td>아이디</td>
            <td><input type="text" name="id" placeholder="변경하고자하는 id 입력"></td>
        </tr>
        <tr>
            <td>비밀번호</td>
            <td><input type="password" name="password"></td>
        </tr>
        <tr>
            <td>이름</td>
            <td><input type="text" name="name"></td>
        </tr>
        <tr>
            <td>이메일</td>
            <td><input type="text" name="email"></td>
        </tr>
    </table>
    <input type="button" value="수정하기" onclick="sendUpdateForm()">
    <input type="reset" value="다시입력">
    <input type="hidden" name="command" value="updateMember"/>
</form>
</body>
</html>

id 폼에 변경하고자하는 id를 입력하면 password, name, email을 입력한 정보로 변경할 수 있게 됩니다.

MemberServlet.javaif문에 UPDATE를 위한 분기를 추가해줍니다.

		if (command != null && command.equals("addMember")) {
            (...)
        }
        else if (command != null && command.equals("updateMember")) {
            String id = req.getParameter("id");
            String password = req.getParameter("password");
            String name = req.getParameter("name");
            String email = req.getParameter("email");

            MemberDTO memberDTO = new MemberDTO();
            memberDTO.setId(id);
            memberDTO.setPassword(password);
            memberDTO.setName(name);
            memberDTO.setEmail(email);
            memberDAO.updateMember(memberDTO);
        }

그리고 MemberDAO에 업데이트 동작 메소드인 updateMember()를 다음과 같이 작성합니다.

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import java.sql.*;
import java.sql.Date;
import java.util.*;

public class MemberDAO {
    private Connection connection;
    private PreparedStatement preparedStatement;
    private DataSource dataSource;
    
    (...)
    
    public void updateMember(MemberDTO memberDTO) {
        try {
            connection = dataSource.getConnection();

            String id = memberDTO.getId();
            System.out.println(id);
            String password = memberDTO.getPassword();
            String name = memberDTO.getName();
            String email = memberDTO.getEmail();

            String sql = "UPDATE member SET " +
                    "password=?, name=?, email=? " +
                    "WHERE id=?";
            System.out.println("query: " + sql);

            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1, password);
            preparedStatement.setString(2, name);
            preparedStatement.setString(3, email);
            preparedStatement.setString(4, id);
            preparedStatement.executeUpdate();
            preparedStatement.close();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}

동작 자체는 addMember()와 동일하되 SQL 쿼리만 변경되었습니다.

입력한 id값을 기반으로 테이블을 탐색해서 id가 존재한다면 입력된 password, name, email로 변경합니다.


Delete

마지막은 회원을 삭제하는 DELETE입니다. 마찬가지로 MemberServletif문에 구문을 추가해줍니다. id를 기반으로 탐색해서 삭제하기 때문에 오직 id만을 전달하면 되어서 간단한 내용을 갖습니다.

if (command != null && command.equals("addMember")) {
	(...)
}
else if (command != null && command.equals("updateMember")) {
	(...)
}
else if (command != null && command.equals("deleteMember")) {
	String id = req.getParameter("id");

	memberDAO.deleteMember(id);
}

삭제를 수행하는 deleteMember()MemberDAO에 추가합니다.

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import java.sql.*;
import java.sql.Date;
import java.util.*;

public class MemberDAO {
    private Connection connection;
    private PreparedStatement preparedStatement;
    private DataSource dataSource;
    
    (...)
    
    public void deleteMember(String id) {
        try {
            connection = dataSource.getConnection();

            String sql = "DELETE FROM member WHERE id = ?";
            System.out.println("query: " + sql);

            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1, id);
            preparedStatement.executeUpdate();
            preparedStatement.close();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}

마찬가지로 DataSource로부터 연결 정보를 받아오고 id를 통해서 DELETE 쿼리를 실행합니다.


전체 코드

코드가 길어서 설명할 때는 생략된 코드들을 올려놨습니다. 만약 전체 코드가 필요할 수도 있기에 MemberSerlvet.java, MemberDAO.java의 전체 코드도 첨부합니다.

//MemberServlet.java
package com.example.helloservlet.dbexample3;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Date;
import java.util.List;

@WebServlet("/member3")
public class MemberServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        doHandle(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        doHandle(req, resp);
    }

    public void doHandle(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");

        MemberDAO memberDAO = new MemberDAO();
        PrintWriter out = resp.getWriter();
        String command = req.getParameter("command");

        if (command != null && command.equals("addMember")) {
            String id = req.getParameter("id");
            String password = req.getParameter("password");
            String name = req.getParameter("name");
            String email = req.getParameter("email");

            MemberDTO memberDTO = new MemberDTO();
            memberDTO.setId(id);
            memberDTO.setPassword(password);
            memberDTO.setName(name);
            memberDTO.setEmail(email);
            memberDAO.addMember(memberDTO);
        }
        else if (command != null && command.equals("deleteMember")) {
            String id = req.getParameter("id");

            memberDAO.deleteMember(id);
        }
        else if (command != null && command.equals("updateMember")) {
            String id = req.getParameter("id");
            String password = req.getParameter("password");
            String name = req.getParameter("name");
            String email = req.getParameter("email");

            MemberDTO memberDTO = new MemberDTO();
            memberDTO.setId(id);
            memberDTO.setPassword(password);
            memberDTO.setName(name);
            memberDTO.setEmail(email);
            memberDAO.updateMember(memberDTO);
        }

        List<MemberDTO> members = memberDAO.listMembers();

        out.println("<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><td>delete</td>" +
                "</tr>");

        for (int i = 0; i < members.size(); i++) {
            MemberDTO memberDTO = (MemberDTO) members.get(i);
            String id = memberDTO.getId();
            String password = memberDTO.getPassword();
            String name = memberDTO.getName();
            String email = memberDTO.getEmail();
            Date joinDate = memberDTO.getJoinDate();

            out.print("<tr><td>" + id + "</td><td>" + password + "</td><td>" +
                    name + "</td><td>" + email + "</td><td>" + joinDate + "</td><td>" +
                    "<a href='/member3?command=deleteMember&id=" + id + "'>" +
                    "회원 삭제</a></td></tr>");
        }

        out.println("</table></body></html>");
        out.print("<a href='/joinForm.html'>회원 가입</a><br/>");
        out.print("<a href='/updateForm.html'>회원 정보 수정</a>");
    }
}
//MemberDAO.java
package com.example.helloservlet.dbexample3;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import java.sql.*;
import java.sql.Date;
import java.util.*;

public class MemberDAO {
    private Connection connection;
    private PreparedStatement preparedStatement;
    private DataSource dataSource;

    public MemberDAO() {
        try {
            Context context = new InitialContext();
            Context envContext = (Context) context.lookup("java:comp/env");
            dataSource = (DataSource) envContext.lookup("jdbc/oracle");
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }

    public List<MemberDTO> listMembers() {
        List<MemberDTO> members = new ArrayList<MemberDTO>();

        try {
            connection = dataSource.getConnection();

            String sql = "SELECT * FROM member";
            System.out.println("query: " + sql);

            preparedStatement = connection.prepareStatement(sql);
            ResultSet resultSet = preparedStatement.executeQuery();

            while (resultSet.next()) {
                String id = resultSet.getString("id");
                String password = resultSet.getString("password");
                String name = resultSet.getString("name");
                String email = resultSet.getString("email");
                Date joinDate = resultSet.getDate("joinDate");

                MemberDTO memberDTO = new MemberDTO();
                memberDTO.setId(id);
                memberDTO.setPassword(password);
                memberDTO.setName(name);
                memberDTO.setEmail(email);
                memberDTO.setJoinDate(joinDate);
                members.add(memberDTO);
            }

            resultSet.close();
            preparedStatement.close();
            connection.close();
        }
        catch (SQLException e) {
            throw new RuntimeException(e);
        }

        return members;
    }

    public void addMember(MemberDTO memberDTO) {
        try {
            connection = dataSource.getConnection();

            String id = memberDTO.getId();
            String password = memberDTO.getPassword();
            String name = memberDTO.getName();
            String email = memberDTO.getEmail();

            String sql = "INSERT INTO member (id, password, name, email)" +
                    "VALUES (?, ?, ?, ?)";
            System.out.println("query: " + sql);

            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1, id);
            preparedStatement.setString(2, password);
            preparedStatement.setString(3, name);
            preparedStatement.setString(4, email);
            preparedStatement.executeUpdate();
            preparedStatement.close();
        }
        catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public void deleteMember(String id) {
        try {
            connection = dataSource.getConnection();

            String sql = "DELETE FROM member WHERE id = ?";
            System.out.println("query: " + sql);

            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1, id);
            preparedStatement.executeUpdate();
            preparedStatement.close();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void updateMember(MemberDTO memberDTO) {
        try {
            connection = dataSource.getConnection();

            String id = memberDTO.getId();
            System.out.println(id);
            String password = memberDTO.getPassword();
            String name = memberDTO.getName();
            String email = memberDTO.getEmail();

            String sql = "UPDATE member SET " +
                    "password=?, name=?, email=? " +
                    "WHERE id=?";
            System.out.println("query: " + sql);

            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1, password);
            preparedStatement.setString(2, name);
            preparedStatement.setString(3, email);
            preparedStatement.setString(4, id);
            preparedStatement.executeUpdate();
            preparedStatement.close();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}

0개의 댓글