본문 바로가기

Program/JSP

Mybatis 사용 예제, Tomcat(HttpServletRequest, HttpSession, Application)

22.08.30 - Mybatis 사용 예제, Tomcat(HttpServletRequest, HttpSession, Application)

Build란?


프로그램이 실행될 수 있도록 장원을 배치하는 것

→ Build툴을 이용하면 class를 생성해줌

Mybatis


목록 넣기

  • mybatis

      package com.academy.web0829.mybatis;
    
      import java.io.InputStream;
    
      import org.apache.ibatis.io.Resources;
      import org.apache.ibatis.session.SqlSession;
      import org.apache.ibatis.session.SqlSessionFactory;
      import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    
      /*
       * mybatis의 설정 정보는 요청이 있을 때 마다, xml을 읽어들일 필요 없고
       * 프로그램이 실행되면 한번만
       * */
      public class ConfigManager {
          private static ConfigManager instance;//싱글톤
    
          SqlSessionFactory sqlSessionFactory;
    
          private ConfigManager() {
              try {
                  String resource = "com/academy/web0829/mybatis/config.xml";
                  InputStream inputStream = Resources.getResourceAsStream(resource);
                  // mybatis를 이용하면 기존에 jdbc에서 sql문 수행시 사용했던 PreparedStatement 를 사용하는게 아니라
                  // 대신 SqlSessio이라는 객체를 이용한다. 아래의 SqlSessionFactory는 SqlSession을 관리 및 반환해주는 객체
                  sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
    
      //sqlSessionFactory로부터 SqlSession을 얻어갈 수 있도록 메소드를 정의
          public SqlSession getSqlSession() {
              return sqlSessionFactory.openSession();
    
          }
    
          public void closeSqlSession(SqlSession sqlSession) {
              sqlSession.close();
          }
    
          public static ConfigManager getInstance() {
              if(instance==null) {
                  instance = new ConfigManager();
              }
              return instance;
          }
      }
      package com.academy.web0829.board.repository;
    
      import org.apache.ibatis.session.SqlSession;
    
      import com.academy.web0829.domain.Board;
      import com.academy.web0829.mybatis.ConfigManager;
    
      public class BoardDAO {
          ConfigManager configManager = ConfigManager.getInstance();
    
          public int insert(Board board) {
              SqlSession sqlSession = configManager.getSqlSession();//mybatis 쿼리 수행 객체
              int result = 0;
              //여기서 sql문 작성하지 않고 XML에 작성된 쿼리문을 호출 
      //        sqlSession.insert("쿼리문을 넣어놓은  xml파일의 id",DTO);
              result = sqlSession.insert("babo.insert",board);
              sqlSession.commit();
              configManager.closeSqlSession(sqlSession);
              return result;
          }
      }
      package com.academy.web0829.board.servlet;
    
      import java.io.IOException;
      import java.io.InputStream;
      import java.io.PrintWriter;
    
      import javax.servlet.ServletException;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
    
      import org.apache.ibatis.io.Resources;
      import org.apache.ibatis.session.SqlSession;
      import org.apache.ibatis.session.SqlSessionFactory;
      import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    
      import com.academy.web0829.board.repository.BoardDAO;
      import com.academy.web0829.domain.Board;
    
      public class RegistServlet extends HttpServlet {
          BoardDAO boardDAO = new BoardDAO();
    
          protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              //파라미터 받기 
              request.setCharacterEncoding("utf-8");
              String title = request.getParameter("title");
              String writer = request.getParameter("writer");
              String content = request.getParameter("content");
    
              Board board = new Board();
              board.setTitle(title);
              board.setWriter(writer);
              board.setContent(content);
    
              int result = boardDAO.insert(board);
    
              response.setContentType("text/html;charset=utf-8");
              PrintWriter out = response.getWriter();
              out.print("<script>");
              if(result==0) {
                  out.print("alert('등록실패');");
                  out.print("history.back();");
              }else {
                  out.print("alert('등록성공');");
                  out.print("location.href='/board/list.jsp';");
              }
              out.print("</script>");
          }
      }
  • xml

      <?xml version="1.0" encoding="UTF-8"?>
      <!--
        Licensed to the Apache Software Foundation (ASF) under one or more
        contributor license agreements.  See the NOTICE file distributed with
        this work for additional information regarding copyright ownership.
        The ASF licenses this file to You under the Apache License, Version 2.0
        (the "License"); you may not use this file except in compliance with
        the License.  You may obtain a copy of the License at
    
            http://www.apache.org/licenses/LICENSE-2.0
    
        Unless required by applicable law or agreed to in writing, software
        distributed under the License is distributed on an "AS IS" BASIS,
        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
        See the License for the specific language governing permissions and
        limitations under the License.
      --><!-- The contents of this file will be loaded for each web application --><Context>
    
          <!-- Default set of monitored resources. If one of these changes, the    -->
          <!-- web application will be reloaded.                                   -->
          <WatchedResource>WEB-INF/web.xml</WatchedResource>
          <WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource>
          <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
    
          <!-- Uncomment this to disable session persistence across Tomcat restarts -->
          <!--
          <Manager pathname="" />
          -->
          <ResourceLink type="javax.sql.DataSource"
                            name="jdbc/myoracle"
                            global="jdbc/myoracle" />
    
          <ResourceLink type="javax.sql.DataSource"
                            name="jdbc/mysql"
                            global="jdbc/mysql" />
      </Context>
      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
      <configuration>
        <environments default="development">
          <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="JNDI">
              <property name="data_source" value="java:comp/env/jdbc/mysql"/>
    
            </dataSource>
          </environment>
        </environments>
        <mappers>
          <mapper resource="com/academy/web0829/mybatis/BoardMapper.xml"/>
        </mappers>
      </configuration>
      <?xml version="1.0" encoding="UTF-8"?>
      <!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor 
          license agreements. See the NOTICE file distributed with this work for additional 
          information regarding copyright ownership. The ASF licenses this file to 
          You under the Apache License, Version 2.0 (the "License"); you may not use 
          this file except in compliance with the License. You may obtain a copy of 
          the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required 
          by applicable law or agreed to in writing, software distributed under the 
          License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 
          OF ANY KIND, either express or implied. See the License for the specific 
          language governing permissions and limitations under the License. --><!-- Note: A "Server" is not itself a "Container", so you may not define 
          subcomponents such as "Valves" at this level. Documentation at /docs/config/server.html --><Server port="8005" shutdown="SHUTDOWN">
          <Listener className="org.apache.catalina.startup.VersionLoggerListener"/>
          <!-- Security listener. Documentation at /docs/config/listeners.html <Listener 
              className="org.apache.catalina.security.SecurityListener" /> -->
          <!-- APR library loader. Documentation at /docs/apr.html -->
          <Listener SSLEngine="on" className="org.apache.catalina.core.AprLifecycleListener"/>
          <!-- Prevent memory leaks due to use of particular java/javax APIs -->
          <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>
          <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>
          <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"/>
    
          <!-- Global JNDI resources Documentation at /docs/jndi-resources-howto.html -->
          <GlobalNamingResources>
              <!-- Editable user database that can also be used by UserDatabaseRealm 
                  to authenticate users -->
              <Resource auth="Container" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" name="UserDatabase" pathname="conf/tomcat-users.xml" type="org.apache.catalina.UserDatabase"/>
    
              <!-- 이 웹 어플리케이션이 사용하게 될 Connection pool을 등록 이와 같이 java코드가 아닌, 외부의 xml과 
                  같은 자원에 정보를 이용하는 방법을 javaSE에서는 JNDI로 지원 -->
              <Resource auth="Container" 
              driverClassName="oracle.jdbc.driver.OracleDriver" 
              maxActive="20" 
              maxIdle="10" 
              maxWait="3000" 
              name="jdbc/myoracle" 
              password="1234" 
              type="javax.sql.DataSource" 
              url="jdbc:oracle:thin:@localhost:1521:XE" 
              username="java"/>
    
              <Resource auth="Container" 
              name="jdbc/mysql" 
              driverClassName="com.mysql.jdbc.Driver" 
              maxActive="20" 
              maxIdle="10" 
              maxWait="3000" 
              password="1234" 
              type="javax.sql.DataSource" 
              url="jdbc:mysql://localhost:3306/javastudy?characterEncoding=UTF-8" 
              username="root"/>
          </GlobalNamingResources>
    
          <!-- A "Service" is a collection of one or more "Connectors" that share 
              a single "Container" Note: A "Service" is not itself a "Container", so you 
              may not define subcomponents such as "Valves" at this level. Documentation 
              at /docs/config/service.html -->
          <Service name="Catalina">
    
              <!--The connectors can use a shared executor, you can define one or more 
                  named thread pools -->
              <!-- <Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="150" 
                  minSpareThreads="4"/> -->
    
              <!-- A "Connector" represents an endpoint by which requests are received 
                  and responses are returned. Documentation at : Java HTTP Connector: /docs/config/http.html 
                  Java AJP Connector: /docs/config/ajp.html APR (HTTP/AJP) Connector: /docs/apr.html 
                  Define a non-SSL/TLS HTTP/1.1 Connector on port 8080 -->
              <Connector connectionTimeout="20000" port="8888" protocol="HTTP/1.1" redirectPort="8443"/>
              <!-- A "Connector" using the shared thread pool -->
              <!-- <Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" 
                  connectionTimeout="20000" redirectPort="8443" /> -->
              <!-- Define an SSL/TLS HTTP/1.1 Connector on port 8443 This connector uses 
                  the NIO implementation. The default SSLImplementation will depend on the 
                  presence of the APR/native library and the useOpenSSL attribute of the AprLifecycleListener. 
                  Either JSSE or OpenSSL style configuration may be used regardless of the 
                  SSLImplementation selected. JSSE style configuration is used below. -->
              <!-- <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" 
                  maxThreads="150" SSLEnabled="true"> <SSLHostConfig> <Certificate certificateKeystoreFile="conf/localhost-rsa.jks" 
                  type="RSA" /> </SSLHostConfig> </Connector> -->
              <!-- Define an SSL/TLS HTTP/1.1 Connector on port 8443 with HTTP/2 This 
                  connector uses the APR/native implementation which always uses OpenSSL for 
                  TLS. Either JSSE or OpenSSL style configuration may be used. OpenSSL style 
                  configuration is used below. -->
              <!-- <Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol" 
                  maxThreads="150" SSLEnabled="true" > <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" 
                  /> <SSLHostConfig> <Certificate certificateKeyFile="conf/localhost-rsa-key.pem" 
                  certificateFile="conf/localhost-rsa-cert.pem" certificateChainFile="conf/localhost-rsa-chain.pem" 
                  type="RSA" /> </SSLHostConfig> </Connector> -->
    
              <!-- Define an AJP 1.3 Connector on port 8009 -->
              <!-- <Connector protocol="AJP/1.3" address="::1" port="8009" redirectPort="8443" 
                  /> -->
    
              <!-- An Engine represents the entry point (within Catalina) that processes 
                  every request. The Engine implementation for Tomcat stand alone analyzes 
                  the HTTP headers included with the request, and passes them on to the appropriate 
                  Host (virtual host). Documentation at /docs/config/engine.html -->
    
              <!-- You should set jvmRoute to support load-balancing via AJP ie : <Engine 
                  name="Catalina" defaultHost="localhost" jvmRoute="jvm1"> -->
              <Engine defaultHost="localhost" name="Catalina">
    
                  <!--For clustering, please take a look at documentation at: /docs/cluster-howto.html 
                      (simple how to) /docs/config/cluster.html (reference documentation) -->
                  <!-- <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/> -->
    
                  <!-- Use the LockOutRealm to prevent attempts to guess user passwords 
                      via a brute-force attack -->
                  <Realm className="org.apache.catalina.realm.LockOutRealm">
                      <!-- This Realm uses the UserDatabase configured in the global JNDI resources 
                          under the key "UserDatabase". Any edits that are performed against this UserDatabase 
                          are immediately available for use by the Realm. -->
                      <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
                  </Realm>
    
                  <Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">
    
                      <!-- SingleSignOn valve, share authentication between web applications 
                          Documentation at: /docs/config/valve.html -->
                      <!-- <Valve className="org.apache.catalina.authenticator.SingleSignOn" 
                          /> -->
    
                      <!-- Access log processes all example. Documentation at: /docs/config/valve.html 
                          Note: The pattern used is equivalent to using pattern="common" -->
                      <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" pattern="%h %l %u %t &quot;%r&quot; %s %b" prefix="localhost_access_log" suffix=".txt"/>
    
                      <Context docBase="web0808" path="/web0808" reloadable="true" source="org.eclipse.jst.jee.server:web0808"/>
                      <Context docBase="web0809" path="/web0809" reloadable="true" source="org.eclipse.jst.jee.server:web0809"/>
                      <Context docBase="web0810" path="/web0810" reloadable="true" source="org.eclipse.jst.jee.server:web0810">
    
                      </Context>
                  <Context docBase="web0811" path="/web0811" reloadable="true" source="org.eclipse.jst.jee.server:web0811"/><Context docBase="web0812" path="/web0812" reloadable="true" source="org.eclipse.jst.jee.server:web0812"/><Context docBase="web0829" path="/" reloadable="true" source="org.eclipse.jst.jee.server:web0829"/></Host>
              </Engine>
          </Service>
      </Server>
      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
      <mapper namespace="babo">
        <!-- 
            앞으로 쿼리문은 java 클래스 안에 두지 말고, mybatis의 xml에 작성하자 
            지금까지 DAO에 작성했던 상투적이고 거창했던 JDBC 코드를 사용하는 것이 아니라 
            개발자가 쿼리문에 집중할 수 있고 유지보수성을 올리기 위한 SQL Mapper중 하나인
            Mybatis 프레임웤을 이용한다...(Hibernate와 mybatis와는 약간의 차이_ 
         -->
         <insert id="insert" parameterType="com.academy.web0829.domain.Board">
                 insert into board(title, writer, content) values(#{title},#{writer},#{content})
         </insert>
    
         <select id ="selectAll">
                 select * from board order by board_id desc
         </select>
      </mapper>

Alias

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases>
        <typeAlias type="com.academy.web0829.domain.Board" alias="Board"/>
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC" />
            <dataSource type="JNDI">
                <property name="data_source"
                    value="java:comp/env/jdbc/mysql" />

            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/academy/web0829/mybatis/BoardMapper.xml" />
    </mappers>
</configuration>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="Board">
  <!-- 
      앞으로 쿼리문은 java 클래스 안에 두지 말고, mybatis의 xml에 작성하자 
      지금까지 DAO에 작성했던 상투적이고 거창했던 JDBC 코드를 사용하는 것이 아니라 
      개발자가 쿼리문에 집중할 수 있고 유지보수성을 올리기 위한 SQL Mapper중 하나인
      Mybatis 프레임웤을 이용한다...(Hibernate와 mybatis와는 약간의 차이_ 
   -->
   <insert id="insert" parameterType="Board">
           insert into board(title, writer, content) values(#{title},#{writer},#{content})
   </insert>

    <!-- 밑에서의 Board는 자료형을 물어보는것 이 BoardDTO에 멤버 변수가 저장되어있는데 이때 컬럼명과 멤버변수 명이 같아야 맵핑을 해준다.
    SqlMapper : Mybatis => Sql문과 맵핑해준다 하고 해서 SqlMapper라고 한다.
    ORMapping : hibernate -> 테이블과 객체를 맵핑 자동으로 쿼리문을 생성해줌 쿼리문을 작성해주지 않음  -->
   <select id ="selectAll" resultType = "Board">
           select board_id, title, writer, content, regdate, hit from board order by board_id desc
   </select>
</mapper>

Mybatis를 이용한 게시판


Servlet

  • DeleteServlet.java

      package com.academy.web0829.board.servlet;
    
      import java.io.IOException;
      import java.io.PrintWriter;
    
      import javax.servlet.ServletException;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
    
      import com.academy.web0829.board.repository.BoardDAO;
    
      public class DeleteServlet extends HttpServlet {
          BoardDAO boardDAO = new BoardDAO();
          @Override
          protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              request.setCharacterEncoding("utf-8");
              int board_id = Integer.parseInt(request.getParameter("board_id"));
              int result = boardDAO.delete(board_id);
    
              response.setContentType("text/html;charset=utf-8");
              PrintWriter out = response.getWriter();
    
              out.print("<script>");
              if(result==0) {
                  out.print("alert('삭제실패');");
                  out.print("history.back();");
              }else {
                  out.print("alert('삭제 성공');");
                  out.print("location.href='/board/list.jsp';");
              }
              out.print("</script>");
          }
      }
  • EditServlet

      package com.academy.web0829.board.servlet;
    
      import java.io.IOException;
      import java.io.PrintWriter;
    
      import javax.servlet.ServletException;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
    
      import com.academy.web0829.board.repository.BoardDAO;
      import com.academy.web0829.domain.Board;
    
      //수정 요청을 처리하는 서블릿
      public class EditServlet  extends HttpServlet{
          BoardDAO boardDAO = new BoardDAO();
          protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              request.setCharacterEncoding("utf-8");
    
              String board_id = request.getParameter("board_id");
              String title = request.getParameter("title");
              String writer = request.getParameter("writer");
              String content = request.getParameter("content");
    
              Board board = new Board();
              board.setBoard_id(Integer.parseInt(board_id));
              board.setTitle(title);
              board.setWriter(writer);
              board.setContent(content);
    
              int result = boardDAO.update(board);
              response.setContentType("text/html;charset=utf-8");
              PrintWriter out = response.getWriter();
    
              out.print("<script>");
              if(result==0) {
                  out.print("alert('등록실패');");
                  out.print("history.back();");
              }else {
                  out.print("alert('등록성공');");
                  out.print("location.href='/board/content.jsp?board_id="+board_id+"';");
              }
              out.print("</script>");
    
          }
      }
  • RegistServlet

      package com.academy.web0829.board.servlet;
    
      import java.io.IOException;
      import java.io.InputStream;
      import java.io.PrintWriter;
    
      import javax.servlet.ServletException;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
    
      import org.apache.ibatis.io.Resources;
      import org.apache.ibatis.session.SqlSession;
      import org.apache.ibatis.session.SqlSessionFactory;
      import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    
      import com.academy.web0829.board.repository.BoardDAO;
      import com.academy.web0829.domain.Board;
    
      public class RegistServlet extends HttpServlet {
          BoardDAO boardDAO = new BoardDAO();
    
          protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              //파라미터 받기 
              request.setCharacterEncoding("utf-8");
              String title = request.getParameter("title");
              String writer = request.getParameter("writer");
              String content = request.getParameter("content");
    
              Board board = new Board();
              board.setTitle(title);
              board.setWriter(writer);
              board.setContent(content);
    
              int result = boardDAO.insert(board);
    
              response.setContentType("text/html;charset=utf-8");
              PrintWriter out = response.getWriter();
              out.print("<script>");
              if(result==0) {
                  out.print("alert('등록실패');");
                  out.print("history.back();");
              }else {
                  out.print("alert('등록성공');");
                  out.print("location.href='/board/list.jsp';");
              }
              out.print("</script>");
          }
      }

JSP

  • content.jsp

      <%@page import="com.academy.web0829.domain.Board"%>
      <%@page import="com.academy.web0829.board.repository.BoardDAO"%>
      <%@ page contentType="text/html;charset=UTF-8"%>
      <%! BoardDAO boardDAO = new BoardDAO(); %>
      <%
          int board_id = Integer.parseInt(request.getParameter("board_id"));
          Board board = boardDAO.select(board_id);
          %>
      <!DOCTYPE html>
      <html>
      <head>
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <style>
      body {font-family: Arial, Helvetica, sans-serif;}
      * {box-sizing: border-box;}
    
      input[type=text], select, textarea {
        width: 100%;
        padding: 12px;
        border: 1px solid #ccc;
        border-radius: 4px;
        box-sizing: border-box;
        margin-top: 6px;
        margin-bottom: 16px;
        resize: vertical;
      }
    
      input[type=button] {
        background-color: #04AA6D;
        color: white;
        padding: 12px 20px;
        border: none;
        border-radius: 4px;
        cursor: pointer;
      }
    
      input[type=button]:hover {
        background-color: #45a049;
      }
    
      .container {
        border-radius: 5px;
        background-color: #f2f2f2;
        padding: 20px;
      }
    
      #comments-list{
          border:1px solid red;
          overflow:hidden;
      }
      #comments-list *{
          float: left;
      }
      .title-style{width:80%}
      .writer-style{width:10%}
      .regdate-style{width:10%}
      </style>
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
      <script>
          function del(){
              if(confirm("삭제하시겠습니까?")){
                  location.href="/board/delete?board_id=<%=board_id%>";
              }
          }
          function edit(){
              if(confirm("수정하시겠어요?")){
                  form1.action = "/board/edit";
                  form1.method = "post";
                  form1.submit();
              }
          }
      </script>
      </head>
      <body >
    
      <div class="container">
        <form name="form1">
            <input type="hidden" name ="board_id" value="<%=board.getBoard_id() %>">    
            <input type="text" name="title" value="<%=board.getTitle()%>">
          <input type="text"name="writer" value="<%=board.getWriter()%>">
          <textarea name="content" style="height:200px"><%=board.getContent() %></textarea>
    
          <input type="button" value="등록" onClick="regist()">
          <input type="button" value="목록" onClick="location.href='/board/list.jsp'">
          <input type="button" value="수정" onClick="edit();">
          <input type="button" value="삭제" onClick="del();">
    
        </form>
    
      </div>
    
      </body>
      </html>
  • list.jsp

      <%@page import="com.academy.web0829.domain.Board"%>
      <%@page import="com.academy.web0829.util.Pager"%>
      <%@page import="java.util.List"%>
      <%@page import="com.academy.web0829.board.repository.BoardDAO"%>
      <%@ page contentType="text/html;charset=UTF-8"%>
      <%! 
          BoardDAO boardDAO = new BoardDAO(); 
          Pager pager = new Pager();
          %>
      <%
          List <Board> boardList = boardDAO.selectAll();
          out.print("게시물 수는 :"+boardList.size());
          pager.init(boardList, request);//공식 계산 
    
    
