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 "%r" %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"));
```'Program > JSP' 카테고리의 다른 글
| JSP 내장 객체, Model(스크립트, Model1, Model), Notice_Project-1 (0) | 2022.12.27 |
|---|---|
| Mybatis JOIN 사용, MVC, Forward 데이터 전송, DispatcherServlet (0) | 2022.12.27 |
| MyBatis, 대형 어플리케이션 구조, Maven 사용, Mapper 생성, Lombok (0) | 2022.12.27 |
| 대댓글 만들기 (0) | 2022.12.27 |
| 게시판 댓글 생성, 댓글 수 표시 (0) | 2022.12.25 |