-
JDBC+DAO 활용한 회원 리스트 만들기framework/Spring 2018. 7. 30. 18:57반응형
지난번에는 Servlet를 이용하여 회원 리스트를 만들어 보았다. 그 방법에서는 모든 코드를 서블릿 안에서 처리해야 하기 때문에 중복되는 코드가 많고 코드가 서로 섞이고 유지보수에 어려운 점이 많았다. 이번에는 DAO를 이용하여 Servlet을 분리해 보도록 하겠다.
1) domain패키지와 Member클래스 생성
우선 src/main/java 아래에 domain 패키지를 생성하고 패키지 아래에 Member 클래스를 만든다. Member 클래스는 자료를 저장하는 모델이 된다. Member 클래스의 코드는 아래와 같다.
123456789101112131415161718192021222324252627282930313233package domain;public class Member {private String id;private String email;private String password;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}}cs 2) DAO 패키지와 클래스를 만든다.
DAO는 Data Access Object의 약자로 Database에 접근하는 객체를 의미한다. 지금은 Servlet에 섞여있는 코드를 분리해 DAO를 만들어 보자. 먼저 DAO 패키지와 클래스를 만든다.
원래 Servlet 코드에 함께 포함된 부분은 다음과 같다.
1234567891011121314151617181920try {Class.forName("com.mysql.jdbc.Driver"); // mysql-jdbc driver를 로딩한다try ( // forName 안에 물리적 주소를 넣으면 클래스를 반환Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/testdb", // mysqldb에 접속하는"test", "1111"); // Connection 객체를 만듭니다PreparedStatement stmt = con.prepareStatement("select mid, email from member"); // sql 쿼리문을// 저장하는 객체ResultSet rs = stmt.executeQuery();) { // 쿼리문을 전송해서 반환되는 값을// 저장하는 resultsetwhile (rs.next()) { // resultset에 값이 있으면 반복문을 계속 수행한다out.println("<tr>");out.printf(" <td><a href='view?id=%s'>%s</a></td><td>%s</td>\n", rs.getString("mid"),rs.getString("mid"), rs.getString("email"));out.println("</tr>");}}} catch (Exception e) {out.println("<p>목록 가져오기 실패!</p>"); //에러처리e.printStackTrace(out);}cs 이 부분은 DAO로 분리해서 꺼낸다. DAO 클래스의 코드는 다음과 같다.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354package dao;import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.util.ArrayList;import java.util.List;import domain.Member;public class MemberDao {private String jdbcUrl;private String username;private String password;// 생성자를 통해 Dao에 필요한 필드변수를 꽂아준다.public MemberDao(String jdbcUrl, String username, String password) {this.jdbcUrl = jdbcUrl;this.username = username;this.password = password;try {// 처음 객체가 생성될 때 드라이브를 로딩한다.Class.forName("com.mysql.jdbc.Driver");} catch (Exception e) {e.printStackTrace();}}public List<Member> selectList() throws Exception {try (// mysqldb에 접속Connection con = DriverManager.getConnection(jdbcUrl, username, password);PreparedStatement stmt = con.prepareStatement("select mid, email from member");ResultSet rs = stmt.executeQuery();) {List<Member> list = new ArrayList<>();while (rs.next()) {// 이전 Servlet 버전에서 이 부분에서 바로 출력을 했으나// DAO에서는 객체에 값을 집어넣어 리턴한다.Member member = new Member();member.setId(rs.getString("mid"));member.setEmail(rs.getString("email"));list.add(member);}return list;}}}cs 3) servlet 부분 수정
이제 servlet 부분도 수정해 줘야한다. MemberDao를 선언하고 생성자를 통해 필요한 값을 주입하는데 이를 의존성 주입이라고 하며 Spring에서 핵심적인 개념이다. 아래 코드를 보자.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162package servlet;import java.io.IOException;import java.io.PrintWriter;import java.util.List;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 dao.MemberDao;import domain.Member;// @는 annotation을 뜻한다, annotation은 서버에 알려주는 역할을 한다.@WebServlet("/member/list") // "/member/list" 라는 요청이 URL로 오면 이 클래스를 실행한다.public class MemberList extends HttpServlet {// HttpServlet 클래스를 상속받으면 해당 클래스가 servlet으로 동작하게 한다// 상속받은 클래스에서 doGet 메서드를 오버라이드 해서 get요청을 받아서 처리한다.@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {response.setContentType("text/html;charset=UTF-8"); // characterset 을 utf8로 지정PrintWriter out = response.getWriter(); // 화면에 직접 html 코드를 출력하는 객체이다out.println("<!DOCTYPE html>"); // 여기서 작성된 태그는 버퍼에 저장되었다가out.println("<html>"); // 한번에 전송된다.out.println("<head>");out.println("<meta charset='UTF-8'>");out.println("<title>멤버 목록</title>");out.println("</head>");out.println("<body>");out.println("<h1>멤버 목록</h1>");out.println("<p><a href='add.html'>새회원</a></p>");out.println("<table border='1'>");out.println("<tr>");out.println(" <th>아이디</th><th>이메일</th>");out.println("</tr>");try {// memberDao 객체를 만들며 생성자에 주소와 아이디 비밀번호를 꽂아준다.MemberDao memberDao = new MemberDao("jdbc:mysql://localhost:3306/testdb", "test", "1111");List<Member> list = memberDao.selectList();// memberDao로부터 받은 객체 리스트를 출력한다.for (Member member : list) {out.println("<tr>");out.printf(" <td><a href='view?id=%s'>%s</a></td><td>%s</td>\n", member.getId(), member.getId(),member.getEmail());out.println("</tr>");}} catch (Exception e) {out.println("<p>목록 가져오기 실패!</p>"); // 에러처리e.printStackTrace(out);}out.println("</table>");out.println("</body>");out.println("</html>");}}cs 위와같이 servlet클래스를 수정하면 아래와 같이 실행되는 것을 확인할 수 있다.
4) ServletContextListener
DAO를 만들어 db 접근 부분을 분리해 낸 것은 성공했지만 한가지 문제점이 남아있다. 바로 페이지를 호출할 때 마다 MemberDao 객체를 계속 생성한다는 것이다. 이렇게 하면 메모리의 낭비가 생길 뿐더러 각 객체마다 연결이 유지되어 여러개의 연결이 서로 충돌을 일으키는 경우가 생길 수 있다.
이를 해결하기 위해 ServletContextListener를 도입한다. servletContext는 각 application마다 하나씩만 유지 되기 때문에 application이 끝날때까지 유지가 된다. 때문에 모든 사용자가 굥유하는 자원을 저장하기에 적합하다. ServletContext 보관소에 DAO 객체를 저장하면 한 번의 객체 생성으로 application 종료시까지 유지할 수 있다.
src/main/java 아래 listener 패키지를 만들고 ContextLoaderListener 클래스를 생성한다.
12345678910111213141516171819202122package listener;import javax.servlet.ServletContext;import javax.servlet.ServletContextEvent;import javax.servlet.ServletContextListener;import javax.servlet.annotation.WebListener;import dao.MemberDao;@WebListenerpublic class ContextLoaderListener implements ServletContextListener { //ServletContextListener를 상속한다.//contextInitialized 는 context가 시작될 때 수행되는 메서드이다.@Overridepublic void contextInitialized(ServletContextEvent sce) {MemberDao memberDao = new MemberDao("jdbc:mysql://localhost:3306/testdb", "test", "1111");ServletContext sc = sce.getServletContext(); // ServletContext 객체를 받아서sc.setAttribute("memberDao", memberDao); // memberDao 객체를 attribute에 추가해 준다.}}cs 이후 servlet에 memberDao 생성 부분을 다음과 같이 변경한다.
12ServletContext sc = this.getServletContext(); //ServletContext에서 MemberDao를 받는다MemberDao memberDao = (MemberDao)sc.getAttribute("memberDao");이제 JDBC와 DAO를 활용한 회원 리스트를 완벽하게 만들었다.
반응형'framework > Spring' 카테고리의 다른 글
마이바티스(mybatis) 도입 (0) 2018.08.02 JSP 도입과 MVC 패턴 (0) 2018.07.31 서블릿(servlet)을 이용한 회원관리 페이지 만들기 (2) 라이브러리 등록과 회원목록 출력 (0) 2018.07.26 서블릿(servlet)을 이용한 회원관리 페이지 만들기 (1) 회원 테이블 생성 (0) 2018.07.26 Tomcat 서버 연동 해서 index.html 페이지 띄우기 (0) 2018.07.26