%>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
table {
    border-collapse: collapse;
    border-spacing: 0;
    width: 100%;
    border: 1px solid #ddd;
}

th, td {
    text-align: left;
    padding: 16px;
}

tr:nth-child(even) {
    background-color: #f2f2f2;
}

.page-style{
    font-size:20px;
    font-weight:bold;
    color:red;
}
</style>
</head>
<body>

    <table>
        <tr>
            <th width="5%">No</th>
            <th width="75%">제목</th>
            <th width="5%">작성자</th>
            <th width="10%">작성일</th>
            <th width="5%">조회수</th>
        </tr>
        <%
            int curPos = pager.getCurPos();
            int num = pager.getNum();
        %>
        <%=pager.getPageSize() %>
    <%for(int i=1; i<=pager.getPageSize(); i++){ %>
    <% if(num<1)break; %>
    <%Board board =boardList.get(curPos++); %>
        <tr>
            <td><%=num-- %></td>
            <td><a href="/board/content.jsp?board_id=<%=board.getBoard_id() %>"><%=board.getTitle() %></a></td>
            <td><%=board.getWriter() %></td>
            <td><%=board.getRegdate() %></td>
            <td><%=board.getHit() %></td>
        </tr>
    <%} %>
        <tr>
            <td colspan="5" style="text-align:center">
            <%for(int i = pager.getFirstPage();i<=pager.getLastPage();i++){ %>
            <%if(i>pager.getTotalPage())break; %>
                [<%=i %>]
                <%} %>
            </td>
        </tr>
        <tr>
            <td colspan="5"><button onClick="location.href='/board/regist.jsp';">글작성</button></td>
        </tr>
    </table>

