BoostCourse | 방명록 만들기

judyzero·2025년 2월 2일

BoostCourse

목록 보기
4/7

개발환경

  • JDK 22
  • Tomcat 11.0.2
  • MySQL
  • IntelliJ

요구사항


개발 순서

1. MySQL 연결

1-1. mysql 서버에 guestboard DB 만들기

  • cd /usr/local/mysql/bin : mysql 폴더로 이동
  • ./mysql -u root -p : mysql 실행
  • create database guestboard; : DB 생성

1-2. guestboard DB 안에 gusestbook 테이블 만들기

CREATE TABLE `guestbook` (
    ->   `id` INT(11) NOT NULL AUTO_INCREMENT COMMENT 'guestbook id',
    ->    `name` VARCHAR(255) NOT NULL COMMENT 'user name',
    ->   `content` TEXT NOT NULL COMMENT 'guestbook content',
    ->   `regdate` DATETIME NULL DEFAULT NULL COMMENT '등록일',
    ->   PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;

해당 명령어를 입력하여 Query OK, 0 rows affected, 2 warnings (0.02 sec) 이게 나온다면, 테이블이 제대로 생성된 것이다.

  • describe guestbook; : 해당 명령어를 통해 guestbook이 제대로 생성되었는지 다시 확인해보았다.

1-3.connectuser에 권한 부여하기

grant all privileges on guestboard.* to connectuser@'%';
grant all privileges on guestboard.* to connectuser@'localhost';
grant all privileges on guestbook.* to connectuser@'%';
grant all privileges on guestbook.* to connectuser@'localhost';
flush privileges;
사실 DB에 권한을 주면 된다해서 guestboard DB에 권한을 주었는데, 제대로 안돼서 테이블에도 권한을 부여했다.

1-4. IntelliJ에 mysql 연결하기

매번 터미널에서 보기에는 너무 귀찮다.
그래서 보통 IntelliJ에 연결하여 보는 편인데, 한번 해보자.
mysql 사이트에 들어가서 mysql-connector-j-9.20을 설치하였다.
압축을 푼 뒤에, /Users/yuda/Library/Java/JavaVirtualMachines/openjdk-22.0.1/Contents/Home/lib
해당 경로에 mysql-connector-j-9.20을 넣었다.
이제, IntelliJ에 들어가서 cmd+; 으로 프로젝트 구조에 들어간다.

라이브러리 -> +버튼 -> Java를 누른 뒤,mysql-connector-j-9.20을 불러온다.

<dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.33</version>
    </dependency>

pom.xml에 해당 depnedency를 추가하였다.

데이터베이스에도 Mysql을 추가해보겠다.

데이터베이스 -> +버튼 -> Data Source -> MySQL을 누른다.

권한을 준 user name과 password를 입력하고, 데이터베이스 이름도 입력한다. Test connection을 통해 DB에 연결되는지 확인하면 모든 준비가 끝났다.

2. Dto, Dao 작성

Dto: Data transfer object

package com.boostcourse.guestbook2.dto;

import java.util.Date;

public class Guestbook {
    private Long id;
    private String name;
    private String content;
    private Date regdate;

    public Guestbook(Long id, String name, String content, Date regdate) {
        this.id = id;
        this.name = name;
        this.content = content;
        this.regdate = regdate;
    }

    public Guestbook(String name, String content) {
        this.name = name;
        this.content = content;
        this.regdate = new Date();
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public Date getRegdate() {
        return regdate;
    }

    public void setRegdate(Date regdate) {
        this.regdate = regdate;
    }

    @Override
    public String toString() {
        return "Guestbook{" +
            "id=" + id +
            ", name='" + name + '\'' +
            ", content='" + content + '\'' +
            ", regdate=" + regdate +
            '}';
    }
}

DB table의 column 내용과 같도록 Guestbook 객체에 id, name content, regdate를 넣어놓았다. getter와 setter를 생성해놓았다.

Dao: Data access Object

package com.boostcourse.guestbook2.dao;

public class GuestbookDao {
    private static String dburl = "jdbc:mysql://localhost:3306/guestboard?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true";
    private static String dbUser = "connectuser";
    private static String dbpasswd = "connect123!@#";

    public static List<Guestbook> getGuestbooks(){
        List<Guestbook> list = new ArrayList<>();
        String getGuestbooksSQL = "select * from guestbook";
        try{
            Class.forName("com.mysql.cj.jdbc.Driver");
            Connection conn = DriverManager.getConnection(dburl, dbUser, dbpasswd);
            PreparedStatement ps = conn.prepareStatement(getGuestbooksSQL);
            ResultSet rs = ps.executeQuery();
            while(rs.next()){
                Long id = rs.getLong("id");
                String name = rs.getString("name");
                String content = rs.getString("content");
                Date regDate = rs.getDate("regdate");
                Guestbook guestbook = new Guestbook(id, name, content, regDate);
                System.out.println(guestbook);
                list.add(guestbook);
            }
        } catch(Exception ex){
            ex.printStackTrace();
        }
        return list;
    }

    public static void addGuestbook(Guestbook guestbook){
        String addGuestbookSQL = "insert into guestbook (name, content, regdate) values (?, ?, NOW())";
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            Connection conn = DriverManager.getConnection(dburl, dbUser, dbpasswd);
            PreparedStatement ps = conn.prepareStatement(addGuestbookSQL);
            ps.setString(1, guestbook.getName());
            ps.setString(2, guestbook.getContent());
            ps.executeUpdate();
        } catch(Exception ex){
            ex.printStackTrace();
        }
    }
}

여기에는 DB와 직접적으로 연결해서 작업을 수행하는 역할이다.

  • getGuestbooks() 함수는 DB의 모든 데이터를 가져오는 역할을 한다.
    select * from guestbook 명령어를 통해 DB의 모든 데이터를 불러오도록 하였다. while(rs.next())를 통해 모든 데이터를 순회하도록 하였고, 가져온 데이터를 객체로 만들어 list에 추가하도록 하였다.

  • addGuestbook() 함수는 DB에 새로운 데이터를 추가할 때 사용하는 함수이다.
    사용자가 입력한 이름과 내용 정보를 불러오고, ps.executeUpdate()를 통해 DB에 업데이트한다.
    이때, id는 auto increment로 설정하였기 때문에 DB에서 자체적으로 생성한다.
    regDate는 생성된 날짜로, NOW() 함수를 통해 현재 시간을 넣도록 처리하였다.

3. Servlet 작성

이전에 servlet은 클라이언트의 요청을 처리하고, 결과값을 반환한다고 배웠다.
이제 실제로 servlet을 통해 사용자 요청을 처리해보자.

3-1. GuestbookWriteServlet 작성

@WebServlet("/guestbooks/write")
public class GuestbookWriteServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String name = request.getParameter("name");
        String content = request.getParameter("content");
        Guestbook guestbook = new Guestbook(name, content);
        GuestbookDao.addGuestbook(guestbook);
        response.sendRedirect("/guestbook2_war_exploded/guestbooks");
    }
}

