본문 바로가기
코딩/수업 정리

21.01.12 Tue [035]

by 6^6 2021. 1. 12.
728x90

jsp

 

 

jsp_lecture_24

 

test를 꼭 써야함

<%@page import="java.util.ArrayList"%>
<%@ page language="java" contentType="text/html; charset=EUC-KR"
	pageEncoding="EUC-KR"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>Insert title here</title>
</head>
<body>

	<c:set var="vatName" value="varValue" />
	vatName :
	<c:out value="${vatName}" />
	<br />
	<c:remove var="vatName" />
	vatName :
	<c:out value="${vatName}" />
	</h3>

	<hr />

	<c:catch var="error">
		<%=2 / 0%>
	</c:catch>
	<br />
	<c:out value="${error}" />

	<hr />

	<c:if test="${1+2==3}">
		1 + 2 = 3
	</c:if>

	<c:if test="${1+2!=3}">
		1 + 2 != 3
	</c:if>

	<hr />

	<c:forEach var="fEach" begin="0" end="30" step="3">
		${fEach}
	</c:forEach>

	<hr />
	<!-- ↓이런식으로 많이 씀 -->
	<%
		/* ====String 배열===== */

	String[] arr = { "순두부", "된장찌개", "제육덮밥" };
	request.setAttribute("menu", arr);

	/* ====ArrayList 배열===== */

	ArrayList<String> arr1 = new ArrayList<String>();
	arr1.add("순두부1");
	arr1.add("된장찌개1");
	arr1.add("제육덮밥1");
	request.setAttribute("menu1", arr1);
	%>

	<ul>
		<c:forEach var="dish" items="${menu}">
			<li>${dish }</li>
		</c:forEach>

	</ul>

	<ul>
		<c:forEach var="dish" items="${menu1}">
			<li>${dish }</li>
		</c:forEach>

	</ul>

</body>
</html>

 

 

 

fEach → 배열에 쓰인다.

 

 

 

 

 

 

jsp_lecture_20

실무에선 반드시 커넥션풀 을 사용한다.

 

서버가 터지면 알아서 해결해야한다. - 그 원인과 해결방법을 알아가는 커넥션 풀(DBCP)

 

웹브라우저=클라이언트

서버(DBCP)=접속하는 곳. (프로그래밍쪽에서 죽을수도있고 메모리가 깎여서 죽을수도있고 원인은 많음) 근데 서버에서 죽는 경우엔 많지 않음

 

DataBase= 오라클서버. 톰캣 ★서버에서 DB(오라클서버)로 접속하는 구간에서 서버가 죽는일이 많다.★

서버에 몇만명 몰리게되면 con = DriverManage.getConnection(url,uid,upw) 이부분에서 터지는경우가 제일 많다.

저렇게 코드짜면 서버 그냥 죽는다. 천명정도는 괜찮지만 십만명은 그냥 죽음.

 

그럼어떻게 안죽게함? ( onebyone1.tistory.com/49 [EmpDAO.java] 예제)