</body>
</html>
```
  • regist.jsp

      <%@ page contentType="text/html;charset=UTF-8"%>
      <!DOCTYPE html>
      <html>
      <head>
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <style>
      body {font-family: Arial, Helvetica, sans-serif;}
      * {box-sizing: border-box;}
    
      input[type=text], select, textarea {
        width: 100%;
        padding: 12px;
        border: 1px solid #ccc;
        border-radius: 4px;
        box-sizing: border-box;
        margin-top: 6px;
        margin-bottom: 16px;
        resize: vertical;
      }
    
      input[type=button] {
        background-color: #04AA6D;
        color: white;
        padding: 12px 20px;
        border: none;
        border-radius: 4px;
        cursor: pointer;
      }
    
      input[type=button]:hover {
        background-color: #45a049;
      }
    
      .container {
        border-radius: 5px;
        background-color: #f2f2f2;
        padding: 20px;
      }
      </style>
      <script>
      function regist(){
          form1.action="/board/regist";
          form1.method="post";
          form1.submit();
      }
      </script>
      </head>
      <body>
    
      <h3>Contact Form</h3>
    
      <div class="container">
        <form name="form1">
          <input type="text" name="title" placeholder="제목입력">
          <input type="text"name="writer" placeholder="작성자 입력">
          <textarea name="content" placeholder="내용작성" style="height:200px"></textarea>
          <input type="button" value="등록" onClick="regist()">
          <input type="button" value="목록" onClick="location.href='/board/list.jsp'">
        </form>
      </div>
    
      </body>
      </html>

XML

  • web.xml

      <?xml version="1.0" encoding="UTF-8"?>
      <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns="http://xmlns.jcp.org/xml/ns/javaee"
          xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
          id="WebApp_ID" version="4.0">
          <display-name>web0829</display-name>
    
          <servlet>
              <servlet-name>registServlet</servlet-name>
              <servlet-class>com.academy.web0829.board.servlet.RegistServlet</servlet-class>
          </servlet>
          <servlet-mapping>
              <servlet-name>registServlet</servlet-name>
              <url-pattern>/board/regist</url-pattern>
          </servlet-mapping>
    
          <servlet>
              <servlet-name>deleteServlet</servlet-name>
              <servlet-class>com.academy.web0829.board.servlet.DeleteServlet</servlet-class>
          </servlet>
          <servlet-mapping>
              <servlet-name>deleteServlet</servlet-name>
              <url-pattern>/board/delete</url-pattern>
          </servlet-mapping>
    
          <servlet>
              <servlet-name>editServlet</servlet-name>
              <servlet-class>com.academy.web0829.board.servlet.EditServlet</servlet-class>
          </servlet>
          <servlet-mapping>
              <servlet-name>editServlet</servlet-name>
              <url-pattern>/board/edit</url-pattern>
          </servlet-mapping>
      </web-app>

mybatis

  • ConfigManger.java

      package com.academy.web0829.mybatis;
    
      import java.io.InputStream;
    
      import org.apache.ibatis.io.Resources;
      import org.apache.ibatis.session.SqlSession;
      import org.apache.ibatis.session.SqlSessionFactory;
      import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    
      /*
       * mybatis의 설정 정보는 요청이 있을 때 마다, xml을 읽어들일 필요 없고
       * 프로그램이 실행되면 한번만
       * */
      public class ConfigManager {
          private static ConfigManager instance;//싱글톤
    
          SqlSessionFactory sqlSessionFactory;
    
          private ConfigManager() {
              try {
                  String resource = "com/academy/web0829/mybatis/config.xml";
                  InputStream inputStream = Resources.getResourceAsStream(resource);
                  // mybatis를 이용하면 기존에 jdbc에서 sql문 수행시 사용했던 PreparedStatement 를 사용하는게 아니라
                  // 대신 SqlSessio이라는 객체를 이용한다. 아래의 SqlSessionFactory는 SqlSession을 관리 및 반환해주는 객체
                  sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
    
      //sqlSessionFactory로부터 SqlSession을 얻어갈 수 있도록 메소드를 정의
          public SqlSession getSqlSession() {
              return sqlSessionFactory.openSession();
    
          }
    
          public void closeSqlSession(SqlSession sqlSession) {
              sqlSession.close();
          }
    
          public static ConfigManager getInstance() {
              if(instance==null) {
                  instance = new ConfigManager();
              }
              return instance;
          }
      }
  • BoardMapper.xml

      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
      <mapper namespace="Board">
        <!-- 
            앞으로 쿼리문은 java 클래스 안에 두지 말고, mybatis의 xml에 작성하자 
            지금까지 DAO에 작성했던 상투적이고 거창했던 JDBC 코드를 사용하는 것이 아니라 
            개발자가 쿼리문에 집중할 수 있고 유지보수성을 올리기 위한 SQL Mapper중 하나인
            Mybatis 프레임웤을 이용한다...(Hibernate와 mybatis와는 약간의 차이_ 
         -->
         <insert id="insert" parameterType="Board">
                 insert into board(title, writer, content) values(#{title},#{writer},#{content})
         </insert>
    
          <!-- 밑에서의 Board는 자료형을 물어보는것 이 BoardDTO에 멤버 변수가 저장되어있는데 이때 컬럼명과 멤버변수 명이 같아야 맵핑을 해준다.
          SqlMapper : Mybatis => Sql문과 맵핑해준다 하고 해서 SqlMapper라고 한다.
          ORMapping : hibernate -> 테이블과 객체를 맵핑 자동으로 쿼리문을 생성해줌 쿼리문을 작성해주지 않음  -->
         <select id ="selectAll" resultType = "Board">
                 select board_id, title, writer, content, regdate, hit from board order by board_id desc
         </select>
    
         <!-- 한 데이터 가져오기 -->
         <select id="select" resultType="Board" parameterType="int">
                 select board_id, title, writer, content, regdate, hit from board where board_id = #{board_id}
         </select>
         <delete id="delete" parameterType="int">
                 delete from board where board_id=#{board_id}
         </delete>
    
         <update id="update"  parameterType="Board" >
                 update board set title=#{title}, writer=#{writer}, content=#{content} where board_id=#{board_id}
         </update>
      </mapper>
  • config.xml

      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
      <configuration>
          <typeAliases>
              <typeAlias type="com.academy.web0829.domain.Board" alias="Board"/>
          </typeAliases>
          <environments default="development">
              <environment id="development">
                  <transactionManager type="JDBC" />
                  <dataSource type="JNDI">
                      <property name="data_source"
                          value="java:comp/env/jdbc/mysql" />
    
                  </dataSource>
              </environment>
          </environments>
          <mappers>
              <mapper resource="com/academy/web0829/mybatis/BoardMapper.xml" />
          </mappers>
      </configuration>

DAO

  • BoardDAO

      package com.academy.web0829.board.repository;
    
      import java.util.List;
    
      import org.apache.ibatis.session.SqlSession;
    
      import com.academy.web0829.domain.Board;
      import com.academy.web0829.mybatis.ConfigManager;
    
      public class BoardDAO {
          ConfigManager configManager = ConfigManager.getInstance();
    
          public int insert(Board board) {
              SqlSession sqlSession = configManager.getSqlSession();//mybatis 쿼리 수행 객체
              int result = 0;
              //여기서 sql문 작성하지 않고 XML에 작성된 쿼리문을 호출 
      //        sqlSession.insert("쿼리문을 넣어놓은  xml파일의 id",DTO);
              result = sqlSession.insert("Board.insert",board);
              sqlSession.commit();
              configManager.closeSqlSession(sqlSession);
              return result;
          }
    
          //목록 가져오기 
          public List selectAll() {
              SqlSession sqlSession = configManager.getSqlSession();
              List list =null;
              list = sqlSession.selectList("Board.selectAll");
              configManager.closeSqlSession(sqlSession);
              return list;
          }
    
          //한건 가져오기
          public Board select(int board_id) {
              SqlSession sqlSession = configManager.getSqlSession();
              Board board = null;
              board = sqlSession.selectOne("Board.select", board_id);
              configManager.closeSqlSession(sqlSession);
    
              return board;
          }
    
          //삭제
          public int delete(int board_id) {
              SqlSession sqlSession = configManager.getSqlSession();
              int result =0;
    
              result = sqlSession.delete("Board.delete",board_id);
              sqlSession.commit();
              configManager.closeSqlSession(sqlSession);
              return result;
          }
    
          //수정 
          public int update(Board board) {
              int result = 0;
              SqlSession sqlSessions = configManager.getSqlSession();
    
              result =sqlSessions.update("Board.update", board);
              sqlSessions.commit();
              configManager.closeSqlSession(sqlSessions);
              return result;
    
          }
      }

DTO

  • Board

      package com.academy.web0829.domain;
    
      import lombok.Data;
    
      @Data
      public class Board {
          private int board_id;
          private String title;
          private String writer;
          private String content;
          private String regdate;
          private int hit;
    
    
}
```