해당 서블릿은 @WebServlet("/guestbooks/write")을 통해 볼 수 있듯이, /guestbooks/write 여기로 요청이 들어와야 실행한다.
doPost 메소드를 통해 사용자가 입력한 name과 content 내용을 받는다.
그리고 guestbook 객체로 만들어서, 위에 작성해놨던 addGuestbook 함수로 보낸다.

3-1. GuestbookListServlet 작성

@WebServlet("/guestbooks")
public class GuestbookListServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setAttribute("list", GuestbookDao.getGuestbooks());
        request.getRequestDispatcher("/WEB-INF/guestbook/guestbook.jsp").forward(request, response);
    }
}

/guestbooks으로 요청이 들어올 때 처리되는 함수이다.
해당 URI로 get 요청이 들어오면 doGet 메소드가 실행된다.
이때는, request에 list의 값으로 getGuestbooks()로 얻은 데이터를 추가한다.
그리고 이 request 객체는 guestbook.jsp를 통해 포워딩된다.

4. jsp 작성

<%@ page import="com.boostcourse.guestbook2.dto.Guestbook" %>
<%@ page import="java.util.List" %>
<%@ page contentType="text/html; charset=utf-8" %>
<html>
<head>
    <title>방명록</title>
    <style>
      .guestbook {
        padding: 5px 0px 5px 5px;
        margin-bottom: 5px;
        border-bottom: 1px solid #efefef;
        font-size: 12px;
      }
    </style>
</head>
<body>

<div class="guestbooks">
    <%-- 리스트를 직접 반복하며 출력 --%>
    <%
        List<Guestbook> list = (List<Guestbook>) request.getAttribute("list");
        for (Guestbook guestbook : list) {
    %>
    <div class="guestbook">
        <div> <label>id : </label> <%= guestbook.getId() %></div>
        <div> <label>name : </label> <%= guestbook.getName() %></div>
        <div> <p><%= guestbook.getContent() %></p></div>
        <div> <label>regdate : </label> <%= guestbook.getRegdate() %></div>
    </div>
    <%
        }
    %>
</div>

<br><br><br>

<form method="post" action="guestbooks/write">
    이름 : <input type="text" name="name"><br>
    내용 :
    <textarea name="content" cols="50" rows="5"></textarea><br>
    <input type="submit" value="확인">
</form>
</body>
</html>

0개의 댓글