서버쪽에서 connection 객체를 미리 생성한다.(Connection con= null; con=DriverManage.get

그 생성한 걸 커넥션 풀(DBCP)에 저장하고 만약 1000명만 저장했다하면 1000명만 받고 다음사람들은 줄을 세워놓는다.

[EmpDAO.java 中 일부 발췌]
public ArrayList<EmpVO> empSelect() {
		ArrayList<EmpVO> dtos = new ArrayList<EmpVO>();
 
		Connection con = null;
		Statement stmt = null;
		ResultSet rs = null;
		String sql = "select * from emp";
		try {
 
			con = DriverManager.getConnection(url, uid, upw);//★이 부분에서 서버 죽음★
			stmt = con.createStatement();
			/*rs = stmt.executeQuery("select * from emp");
								// 해당 데이터를 갖고 옴*/
			rs = stmt.executeQuery(sql);//바뀔수있으니까 이렇게 생성
			
			while (rs.next()) {//12개 다 받아오는 로직 rs.next()
				String name = rs.getString("ename");//String이니까
				int empno = rs.getInt("empno");//int니까
				String job = rs.getString("job");
 
				EmpVO eDto = new EmpVO(name, empno, job);
				dtos.add(eDto); // ArrayList 로 관리
			}

 

 

 

 

커넥션풀은 반드시 서버쪽에서 만들어야하기 때문에 밑에 예제로 세팅을 한다.(서버쪽에 context.xml을 만든다.)

[server.xml]- Servers - Tomcat v9.0 Server at localhost - server.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="" />
    -->
    
     <Resource 
       auth="Container" 
       driverClassName="oracle.jdbc.OracleDriver" 
       maxIdle="10" 
       maxTotal="20" 
       maxWaitMillis="-1" 
       name="jdbc/oracle" 
       password="tiger" 
       type="javax.sql.DataSource" 
       url="jdbc:oracle:thin:@127.0.0.1:1521:xe" 
       username="scott"
    />
   
   <!--
    auth : 컨테이너를 자원 관리자로 기술
    name : JDBC이름, 변경 가능
    driverClassName : JDBC 드라이버
    type : 웹에서 이 리소스를 사용할 때 DataSource로 리턴됨
    username : 접속계정
    password : 접속할 계정 비밀번호
    
    loginTimeout : 연결 끊어지는 시간
    maxActive : 최대 연결 가능한 Connection수 (기본 20개)
    maxIdle : Connection pool 유지를 위해 최대 대기 connection 숫자
    maxWait : 사용 가능한 커넥션이 없을 때 커넥션 회수를 기다리는 시간 (1000 = 1초)
    testOnBorrow : db에 test를 해볼 것인지
   -->
       
</Context>

 

 

 

 

 

jsp_lecture_27

MVC패턴을 이용한 게시판만들기

↑이그림 하나하나 코드 하나하나 다 외우기

 

ui화면, command 하나하나가 객체이다.

 

DOA = data object 

로직실행부분이 model (ex. 가위바위보 if문 넣은부분)

화면ui가 view

요청부분이 controller

 

↑가장간단한 게시판 예시

설계하기 어려운 DB생성

댓글구성에 대해 무조건 외우기

 

오른쪽화면 1,2,3,4,,, 가 bid이다. - primary 키 속성을 주는것이다.(중복되면 에러남)

bName = 작성자

bTitle  = 글제목

bContent = 글내용

bDate = 글작성일자

bHit = 글조회수

bGroup, bStep, bIndent = 댓글★★

 

Group

bid 에서 원글번호는 1번, 댓글,대댓글,대대댓글의 번호도 2번아니고 1번(자식이 되는것임. 그룹화)

 

Step 

댓글을 표현해야할때 원글에서 세로를 나타낼때.(몇번째 밑에있는가)

 

Indent

가로로 몇번째인지.(몇번째 밑에있어서 가로로 몇번째에 있는가)(원글의 답글인지 답글의 답글인지를 구분하기위한 들여쓰기)

 

 

→삼총사 만나면 댓글이 만들어진다...

 

 

 

 

create secreate sequence mvc_board_seq; //이걸 쓰는 이유는 생성된 테이블에 자동으로 값을 넣어주기 때문 

 

-- bGroup : 원글에 달린 답변글 전체 
--          그룹 넘버는 답변들도 원글과 똑같은 넘버를 가지고 있다.                    
-- bStep : 위에서 몇 번째 위치할 것이냐 
-- bIndent : 들여쓰기 
--           원글에 바로 단 답변은 한 번만 들여쓰면 된다. 
--           그 답변의 답변은 원글의 답변보다 Step은 하나 높고  
--           Indent도 한번 더 들어가야 한다.  
--           답변의 답변의 답변은 step은 가장 높고 
--           들여쓰기는 한 번만 더 하면 된다. 
 
--           실행은 ctrl+enter

 

create table mvc_board(
bId NUMBER(4) PRIMARY KEY,
bName VARCHAR2(20),
bTitle VARCHAR2(100),
bContent VARCHAR2(300),
bDate DATE DEFAULT SYSDATE,
bHit NUMBER(4) DEFAULT 0,
bGroup NUMBER(4),
bStep NUMBER(4),
bIndent NUMBER(4)
);
create sequence mvc_board_seq;

insert into mvc_board(bId, bName, bTitle, bContent, 
bHit, bGroup, bStep, bIndent)
values (mvc_board_seq.nextval, 'abcd', 'is title', 'is content',
0, mvc_board_seq.currval, 0, 0);

select * from mvc_board;

commit; //★ 커밋 이 부분 해줘야 서블렛 실행됨
insert into mvc_board(bId, bName, bTitle, bContent, 
bHit, bGroup, bStep, bIndent)
values (mvc_board_seq.nextval, 'abcd', 'is title', 'is content',
0, mvc_board_seq.currval, 0, 0); 이거 실행 한번 더해주면 bid에 알아서 1행이 더 삽입된다.

 

 

 

jsp_lecture_28

 

 

 

controller는 120% class-servlet으로 짠다!!!!(doget dopost)

==========================================

package edu.bit.ex.command;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public interface BCommand {
//인터페이스안에 추상함수가 들어감
	abstract void execute(HttpServletRequest request, 
			HttpServletResponse response);

	//지금하고있는것은 list갖고와서 list뿌리는것.
	//list갖고오기 - BListCommand 자손만들기
	
}
[BListCommand.java] src-edu.bit.ex.command-BListCommand.java
package edu.bit.ex.command;

import java.util.ArrayList;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import edu.bit.ex.dao.BDao;
import edu.bit.ex.dto.BDto;

//지금하고있는것은 list갖고와서 list뿌리는것. 중
//list갖고오기
public class BListCommand implements BCommand {
	// implements 자손이 구현하라

	@Override
	public void execute(HttpServletRequest request, HttpServletResponse response) {

		BDao dao = new BDao(); // 그림에서 Dao가 command 호출하고 있는부분
		// package edu.bit.ex.dao;
		// class BDao 생성
		
		ArrayList<BDto> dtos = dao.list();
		request.setAttribute("list", dtos);
	}
}

 

[BFrontController.java] src-edu.bit.ex.controller-BFrontController.java

package edu.bit.ex.controller;
//패키지명 반드시 이렇게 쓰기

import java.io.IOException;

import javax.servlet.RequestDispatcher;
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 edu.bit.ex.command.BCommand;
import edu.bit.ex.command.BListCommand;

@WebServlet("*.do")
// 유저가 url치고들어오는데 뭘치고 들어오든 .do(controll로 들어오는거)면 다 받겠다.
public class BFrontController extends HttpServlet {
	private static final long serialVersionUID = 1L;

	public BFrontController() {
		super();

	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		System.out.println("doGet");
		actionDo(request, response);
	}

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

		doGet(request, response);
	}

	private void actionDo(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException { // 한글처리했을때 에러나서 throws 추가
		//doGet, doPost 둘 중 하나의 요청을 받으면 actionDo 메서드로 넘겨준다.
        System.out.println("actionDo"); // .do로 들어오면 actionDo로 표시하겠다.

		request.setCharacterEncoding("EUC-KR");

		String viewPage = null; // FrontController에서 view들을 결정하는것.
		BCommand command = null; // 그림에 command command 객체가 바로 이거.
		// Command가 인터페이스(자손구현하는것)이다.

		String uri = request.getRequestURI();
		String conPath = request.getContextPath();
		String com = uri.substring(conPath.length());

		System.out.println(uri);
		System.out.println(conPath);
		System.out.println(com);

		if (com.equals("/list.do")) {
						// .list.do 이렇게 치고 들어오게 링크주는것.
			command = new BListCommand();
			//↑다형성 적용. BCommand는 부모
			command.execute(request, response);
			viewPage = "list.jsp";
		}

		
		//리스트화면 뿌려주는게 dispatcher - 이 두줄은 그냥 외우기★
		RequestDispatcher dispatcher = request.getRequestDispatcher(viewPage);
												//viewpage = list.jsp 임
		dispatcher.forward(request, response);
		//포워딩시키는 이유는? BListcommand.jsp에 requestsetAttribute list실행해주려고.

	}
}
[BDao.java] src- edu.bit.ex.dao-BDao.java
package edu.bit.ex.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Timestamp;
import java.util.ArrayList;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;

import edu.bit.ex.dto.BDto;

public class BDao {
	DataSource dataSource;
	// 이게 바로 커넥션풀객체 = 데이터소스
	
	public BDao() {

		try {
			Context context = new InitialContext();
//context는 해당서버안에있는 context.xml에서 만든 Resource 읽어오는것이다.

			dataSource = (DataSource) context.lookup("java:comp/env/jdbc/oracle");
			// java:~~은 고슬링아저씨가 만들어놓은것.
			// context에서 뭘찾냐? env(환경설정)에서 jdbc(Resource에 name에 있는걸 불러옴. 따라서 jdbc/뒤에있는거랑 똑같이
			// 써야함
			// 정리 : /jdbc/oracle은 커넥션풀에있는 name에있는거랑 똑같이 적어줘야한다.

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public ArrayList<BDto> list() {
		// BDto는 게시판
		ArrayList<BDto> dtos = new ArrayList<BDto>();
		Connection connection = null;
		PreparedStatement preparedStatement = null;
		//preparedStatement가 속도, 사용법, 보안 전부 좋음.
		ResultSet resultSet = null;

		try {
			connection = dataSource.getConnection();
			// 예전엔 drivermanager.으로 가져왔는데 getConnection해서 바로 꺼내옴. 한줄로끝
			String query = "select bId, bName, bTitle, bContent, bDate, bHit, bGroup, bStep, bIndent from mvc_board order by bGroup desc, bStep asc";
			// order by bGroup desc, bStep asc 이부분안해주면 댓글 정렬이 안된다. 이거까지 해야 댓글순서대로 제대로 끌고 오는
			// 것임. 반드시 외울것!★

			preparedStatement = connection.prepareStatement(query);
			resultSet = preparedStatement.executeQuery();
			

			while (resultSet.next()) {
				int bId = resultSet.getInt("bId");
				String bName = resultSet.getString("bName");
				String bTitle = resultSet.getString("bTitle");
				String bContent = resultSet.getString("bContent");
				Timestamp bDate = resultSet.getTimestamp("bDate");
				//timestamp는 java sql로 임포트
				int bHit = resultSet.getInt("bHit");
				int bGroup = resultSet.getInt("bGroup");
				int bStep = resultSet.getInt("bStep");
				int bIndent = resultSet.getInt("bIndent");

				BDto dto = new BDto(bId, bName, bTitle, bContent, bDate, bHit, bGroup, bStep, bIndent);
				dtos.add(dto);
			}

		} catch (Exception e) {
			
			e.printStackTrace();
		} finally {
			try {
				if (resultSet != null)
					resultSet.close();
				if (preparedStatement != null)
					preparedStatement.close();
				if (connection != null)
					connection.close();
			} catch (Exception e2) {
				
				e2.printStackTrace();
			}
		}
		return dtos;
	}
	
	
}
[BDto.java] scr - edu.bit.ex.dto-BDto.java
package edu.bit.ex.dto;

import java.sql.Timestamp;

public class BDto {

	int bId;
	String bName;
	String bTitle;
	String bContent;
	Timestamp bDate;
	int bHit;
	int bGroup;
	int bStep;
	int bIndent;
	
	public BDto() {
		//디폴트 생성자 반드시 만든다.
	}
	
	public BDto(int bId, String bName, String bTitle,
			String bContent, Timestamp bDate, int bHit, 
			int bGroup, int bStep, int bIndent) {
		  //나중에 arrays로 갖고 끌고올거임
		this.bId = bId;
		this.bName = bName;
		this.bTitle = bTitle;
		this.bContent = bContent;
		this.bDate = bDate;
		this.bHit = bHit;
		this.bGroup = bGroup;
		this.bStep = bStep;
		this.bIndent = bIndent;
	}

	public int getbId() {
		return bId;
	}

	public void setbId(int bId) {
		this.bId = bId;
	}

	public String getbName() {
		return bName;
	}

	public void setbName(String bName) {
		this.bName = bName;
	}

	public String getbTitle() {
		return bTitle;
	}

	public void setbTitle(String bTitle) {
		this.bTitle = bTitle;
	}

	public String getbContent() {
		return bContent;
	}

	public void setbContent(String bContent) {
		this.bContent = bContent;
	}

	public Timestamp getbDate() {
		return bDate;
	}

	public void setbDate(Timestamp bDate) {
		this.bDate = bDate;
	}

	public int getbHit() {
		return bHit;
	}

	public void setbHit(int bHit) {
		this.bHit = bHit;
	}

	public int getbGroup() {
		return bGroup;
	}

	public void setbGroup(int bGroup) {
		this.bGroup = bGroup;
	}

	public int getbStep() {
		return bStep;
	}

	public void setbStep(int bStep) {
		this.bStep = bStep;
	}

	public int getbIndent() {
		return bIndent;
	}

	public void setbIndent(int bIndent) {
		this.bIndent = bIndent;
	}
	
}
[list.jsp] WebContent-list.jsp

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>Insert title here</title>
</head>
<body>
   
   <table width="500" cellpadding="0" cellspacing="0" border="1">
      <tr>
         <td>번호</td>
         <td>이름</td>
         <td>제목</td>
         <td>날짜</td>
         <td>히트</td>
      </tr>
      <c:forEach items="${list}" var="dto">
<%-- list는 request객체 안에 있기 때문에 그냥 forward시킨쪽에서는 그냥 ${list}라고 쓰면된다.
list는 BListCommand.java에있다. --%>

      <tr>
         <td>${dto.bId}</td>
         <!-- dto안에있는 bId꺼내오는것 -->
         <td>${dto.bName}</td>
         <td>
            <c:forEach begin="1" end="${dto.bIndent}">-</c:forEach>
            <a href="content_view.do?bId=${dto.bId}">${dto.bTitle}</a></td>
         <td>${dto.bDate}</td>
         <td>${dto.bHit}</td>
      </tr>
      </c:forEach>
      <tr>
         <td colspan="5"> <a href="write_view.do">글작성</a> </td>
      </tr>
   </table>
   
</body>
</html>

 

 

 

 

 

DAO에서 오류났을 확률 多

 

 

 

 

 

 

 

 

 

 

 

+)

${ }은 웹브라우저(webcontent-jsp, html)에서 자바문법임에도 어떻게 출력될까? 자바문법은 html(웹브라우저)가 절대 해석못한다. 그래도 출력할 수 있는건 그걸 html이 해석 할 수 있도록 변환하는 역할을 해주는 것이다.

 

 

 

 

어제 2번문제 매니저 출력하는 시퀀스

select m.empno, m.ename as manage from emp e, emp m where e.mgr = m.empno group by m.ename, m.empno;

 

//셀렉트부분


public ArrayList<EmpVO> manangerSelect(){
      ArrayList<EmpVO> dtos = new ArrayList<EmpVO>();
      
      Connection con = null;
      Statement stmt = null;
      ResultSet rs = null;
      String sql = "select m.EMPNO ,m.ename as manage from emp e , emp m where e.mgr = m.empno group by m.ename ,m.EMPNO";
      
      try {

         con = DriverManager.getConnection(url, uid, upw);
         stmt = con.createStatement();
         rs = stmt.executeQuery(sql); //해당 데이터를 갖고 옴

         while (rs.next()) {
            String name = rs.getString("manage");
            int empno = rs.getInt("empno");

            EmpVO eDto = new EmpVO(name, empno, "");
            dtos.add(eDto); //어레이 리스트로 관리 
         }

      } catch (Exception e) {
         e.printStackTrace();

      } finally {

         try {
            
            if (rs != null) rs.close();
            if(stmt != null) stmt.close();
            if (con != null) con.close(); 

         } catch (Exception e2) {
            e2.printStackTrace();
         }

      }
      
      return dtos;   
      
   }
   
   public ArrayList<String> getMananger(){
      ArrayList<String> dtos = new ArrayList<String>();
      
      Connection con = null;
      Statement stmt = null;
      ResultSet rs = null;
      String sql = "select (m.EMPNO||' '||m.ename) as manage from emp e , emp m where e.mgr = m.empno group by m.ename ,m.EMPNO";
      
      try {

         con = DriverManager.getConnection(url, uid, upw);
         stmt = con.createStatement();
         rs = stmt.executeQuery(sql); //해당 데이터를 갖고 옴

         while (rs.next()) {
            String name = rs.getString("manage");

            dtos.add(name); 
         }

      } catch (Exception e) {
         e.printStackTrace();

      } finally {

         try {
            
            if (rs != null) rs.close();
            if(stmt != null) stmt.close();
            if (con != null) con.close(); 

         } catch (Exception e2) {
            e2.printStackTrace();
         }

      }
      return dtos;
   }

728x90

'코딩 > 수업 정리' 카테고리의 다른 글

21.01.14 Thu [037]  (0) 2021.01.14
21.01.13 Wed [036]  (0) 2021.01.13
21.01.11 Mon [034]  (0) 2021.01.11
21.01.08 Fri [033]  (0) 2021.01.08
21.01.07 Thu [032]  (0) 2021.01.07

댓글