JAVA

  • Pager.java

      package com.academy.web0829.util;
    
      import java.util.List;
    
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
    
      import lombok.Data;
    
      @Data
      public class Pager {
          private int totalRecord;//총레코드 수 
          private int pageSize =10 ;//페이지당 보여질 레코드 수 
          private int totalPage;
          private int blockSize=10;//블럭당 보여질 페이지 수 
          private int currentPage=1;//처음 들어왔을때
          private int firstPage;//블럭당 시작 페이지
          private int lastPage;//블럭당 마지막 페이지
          private int curPos; //페이지당 시작 index(커서의 위치와 같다.)
          private int num;//페이지당 게시물 시작 번호
    
          //공식을 대입하기 위함 
          public void init(List list, HttpServletRequest request) {
              totalRecord = list.size();
              totalPage = (int)Math.ceil((float)totalRecord/pageSize);
              if(request.getParameter("currentPage")!=null) {
                  currentPage = Integer.parseInt(request.getParameter("currentPage"));
              }
              firstPage = currentPage-(currentPage-1)% blockSize;
              lastPage = firstPage+(blockSize-1);
              curPos = (currentPage-1)*pageSize;
              num = totalRecord-curPos;
          }
      }

Tomcat


HttpServletRequest : 자료형

내장 객체 :request

