Servlet; DataSource 연동

🗓️

서블릿 : 비즈니스 로직

  • 서블릿 비즈니스 처리 작업이란 서블릿이 클라이언트로부터 요청을 받으면 그 요청에 대해 작업을 수행하는 것을 의미 합니다.
  • 대부분의 비즈니스로직 처리는 DB연동 작업이 동반된다.

서블릿의 데이터베이스 연동

  • DAO와 VO를 사용한 회원정보 연동을 해보자

서블릿으로 회원 정보 테이블의 회원 정보 조회

  • H2 데이터베이스를 미리 준비한다
create table t_member(
    id varchar2(10) PRIMARY KEY,
    pwd varchar2(10),
    name varchar2(50),
    email varchar2(50),
    joinDate date default sysdate
);

insert into t_member values('kang', '1234' ,'강민철','platanus.kr@gmail.com',sysdate);
insert into t_member values('minho', '1234' ,'이센스','esens@bana.com',sysdate);
insert into t_member values('ximya', '1234' ,'김심야','ximya@bana.com',sysdate);
commit;
  • 쿼리를 밀어넣고 maven.xml에 다음 내용을 추가한다.
    <dependency>
      <groupId>com.h2database</groupId>
      <artifactId>h2</artifactId>
      <version>1.4.181</version>
    </dependency>
  • MemberDAO, MemberVO
  • MemberServlet
@WebServlet("/member")
public class MemberServlet extends HttpServlet {

    @Override
    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();
        List<MemberVO> list = dao.listMembers();

        out.print("<html><body>");
        out.print("<table border=1><tr>");
        out.print("<td>ID</td><td>PW</td><td>Name</td><td>E-Mail</td><td>joindate</td></tr>");

        for (int i = 0; i < list.size(); i++){
            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>");

        }
        out.print("</table></body></html>");

    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

    }
}

DataSouce를 이용해 데이터베이스 연동하기

  • 데이터베이스 연동 과정은 웹 어플리케이션이 필요할 때마다 DB에 연결해 작업하는 방식이다. 이런식으로 필요할때마다 연동해서 작업한다면 DB연결에 걸리는 시간이 오버헤드로 잡힌다.
  • 웹 어플리케이션이 실행됨과 동시에 연동할 데이터베이스와의 연결을 미리 설정한다.
  • 그리고 미리 연결해 놓은 상태를 이용해 빠르게 데이터베이스와 연동작업을 한다.
  • 미리 데이터베이스와 연결시킨 상태를 유지하는 것을 Connection Pool이라고 한다

JNDI; Java Naming and Directory Interface

  • 실제 웹 어플리케이션에서 CP 객체를 구현할 때는 JDK에서 제공하는 javax.sql.DataSource 클래스를 이용한다. 그리고 웹 어플리케이션 실행 시 톰캣이 만들어 놓은 CP 객체에 접근할때는 JNDI를 이용한다.
  • JNDI의 사용 예
    • 웹 브라우저에서 name-value쌍으로 전송한 후 서블릿에서 getParameter(name)으로 값을 가져올 때
    • HashMap이나 HashTable에서 key-value값으로 저장한 후 키를 이용해 값을 가져올 때
    • 웹 브라우저에서 도메인 네임으로 DNS서버에 요청할 경우 도메인 네임에 대한 IP 주소를 가져올 때
  • 톰캣 컨테이너가 CP객체를 생성하면 이 객체에 대한 JNDI key를 미리 설정해놓는다.
  • 웹 어플리케이션에서 DB와 연동작업을 할 때 JNDI 이름으로 접근해 작업한다.

DataSource 설정

Intellij에서 DataSource context.xml 설정하기

  • DataSource 설정
<?xml version="1.0" encoding="UTF-8"?>
<Context>
  <WatchedResource>WEB-INF/web.xml</WatchedResource>
  <Resource
    name="jdbc/h2"
    auth="Container"
    type="javax.sql.DataSource"
    driverClassName="org.h2.Driver"
    url="jdbc:h2:tcp://localhost/~/Development/h2/jsp"
    username="sa"
    password=""
  />
</Context>
  • DataSource를 쓰도록 DAO 변경하기
public class MemberDAO {

    private Connection con;
    private PreparedStatement pstmt;
    private DataSource dataFactory;

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

    public List<MemberVO> listMembers() {
        List<MemberVO> list = new ArrayList<MemberVO>();
        try {
            con = dataFactory.getConnection();
            String query = "select * from t_member ";
            System.out.println(query);
            pstmt = con.prepareStatement(query);
            ResultSet rs = pstmt.executeQuery();
            while (rs.next()) {
                // 중략
            }
            rs.close();
            pstmt.close();
            con.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }
}

DataSource 응용