클라이언트에게 response를 전달하게 될때 죽는다. (이때 request,thread와 같이 죽음)

HttpSession : 자료형

내장 객체 : session

session :tomcat 에서 처음 접속한 클라이언트에 대해 새롭게 생성

session은 브라우저를 닫지 않으면 죽지 않는다.

Application : JSP 내장객체


application은 tomcat을 닫지 않는 이상 죽지 않는다.

//jsp의 내장 객체 중 application 내장 객체의 생명력을 테스트한다.
    //이름 그대로 application(웹 어플리케이션)은 Tomcat 서버를 가동할때 생성되어 
    //프로그램이 끝날때 까지 즉 Tomcat 서버를 종료할때까지 생명력을 유지할 수 있다. 
    //위의 설명이 Application scope
    application.setAttribute("id", "batman");
    out.print(application.getAttribute("id"));

Tomcat이 실행될때 잡아내는 listener


  • java

      package com.academy.web0829.listener;
    
      import javax.servlet.ServletContext;
      import javax.servlet.ServletContextEvent;
      import javax.servlet.ServletContextListener;
    
      public class MyListener implements ServletContextListener{
          String name = "superman";
          @Override
          public void contextInitialized(ServletContextEvent sce) {
              // TODO Auto-generated method stub
              System.out.println("서버 가동 감지");
              //application 내장객체에 name 을 담아놓으면, 프로그램이 끝날때 까지 name을 사용할 수 있다.
              ServletContext application = sce.getServletContext();
              application.setAttribute("nick", name);
          }
    
          @Override
          public void contextDestroyed(ServletContextEvent sce) {
              System.out.println("서버 종료 감지");
          }
      }
  • xml

      <!-- web.xml에는 서버 가동과 관련된 이벤트를 제어하는 리스너가 지원된다. -->
          <listener>
              <listener-class>com.academy.web0829.listener.MyListener</listener-class>
          </listener>
    
    
    //jsp의 내장 객체 중 application 내장 객체의 생명력을 테스트한다.
    //이름 그대로 application(웹 어플리케이션)은 Tomcat 서버를 가동할때 생성되어 
    //프로그램이 끝날때 까지 즉 Tomcat 서버를 종료할때까지 생명력을 유지할 수 있다. 
    //위의 설명이 Application scope
    application.setAttribute("id", "batman");
    out.print(application.getAttribute("id"));
    out.print(application.getAttribute("nick"));
```